summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-08-31.lua (renamed from Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-05-06.lua)988
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua7
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua51
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua91
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua5
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua3
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua68
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-italics.lua46
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-map.lua2
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua118
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua1
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua1
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ota.lua116
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua1
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua117
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua48
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ott.lua38
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua395
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua1
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-vfc.lua2
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua8
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua1
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua10110
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-fil.lua1
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua86
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua58
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua177
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua131
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua167
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua14
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua97
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua180
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua27
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua16
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua29
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua8
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua180
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty9
56 files changed, 7607 insertions, 5875 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-05-06.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-08-31.lua
index 418ca726ba2..01e1f8300cd 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-05-06.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-08-31.lua
@@ -1,6 +1,6 @@
--[[info-----------------------------------------------------------------------
Luaotfload fontloader package
- build 2020-05-01 16:08:24
+ build 2020-08-31 23:33:48
-------------------------------------------------------------------------------
© 2020 PRAGMA ADE / ConTeXt Development Team
@@ -8,7 +8,7 @@
The code in this file is provided under the GPL v2.0 license. See the
file COPYING in the Luaotfload repository for details.
- Report bugs to github.com/u-fischer/luaotfload
+ Report bugs to https://github.com/latex3/luaotfload
This file has been assembled from components taken from Context. See
the Luaotfload documentation for details:
@@ -50,6 +50,7 @@
· fontloader-fonts-tfm.lua
· fontloader-font-lua.lua
· fontloader-font-def.lua
+ · fontloader-font-shp.lua
· fontloader-fonts-def.lua
· fontloader-fonts-ext.lua
· fontloader-font-imp-tex.lua
@@ -62,7 +63,7 @@
--info]]-----------------------------------------------------------------------
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] ---
if not modules then modules={} end modules ['data-con']={
version=1.100,
@@ -183,10 +184,10 @@ function containers.cleanname(name)
return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “data-con”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-nod” 68226d7dadd241bca55171af9ce1f243] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod” e296bfb03d5654a596b43612348c4191] ---
if not modules then modules={} end modules ['luatex-fonts-nod']={
version=1.001,
@@ -239,6 +240,7 @@ end
nodes.nodecodes=nodecodes
nodes.glyphcodes=glyphcodes
nodes.disccodes=disccodes
+nodes.dirvalues={ lefttoright=0,righttoleft=1 }
nodes.handlers.protectglyphs=node.protect_glyphs
nodes.handlers.unprotectglyphs=node.unprotect_glyphs
local direct=node.direct
@@ -435,10 +437,10 @@ do
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-nod”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] ---
characters=characters or {}
@@ -4048,10 +4050,10 @@ characters.indicgroups={
},
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-chr”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] ---
if not modules then modules={} end modules ['font-ini']={
version=1.001,
@@ -4092,10 +4094,10 @@ if node and not tex.getfontoffamily then
tex.getfontoffamily=node.family_font
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ini”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] ---
if not modules then modules={} end modules ['luatex-font-mis']={
version=1.001,
@@ -4127,10 +4129,10 @@ function font.each()
return table.sortedhash(fonts.hashes.identifiers)
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-mis”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-con” 40e3a857b2f31be1959dc6d445aaa9c4] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con” cbccccc4a5016196d62332a365aa8b72] ---
if not modules then modules={} end modules ['font-con']={
version=1.001,
@@ -4251,6 +4253,9 @@ function constructors.assignmathparameters(target,original)
if not mathparameters.FractionDelimiterDisplayStyleSize then
targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
end
+ if not targetmathparameters.SpaceBeforeScript then
+ targetmathparameters.SpaceBeforeScript=targetmathparameters.SpaceAfterScript
+ end
target.mathparameters=targetmathparameters
end
end
@@ -4258,31 +4263,40 @@ function constructors.beforecopyingcharacters(target,original)
end
function constructors.aftercopyingcharacters(target,original)
end
-constructors.sharefonts=false
-constructors.nofsharedfonts=0
-local sharednames={}
+local nofinstances=0
+local instances=setmetatableindex(function(t,k)
+ nofinstances=nofinstances+1
+ t[k]=nofinstances
+ return nofinstances
+end)
function constructors.trytosharefont(target,tfmdata)
- if constructors.sharefonts then
- local characters=target.characters
- local n=1
- local t={ target.psname }
- local u=sortedkeys(characters)
- for i=1,#u do
- local k=u[i]
- n=n+1;t[n]=k
- n=n+1;t[n]=characters[k].index or k
- end
- local h=md5.HEX(concat(t," "))
- local s=sharednames[h]
- if s then
- if trace_defining then
- report_defining("font %a uses backend resources of font %a",target.fullname,s)
- end
- target.fullname=s
- constructors.nofsharedfonts=constructors.nofsharedfonts+1
- target.properties.sharedwith=s
+ local properties=target.properties
+ local instance=properties.instance
+ if instance then
+ local fullname=target.fullname
+ local fontname=target.fontname
+ local psname=target.psname
+ local format=tfmdata.properties.format
+ if format=="opentype" then
+ target.streamprovider=1
+ elseif format=="truetype" then
+ target.streamprovider=2
else
- sharednames[h]=target.fullname
+ target.streamprovider=0
+ end
+ if target.streamprovider>0 then
+ if fullname then
+ fullname=fullname..":"..instances[instance]
+ target.fullname=fullname
+ end
+ if fontname then
+ fontname=fontname..":"..instances[instance]
+ target.fontname=fontname
+ end
+ if psname then
+ psname=psname..":"..instances[instance]
+ target.psname=psname
+ end
end
end
end
@@ -4448,12 +4462,14 @@ function constructors.scale(tfmdata,specification)
target.cidinfo=properties.cidinfo
target.format=properties.format
target.cache=constructors.cacheintex and "yes" or "renew"
+ local original=properties.original or tfmdata.original
local fontname=properties.fontname or tfmdata.fontname
local fullname=properties.fullname or tfmdata.fullname
local filename=properties.filename or tfmdata.filename
local psname=properties.psname or tfmdata.psname
local name=properties.name or tfmdata.name
local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+ target.original=original
target.fontname=fontname
target.fullname=fullname
target.filename=filename
@@ -4543,6 +4559,14 @@ function constructors.scale(tfmdata,specification)
targetparameters.x_height=targetx_height
targetparameters.quad=targetquad
targetparameters.extra_space=targetextra_space
+ local hshift=parameters.hshift
+ if hshift then
+ targetparameters.hshift=delta*hshift
+ end
+ local vshift=parameters.vshift
+ if vshift then
+ targetparameters.vshift=delta*vshift
+ end
local ascender=parameters.ascender
if ascender then
targetparameters.ascender=delta*ascender
@@ -5473,10 +5497,10 @@ function constructors.addcoreunicodes(unicodes)
return unicodes
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-con”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] ---
if not modules then modules={} end modules ['luatex-font-enc']={
version=1.001,
@@ -5545,10 +5569,10 @@ function encodings.load(filename)
return containers.write(encodings.cache,name,data)
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-enc”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] ---
if not modules then modules={} end modules ['font-cid']={
version=1.001,
@@ -5699,13 +5723,14 @@ function cid.getmap(specification)
return found
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cid”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-map” 51d0362c19d2d0f621e5cb750410a809] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map” a03653ea3c5f042b457d54ed678d6df3] ---
if not modules then modules={} end modules ['font-map']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -5790,6 +5815,7 @@ end
local hash={}
local conc={}
table.setmetatableindex(hash,function(t,k)
+ local v
if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
v=f_single(k)
else
@@ -6108,10 +6134,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-map”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc” 04fa0ffad5c51198c7c19462949f54ed] ---
if not modules then modules={} end modules ['font-vfc']={
version=1.001,
@@ -6125,7 +6151,6 @@ local insert=table.insert
local fonts=fonts
local helpers=fonts.helpers
local setmetatableindex=table.setmetatableindex
-local makeweak=table.makeweak
local push={ "push" }
local pop={ "pop" }
local dummy={ "comment" }
@@ -6209,13 +6234,14 @@ helpers.commands=utilities.storage.allocate {
dummy=dummy,
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-vfc”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otr” d96724dcb40c673ac294df7044a39925] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr” 7a2f7a9e9627b29158e1822ea3c650ab] ---
if not modules then modules={} end modules ['font-otr']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -7657,17 +7683,11 @@ local function readtable(tag,f,fontdata,specification,...)
reader(f,fontdata,specification,...)
end
end
-local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
local function readdata(f,offset,specification)
local fontdata,tables=loadtables(f,specification,offset)
if specification.glyphs then
prepareglyps(fontdata)
end
- if not variablefonts_supported then
- specification.instance=nil
- specification.variable=nil
- specification.factors=nil
- end
fontdata.temporary={}
readtable("name",f,fontdata,specification)
local askedname=specification.askedname
@@ -7682,60 +7702,58 @@ local function readdata(f,offset,specification)
readtable("stat",f,fontdata,specification)
readtable("avar",f,fontdata,specification)
readtable("fvar",f,fontdata,specification)
- if variablefonts_supported then
- local variabledata=fontdata.variabledata
- if variabledata then
- local instances=variabledata.instances
- local axis=variabledata.axis
- if axis and (not instances or #instances==0) then
- instances={}
- variabledata.instances=instances
- local function add(n,subfamily,value)
- local values={}
- for i=1,#axis do
- local a=axis[i]
- values[i]={
- axis=a.tag,
- value=i==n and value or a.default,
- }
- end
- instances[#instances+1]={
- subfamily=subfamily,
- values=values,
- }
- end
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ if axis and (not instances or #instances==0) then
+ instances={}
+ variabledata.instances=instances
+ local function add(n,subfamily,value)
+ local values={}
for i=1,#axis do
local a=axis[i]
- local tag=a.tag
- add(i,"default"..tag,a.default)
- add(i,"minimum"..tag,a.minimum)
- add(i,"maximum"..tag,a.maximum)
- end
- end
- end
- if not specification.factors then
- local instance=specification.instance
- if type(instance)=="string" then
- local factors=helpers.getfactors(fontdata,instance)
- if factors then
- specification.factors=factors
- fontdata.factors=factors
- fontdata.instance=instance
- report("user instance: %s, factors: % t",instance,factors)
- else
- report("user instance: %s, bad factors",instance)
+ values[i]={
+ axis=a.tag,
+ value=i==n and value or a.default,
+ }
end
+ instances[#instances+1]={
+ subfamily=subfamily,
+ values=values,
+ }
+ end
+ for i=1,#axis do
+ local a=axis[i]
+ local tag=a.tag
+ add(i,"default"..tag,a.default)
+ add(i,"minimum"..tag,a.minimum)
+ add(i,"maximum"..tag,a.maximum)
end
end
- if not fontdata.factors then
- if fontdata.variabledata then
- local factors=helpers.getfactors(fontdata,true)
- if factors then
- specification.factors=factors
- fontdata.factors=factors
- end
+ end
+ if not specification.factors then
+ local instance=specification.instance
+ if type(instance)=="string" then
+ local factors=helpers.getfactors(fontdata,instance)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ fontdata.instance=instance
+ report("user instance: %s, factors: % t",instance,factors)
else
+ report("user instance: %s, bad factors",instance)
+ end
+ end
+ end
+ if not fontdata.factors then
+ if fontdata.variabledata then
+ local factors=helpers.getfactors(fontdata,true)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
end
+ else
end
end
readtable("os/2",f,fontdata,specification)
@@ -7959,6 +7977,7 @@ function readers.loadfont(filename,n,instance)
hascolor=fontdata.hascolor or false,
instance=fontdata.instance,
factors=fontdata.factors,
+ nofsubfonts=fontdata.subfonts and #fontdata.subfonts or nil,
},
resources={
filename=filename,
@@ -8062,10 +8081,10 @@ function readers.extend(fontdata)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otr”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] ---
if not modules then modules={} end modules ['font-oti']={
version=1.001,
@@ -8208,10 +8227,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oti”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott” 1249b7018dba80e080fc478a38aa6756] ---
if not modules then modules={} end modules ["font-ott"]={
version=1.001,
@@ -9288,9 +9307,6 @@ function otffeatures.normalize(features,wrap)
h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt"
elseif k=="axis" then
h[k]=normalizedaxis(value)
- if not callbacks.supported.glyph_stream_provider then
- h.variableshapes=true
- end
else
local uk=usedfeatures[key]
local uv=uk[value]
@@ -9330,13 +9346,14 @@ function otffeatures.normalize(features,wrap)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ott”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cff” 155821e11e84021437869ff973e75d93] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff” aa9038651d9fedd2b76cacd1f69fd742] ---
if not modules then modules={} end modules ['font-cff']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -9784,12 +9801,15 @@ do
local p_dictionary=(
p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
)^1
- parsedictionaries=function(data,dictionaries,what)
+ parsedictionaries=function(data,dictionaries,version)
stack={}
strings=data.strings
+ if trace_charstrings then
+ report("charstring format %a",version)
+ end
for i=1,#dictionaries do
top=0
- result=what=="cff" and {
+ result=version=="cff" and {
monospaced=false,
italicangle=0,
underlineposition=-100,
@@ -10588,6 +10608,7 @@ do
end
end
else
+ top=top-nofregions*n
end
end
local actions={ [0]=unsupported,
@@ -11163,8 +11184,8 @@ do
processshape(tab,index-1)
end
end
-local function readglobals(f,data)
- local routines=readlengths(f)
+local function readglobals(f,data,version)
+ local routines=readlengths(f,version=="cff2")
for i=1,#routines do
routines[i]=readbytetable(f,routines[i])
end
@@ -11218,14 +11239,14 @@ local function readprivates(f,data)
private.data=readstring(f,private.size)
end
end
-local function readlocals(f,data,dictionary)
+local function readlocals(f,data,dictionary,version)
local header=data.header
local private=dictionary.private
if private then
local subroutineoffset=private.data.subroutines
if subroutineoffset~=0 then
setposition(f,header.offset+private.offset+subroutineoffset)
- local subroutines=readlengths(f)
+ local subroutines=readlengths(f,version=="cff2")
for i=1,#subroutines do
subroutines[i]=readbytetable(f,subroutines[i])
end
@@ -11238,7 +11259,7 @@ local function readlocals(f,data,dictionary)
dictionary.subroutines={}
end
end
-local function readcharstrings(f,data,what)
+local function readcharstrings(f,data,version)
local header=data.header
local dictionaries=data.dictionaries
local dictionary=dictionaries[1]
@@ -11247,7 +11268,7 @@ local function readcharstrings(f,data,what)
if type(offset)~="number" then
elseif stringtype==2 then
setposition(f,header.offset+offset)
- local charstrings=readlengths(f,what=="cff2")
+ local charstrings=readlengths(f,version=="cff2")
local nofglyphs=#charstrings
for i=1,nofglyphs do
charstrings[i]=readstring(f,charstrings[i])
@@ -11277,7 +11298,8 @@ readers.parsecharstrings=parsecharstrings
local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionaries=data.dictionaries
local dictionary=dictionaries[1]
- readglobals(f,data)
+ local cid=not dictionary.private and dictionary.cid
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version=="cff2" then
dictionary.charset=nil
@@ -11285,9 +11307,27 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
readencodings(f,data)
readcharsets(f,data,dictionary)
end
+ if cid then
+ local fdarray=cid.fdarray
+ if fdarray then
+ setposition(f,data.header.offset+fdarray)
+ local dictionaries=readlengths(f,version=="cff2")
+ local nofdictionaries=#dictionaries
+ if nofdictionaries>0 then
+ for i=1,nofdictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ dictionary.private=dictionaries[1].private
+ if nofdictionaries>1 then
+ report("ignoring dictionaries > 1 in cid font")
+ end
+ end
+ end
+ end
readprivates(f,data)
parseprivates(data,data.dictionaries)
- readlocals(f,data,dictionary)
+ readlocals(f,data,dictionary,version)
startparsing(fontdata,data,streams)
parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
stopparsing(fontdata,data)
@@ -11298,7 +11338,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionary=dictionaries[1]
local cid=dictionary.cid
local cidselect=cid and cid.fdselect
- readglobals(f,data)
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version~="cff2" then
readencodings(f,data)
@@ -11342,7 +11382,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local cidarray=cid.fdarray
if cidarray then
setposition(f,header.offset+cidarray)
- local dictionaries=readlengths(f)
+ local dictionaries=readlengths(f,version=="cff2")
for i=1,#dictionaries do
dictionaries[i]=readstring(f,dictionaries[i])
end
@@ -11350,7 +11390,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
cid.dictionaries=dictionaries
readcidprivates(f,data)
for i=1,#dictionaries do
- readlocals(f,data,dictionaries[i])
+ readlocals(f,data,dictionaries[i],version)
end
startparsing(fontdata,data,streams)
for i=1,#charstrings do
@@ -11504,13 +11544,14 @@ function readers.cffcheck(filename)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cff”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf” 807599f6d56c775d53cf6f358d741f34] ---
if not modules then modules={} end modules ['font-ttf']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -12677,13 +12718,14 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ttf”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-dsp” 618e5e760ec5dceb0c898a83816dbe61] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp” e1c275ded4770aa6cbe0b1afbdfd0dde] ---
if not modules then modules={} end modules ['font-dsp']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -15957,10 +15999,10 @@ function readers.mvar(f,fontdata,specification)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-dsp”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oup” 1700a2dac4f8b105c187d4e5b84cecdf] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup” 1700a2dac4f8b105c187d4e5b84cecdf] ---
if not modules then modules={} end modules ['font-oup']={
version=1.001,
@@ -18601,10 +18643,10 @@ function readers.expand(data)
expandlookups(sublookups)
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oup”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otl” f111f9ac18d24049fadeb8883e4e8da5] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl” f111f9ac18d24049fadeb8883e4e8da5] ---
if not modules then modules={} end modules ['font-otl']={
version=1.001,
@@ -19308,10 +19350,10 @@ otf.coverup={
end
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otl”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] ---
if not modules then modules={} end modules ['font-oto']={
version=1.001,
@@ -19769,13 +19811,14 @@ registerotffeature {
}
otf.basemodeinitializer=featuresinitializer
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oto”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otj” c9ded1d935bfa43020657e1f408fb820] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj” a37a1007b8a92c9e7d24064180c2a772] ---
if not modules then modules={} end modules ['font-otj']={
version=1.001,
+ optimize=true,
comment="companion to font-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -21266,10 +21309,10 @@ function injections.handler(head,where)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otj”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ota” dd5f1c8ba28abaf4505fd960d04a3a98] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota” f31232af3a694ae3d50380a5a92f88d3] ---
if not modules then modules={} end modules ['font-ota']={
version=1.001,
@@ -21279,6 +21322,7 @@ if not modules then modules={} end modules ['font-ota']={
license="see context related readme files"
}
local type=type
+local setmetatableindex=table.setmetatableindex
if not trackers then trackers={ register=function() end } end
local fonts,nodes,node=fonts,nodes,node
local allocate=utilities.storage.allocate
@@ -21492,7 +21536,7 @@ if not classifiers then
local f_mandiac,l_mandiac=characters.blockrange("mandiac")
local f_nko,l_nko=characters.blockrange("nko")
local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda")
- classifiers=table.setmetatableindex(function(t,k)
+ classifiers=setmetatableindex(function(t,k)
if type(k)=="number" then
local c=chardata[k]
local v=false
@@ -21658,17 +21702,118 @@ end
methods.syrc=methods.arab
methods.mand=methods.arab
methods.nko=methods.arab
+do
+ local joining=setmetatableindex(function(t,k)
+ if type(k)=="number" then
+ local c=chardata[k]
+ local v=false
+ if c then
+ local mongolian=c.mongolian
+ v=mongolian
+ end
+ t[k]=v
+ return v
+ end
+ end)
+ function methods.mong(head,font,attr)
+ local first,last
+ local current=head
+ local done=false
+ local prevjoin=nil
+ local prestate=nil
+ current=tonut(current)
+ local function wrapup()
+ if last then
+ if last~=first then
+ local s=getstate(last)
+ if s==s_medi then
+ setstate(last,s_fina)
+ elseif s==s_init then
+ setstate(last,s_isol)
+ end
+ end
+ last=nil
+ first=nil
+ prevjoin=nil
+ prestate=nil
+ end
+ end
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getstate(current) then
+ local currjoin=joining[char]
+ done=true
+ if not last then
+ setstate(current,s_isol)
+ prevjoin=currjoin
+ first=current
+ last=current
+ prevstate=s_isol
+ elseif currjoin=="t" then
+ last=current
+ elseif prevjoin=="d" or prevjoin=="jc" or prevjoin=="l" then
+ if currjoin=="d" or prevjoin=="jc" or prevjoin=="r" then
+ local s=getstate(last)
+ if s==s_isol then
+ setstate(last,s_init)
+ elseif s==s_fina then
+ setstate(last,s_medi)
+ end
+ setstate(current,s_fina)
+ prevstate=s_fina
+ elseif prevjoin=="nj" or prevjoin=="l" then
+ local s=getstate(last)
+ if s==s_medi then
+ setstate(last,s_fina)
+ elseif s==s_init then
+ setstate(last,s_isol)
+ end
+ setstate(current,s_isol)
+ prevstate=s_isol
+ end
+ prevjoin=currjoin
+ last=current
+ elseif prevjoin=="nj" or prevjoin=="r" then
+ if s==s_medi then
+ setstate(last,s_fina)
+ elseif s==s_init then
+ setstate(last,s_isol)
+ end
+ setstate(current,s_isol)
+ prevjoin=currjoin
+ prevstate=s_isol
+ last=current
+ elseif last then
+ wrapup()
+ end
+ else
+ if last then
+ wrapup()
+ end
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if last then
+ wrapup()
+ end
+ return head,done
+ end
+end
directives.register("otf.analyze.useunicodemarks",function(v)
analyzers.useunicodemarks=v
end)
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ota”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ots” 113b7ad0c40d4786bb026706e479c3f3] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots” c507280651dcbc549f1d8a5622da8667] ---
if not modules then modules={} end modules ['font-ots']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -21771,6 +21916,8 @@ local disc_code=nodecodes.disc
local math_code=nodecodes.math
local dir_code=nodecodes.dir
local localpar_code=nodecodes.localpar
+local lefttoright_code=nodes.dirvalues.lefttoright
+local righttoleft_code=nodes.dirvalues.righttoleft
local discretionarydisc_code=disccodes.discretionary
local ligatureglyph_code=glyphcodes.ligature
local a_noligature=attributes.private("noligature")
@@ -23274,6 +23421,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local sweepnode=sweepnode
local sweeptype=sweeptype
local sweepoverflow=false
+ local checkdisc=getprev(head)
local keepdisc=not sweepnode
local lookaheaddisc=nil
local backtrackdisc=nil
@@ -23397,7 +23545,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local current=prev
local i=f
local t=sweeptype=="pre" or sweeptype=="replace"
- if not current and t and current==checkdisk then
+ if not current and t and current==checkdisc then
current=getprev(sweepnode)
end
while current and i>1 do
@@ -23425,7 +23573,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
end
end
current=getprev(current)
- if t and current==checkdisk then
+ if t and current==checkdisc then
current=getprev(sweepnode)
end
end
@@ -23610,6 +23758,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local l=ck[5]
local current=start
local last=start
+ if s==1 then
+ goto next
+ end
if l>f then
local discfound
local n=f+1
@@ -23675,6 +23826,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
break
end
end
+ if n<=l then
+ notmatchpre[last]=true
+ end
else
notmatchpre[last]=true
end
@@ -24620,8 +24774,6 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase
end
local txtdirstate,pardirstate do
local getdirection=nuts.getdirection
- local lefttoright=0
- local righttoleft=1
txtdirstate=function(start,stack,top,rlparmode)
local dir,pop=getdirection(start)
if pop then
@@ -24629,19 +24781,19 @@ local txtdirstate,pardirstate do
return 0,rlparmode
else
top=top-1
- if stack[top]==righttoleft then
+ if stack[top]==righttoleft_code then
return top,-1
else
return top,1
end
end
- elseif dir==lefttoright then
+ elseif dir==lefttoright_code then
top=top+1
- stack[top]=lefttoright
+ stack[top]=lefttoright_code
return top,1
- elseif dir==righttoleft then
+ elseif dir==righttoleft_code then
top=top+1
- stack[top]=righttoleft
+ stack[top]=righttoleft_code
return top,-1
else
return top,rlparmode
@@ -24649,13 +24801,9 @@ local txtdirstate,pardirstate do
end
pardirstate=function(start)
local dir=getdirection(start)
- if dir==lefttoright then
- return 1,1
- elseif dir==righttoleft then
- return -1,-1
- elseif dir=="TLT" then
+ if dir==lefttoright_code then
return 1,1
- elseif dir=="TRT" then
+ elseif dir==righttoleft_code then
return -1,-1
else
return 0,0
@@ -24710,7 +24858,7 @@ do
local initialrl=0
if getid(head)==localpar_code and start_of_par(head) then
initialrl=pardirstate(head)
- elseif direction==1 or direction=="TRT" then
+ elseif direction==righttoleft_code then
initialrl=-1
end
local datasets=otfdataset(tfmdata,font,attr)
@@ -24934,7 +25082,7 @@ do
local done=false
local dirstack={ nil }
local start=head
- local initialrl=(direction==1 or direction=="TRT") and -1 or 0
+ local initialrl=(direction==righttoleft_code) and -1 or 0
local rlmode=initialrl
local rlparmode=initialrl
local topstack=0
@@ -25253,10 +25401,10 @@ registerotffeature {
},
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ots”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-osd” 61f05fcf91add1aa5dac9bc8b235adc9] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd” 61f05fcf91add1aa5dac9bc8b235adc9] ---
if not modules then modules={} end modules ['font-osd']={
version=1.001,
@@ -27689,10 +27837,10 @@ for i=1,nofscripts do
methods[scripts_two[i]]=method_two
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-osd”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ocl” e6b45379971219a6227e8655cda14aff] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl” ab81576f20e2d37bc8707e1dbd3decf2] ---
if not modules then modules={} end modules ['font-ocl']={
version=1.001,
@@ -27701,9 +27849,6 @@ if not modules then modules={} end modules ['font-ocl']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then
- return
-end
local tostring,tonumber,next=tostring,tonumber,next
local round,max=math.round,math.round
local gsub,find=string.gsub,string.find
@@ -27808,7 +27953,7 @@ local function convert(t,k)
t[k]=v
return v
end
-local start={ "pdf","mode","font" }
+local mode={ "pdf","mode","font" }
local push={ "pdf","page","q" }
local pop={ "pdf","page","Q" }
local function initializeoverlay(tfmdata,kind,value)
@@ -27853,7 +27998,7 @@ local function initializeoverlay(tfmdata,kind,value)
local s=#colorlist
local goback=w~=0 and leftcommand[w] or nil
local t={
- start,
+ mode,
not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) },
push,
}
@@ -27977,7 +28122,7 @@ do
local loaddata=io.loaddata
local savedata=io.savedata
local remove=os.remove
- if context and xml.convert then
+if context then
local xmlconvert=xml.convert
local xmlfirst=xml.first
function otfsvg.filterglyph(entry,index)
@@ -27986,11 +28131,11 @@ do
local data=root and tostring(root)
return data
end
- else
+else
function otfsvg.filterglyph(entry,index)
return entry.data
end
- end
+end
local runner=sandbox and sandbox.registerrunner {
name="otfsvg",
program="inkscape",
@@ -28003,6 +28148,14 @@ do
return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w")
end
end
+ local new=nil
+ local function inkscapeformat(suffix)
+ if new==nil then
+ new=os.resultof("inkscape --version") or ""
+ new=new=="" or not find(new,"Inkscape%s*0")
+ end
+ return new and "filename" or suffix
+ end
function otfsvg.topdf(svgshapes,tfmdata)
local pdfshapes={}
local inkscape=runner()
@@ -28011,7 +28164,7 @@ do
local nofshapes=#svgshapes
local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"]
local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"]
- local f_convert=formatters["%s --export-pdf=%s\n"]
+ local f_convert=formatters["%s --export-%s=%s\n"]
local filterglyph=otfsvg.filterglyph
local nofdone=0
local processed={}
@@ -28025,7 +28178,7 @@ do
local svgfile=f_svgfile(index)
local pdffile=f_pdffile(index)
savedata(svgfile,data)
- inkscape:write(f_convert(svgfile,pdffile))
+ inkscape:write(f_convert(svgfile,inkscapeformat("pdf"),pdffile))
processed[index]=true
nofdone=nofdone+1
if nofdone%25==0 then
@@ -28230,10 +28383,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ocl”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] ---
if not modules then modules={} end modules ['font-otc']={
version=1.001,
@@ -28990,13 +29143,14 @@ end
otf.enhancers.enhance=enhance
otf.enhancers.register("check extra features",enhance)
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otc”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-onr” 22572ec0f86f53631e14b6d1ed43ee51] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr” 7a9ece7bf3e36b5f0adf295a9a2a2989] ---
if not modules then modules={} end modules ['font-onr']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -29365,13 +29519,14 @@ function readers.getinfo(filename)
end
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-onr”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one” 1402ae8e4e96186c848fa2742388fb24] ---
if not modules then modules={} end modules ['font-one']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -30079,10 +30234,10 @@ registerafmenhancer("normalize features",enhance_normalize_features)
registerafmenhancer("check extra features",otfenhancers.enhance)
registerafmenhancer("fix names",enhance_fix_names)
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-one”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] ---
if not modules then modules={} end modules ['font-afk']={
version=1.001,
@@ -30249,10 +30404,10 @@ fonts.handlers.afm.helpdata={
}
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-afk”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] ---
if not modules then modules={} end modules ['luatex-fonts-tfm']={
version=1.001,
@@ -30767,10 +30922,10 @@ registertfmfeature {
}
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-tfm”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] ---
if not modules then modules={} end modules ['font-lua']={
version=1.001,
@@ -30810,10 +30965,10 @@ function readers.lua(specification)
return check_lua(specification,fullname)
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-lua”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-def” c525b9f55da1c736a1f6939c0a6f8f00] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def” 226b4d26ede7fa7be8e45b7f0d93e781] ---
if not modules then modules={} end modules ['font-def']={
version=1.001,
@@ -31178,8 +31333,9 @@ function definers.read(specification,size,id)
report_defining("already hashed: %s",hash)
end
else
- tfmdata=definers.loadfont(specification)
+ tfmdata=definers.loadfont(specification)
if tfmdata then
+ tfmdata.original=specification.specification
if trace_defining then
report_defining("loaded and hashed: %s",hash)
end
@@ -31212,10 +31368,378 @@ if not context then
callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-def”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp” c4a8c14513597ce3579d3ad4c580fe51] ---
+
+if not modules then modules={} end modules ['font-shp']={
+ 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 tonumber,next=tonumber,next
+local concat=table.concat
+local formatters=string.formatters
+local otf=fonts.handlers.otf
+local afm=fonts.handlers.afm
+local pfb=fonts.handlers.pfb
+local hashes=fonts.hashes
+local identifiers=hashes.identifiers
+local version=0.009
+local shapescache=containers.define("fonts","shapes",version,true)
+local streamscache=containers.define("fonts","streams",version,true)
+local compact_streams=false
+directives.register("fonts.streams.compact",function(v) compact_streams=v end)
+local function packoutlines(data,makesequence)
+ local subfonts=data.subfonts
+ if subfonts then
+ for i=1,#subfonts do
+ packoutlines(subfonts[i],makesequence)
+ end
+ return
+ end
+ local common=data.segments
+ if common then
+ return
+ end
+ local glyphs=data.glyphs
+ if not glyphs then
+ return
+ end
+ if makesequence then
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ local sequence={}
+ local nofsequence=0
+ for i=1,#segments do
+ local segment=segments[i]
+ local nofsegment=#segment
+ nofsequence=nofsequence+1
+ sequence[nofsequence]=segment[nofsegment]
+ for i=1,nofsegment-1 do
+ nofsequence=nofsequence+1
+ sequence[nofsequence]=segment[i]
+ end
+ end
+ glyph.sequence=sequence
+ glyph.segments=nil
+ end
+ end
+ end
+ else
+ local hash={}
+ local common={}
+ local reverse={}
+ local last=0
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ for i=1,#segments do
+ local h=concat(segments[i]," ")
+ hash[h]=(hash[h] or 0)+1
+ end
+ end
+ end
+ end
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ for i=1,#segments do
+ local segment=segments[i]
+ local h=concat(segment," ")
+ if hash[h]>1 then
+ local idx=reverse[h]
+ if not idx then
+ last=last+1
+ reverse[h]=last
+ common[last]=segment
+ idx=last
+ end
+ segments[i]=idx
+ end
+ end
+ end
+ end
+ end
+ if last>0 then
+ data.segments=common
+ end
+ end
+end
+local function unpackoutlines(data)
+ local subfonts=data.subfonts
+ if subfonts then
+ for i=1,#subfonts do
+ unpackoutlines(subfonts[i])
+ end
+ return
+ end
+ local common=data.segments
+ if not common then
+ return
+ end
+ local glyphs=data.glyphs
+ if not glyphs then
+ return
+ end
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ for i=1,#segments do
+ local c=common[segments[i]]
+ if c then
+ segments[i]=c
+ end
+ end
+ end
+ end
+ end
+ data.segments=nil
+end
+local readers=otf.readers
+local cleanname=otf.readers.helpers.cleanname
+local function makehash(filename,sub,instance)
+ local name=cleanname(file.basename(filename))
+ if instance then
+ return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance))
+ else
+ return formatters["%s-%s"] (name,sub or 0)
+ end
+end
+local function loadoutlines(cache,filename,sub,instance)
+ local base=file.basename(filename)
+ local name=file.removesuffix(base)
+ local kind=file.suffix(filename)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ local sub=tonumber(sub)
+ if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then
+ local hash=makehash(filename,sub,instance)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ data=otf.readers.loadshapes(filename,sub,instance)
+ if data then
+ data.size=size
+ data.format=data.format or (kind=="otf" and "opentype") or "truetype"
+ data.time=time
+ packoutlines(data)
+ containers.write(cache,hash,data)
+ data=containers.read(cache,hash)
+ end
+ end
+ unpackoutlines(data)
+ elseif size>0 and (kind=="pfb") then
+ local hash=containers.cleanname(base)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ data=afm.readers.loadshapes(filename)
+ if data then
+ data.size=size
+ data.format="type1"
+ data.time=time
+ packoutlines(data)
+ containers.write(cache,hash,data)
+ data=containers.read(cache,hash)
+ end
+ end
+ unpackoutlines(data)
+ else
+ data={
+ filename=filename,
+ size=0,
+ time=time,
+ format="unknown",
+ units=1000,
+ glyphs={}
+ }
+ end
+ return data
+end
+local function cachethem(cache,hash,data)
+ containers.write(cache,hash,data,compact_streams)
+ return containers.read(cache,hash)
+end
+local function loadstreams(cache,filename,sub,instance)
+ local base=file.basename(filename)
+ local name=file.removesuffix(base)
+ local kind=file.suffix(filename)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ local sub=tonumber(sub)
+ if size>0 and (kind=="otf" or kind=="ttf" or kind=="ttc") then
+ local hash=makehash(filename,sub,instance)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ data=otf.readers.loadshapes(filename,sub,instance,true)
+ if data then
+ local glyphs=data.glyphs
+ local streams={}
+ if glyphs then
+ for i=0,#glyphs do
+ local glyph=glyphs[i]
+ if glyph then
+ streams[i]=glyph.stream or ""
+ else
+ streams[i]=""
+ end
+ end
+ end
+ data.streams=streams
+ data.glyphs=nil
+ data.size=size
+ data.format=data.format or (kind=="otf" and "opentype") or "truetype"
+ data.time=time
+ data=cachethem(cache,hash,data)
+ end
+ end
+ elseif size>0 and (kind=="pfb") then
+ local hash=makehash(filename,sub,instance)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ local names,encoding,streams,metadata=pfb.loadvector(filename,false,true)
+ if streams then
+ local fontbbox=metadata.fontbbox or { 0,0,0,0 }
+ for i=0,#streams do
+ streams[i]=streams[i].stream or "\14"
+ end
+ data={
+ filename=filename,
+ size=size,
+ time=time,
+ format="type1",
+ streams=streams,
+ fontheader={
+ fontversion=metadata.version,
+ units=1000,
+ xmin=fontbbox[1],
+ ymin=fontbbox[2],
+ xmax=fontbbox[3],
+ ymax=fontbbox[4],
+ },
+ horizontalheader={
+ ascender=0,
+ descender=0,
+ },
+ maximumprofile={
+ nofglyphs=#streams+1,
+ },
+ names={
+ copyright=metadata.copyright,
+ family=metadata.familyname,
+ fullname=metadata.fullname,
+ fontname=metadata.fontname,
+ subfamily=metadata.subfamilyname,
+ trademark=metadata.trademark,
+ notice=metadata.notice,
+ version=metadata.version,
+ },
+ cffinfo={
+ familyname=metadata.familyname,
+ fullname=metadata.fullname,
+ italicangle=metadata.italicangle,
+ monospaced=metadata.isfixedpitch and true or false,
+ underlineposition=metadata.underlineposition,
+ underlinethickness=metadata.underlinethickness,
+ weight=metadata.weight,
+ },
+ }
+ data=cachethem(cache,hash,data)
+ end
+ end
+ else
+ data={
+ filename=filename,
+ size=0,
+ time=time,
+ format="unknown",
+ streams={}
+ }
+ end
+ return data
+end
+local loadedshapes={}
+local loadedstreams={}
+local function loadoutlinedata(fontdata,streams)
+ local properties=fontdata.properties
+ local filename=properties.filename
+ local subindex=fontdata.subindex
+ local instance=properties.instance
+ local hash=makehash(filename,subindex,instance)
+ local loaded=loadedshapes[hash]
+ if not loaded then
+ loaded=loadoutlines(shapescache,filename,subindex,instance)
+ loadedshapes[hash]=loaded
+ end
+ return loaded
+end
+hashes.shapes=table.setmetatableindex(function(t,k)
+ local f=identifiers[k]
+ if f then
+ return loadoutlinedata(f)
+ end
+end)
+local function getstreamhash(fontid)
+ local fontdata=identifiers[fontid]
+ if fontdata then
+ local properties=fontdata.properties
+ return makehash(properties.filename,properties.subfont,properties.instance)
+ end
+end
+local function loadstreamdata(fontdata)
+ local properties=fontdata.properties
+ local shared=fontdata.shared
+ local rawdata=shared and shared.rawdata
+ local metadata=rawdata and rawdata.metadata
+ local filename=properties.filename
+ local subindex=metadata and metadata.subfontindex
+ local instance=properties.instance
+ local hash=makehash(filename,subindex,instance)
+ local loaded=loadedstreams[hash]
+ if not loaded then
+ loaded=loadstreams(streamscache,filename,subindex,instance)
+ loadedstreams[hash]=loaded
+ end
+ return loaded
+end
+hashes.streams=table.setmetatableindex(function(t,k)
+ local f=identifiers[k]
+ if f then
+ return loadstreamdata(f)
+ end
+end)
+otf.loadoutlinedata=loadoutlinedata
+otf.loadstreamdata=loadstreamdata
+otf.loadshapes=loadshapes
+otf.getstreamhash=getstreamhash
+local streams=fonts.hashes.streams
+callback.register("glyph_stream_provider",function(id,index,mode)
+ if id>0 then
+ local streams=streams[id].streams
+ if streams then
+ return streams[index] or ""
+ end
+ end
+ return ""
+end)
+
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp”] ---
+
+
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] ---
if not modules then modules={} end modules ['luatex-fonts-def']={
version=1.001,
@@ -31296,10 +31820,10 @@ function fonts.definers.applypostprocessors(tfmdata)
return tfmdata
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-def”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] ---
if not modules then modules={} end modules ['luatex-fonts-ext']={
version=1.001,
@@ -31485,10 +32009,10 @@ registerotffeature {
}
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-ext”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] ---
if not modules then modules={} end modules ['font-imp-tex']={
version=1.001,
@@ -31587,10 +32111,10 @@ registerotffeature {
description="arabic digits",
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-tex”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] ---
if not modules then modules={} end modules ['font-imp-ligatures']={
version=1.001,
@@ -31704,10 +32228,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-ligatures”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics” 058fb834c11c6ac30c280b29e496966e] ---
if not modules then modules={} end modules ['font-imp-italics']={
version=1.001,
@@ -31776,8 +32300,6 @@ if context then
}
registerotffeature(specification)
registerafmfeature(specification)
-end
-if context then
local letter=characters.is_letter
local always=true
local function collapseitalics(tfmdata,key,value)
@@ -31813,10 +32335,10 @@ if context then
registerafmfeature(dimensions_specification)
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-italics”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects” 582f9dd5031e9d67fff389efd16a874f] ---
if not modules then modules={} end modules ['font-imp-effects']={
version=1.001,
@@ -32049,6 +32571,7 @@ local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze
end
end
end
+local shiftmode=CONTEXTLMTXMODE>0
local function manipulateeffect(tfmdata)
local effect=tfmdata.properties.effect
if effect then
@@ -32070,38 +32593,45 @@ local function manipulateeffect(tfmdata)
local factor=(1+effect.factor)*factor
local hfactor=(1+effect.hfactor)*hfactor
local vfactor=(1+effect.vfactor)*vfactor
- local vshift=vshift~=0 and upcommand[vshift] or false
+ if shiftmode then
+ parameters.hshift=hshift
+ parameters.vshift=vshift
+ else
+ vshift=vshift~=0 and upcommand[vshift] or false
+ hshift=rightcommand[hshift]
+ end
for unicode,character in next,characters do
local oldwidth=character.width
local oldheight=character.height
local olddepth=character.depth
if oldwidth and oldwidth>0 then
character.width=oldwidth+wdelta
- local commands=character.commands
- local hshift=rightcommand[hshift]
- if vshift then
- if commands then
- prependcommands (commands,
- hshift,
- vshift
- )
- else
- character.commands={
- hshift,
- vshift,
- charcommand[unicode]
- }
- end
- else
- if commands then
- prependcommands (commands,
- hshift
- )
+ if not shiftmode then
+ local commands=character.commands
+ if vshift then
+ if commands then
+ prependcommands (commands,
+ hshift,
+ vshift
+ )
+ else
+ character.commands={
+ hshift,
+ vshift,
+ charcommand[unicode]
+ }
+ end
else
- character.commands={
- hshift,
- charcommand[unicode]
- }
+ if commands then
+ prependcommands (commands,
+ hshift
+ )
+ else
+ character.commands={
+ hshift,
+ charcommand[unicode]
+ }
+ end
end
end
end
@@ -32173,10 +32703,10 @@ local specification={
registerotffeature(specification)
registerafmfeature(specification)
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-effects”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] ---
fonts.handlers.otf.addfeature {
@@ -34245,10 +34775,10 @@ fonts.handlers.otf.addfeature {
["type"]="ligature",
}
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-lig”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig”] ---
-do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] ---
+do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] ---
if not modules then modules={} end modules ['luatex-fonts-gbn']={
version=1.001,
@@ -34513,7 +35043,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
return head
end
-end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-gbn”] ---
+end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn”] ---
--- vim:ft=lua:sw=2:ts=8:et:tw=79
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua
index f52fec69676..5a6e90ceee7 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua
@@ -105,14 +105,14 @@ utilities.parsers = utilities.parsers or {
end,
settings_to_hash = function(s)
local t = { }
- for k, v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do
+ for k, v in gmatch((gsub(s,"^{(.*)}$", "%1")),"([^%s,=]+)=([^%s,]+)") do
t[k] = v
end
return t
end,
settings_to_hash_colon_too = function(s)
local t = { }
- for k, v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do
+ for k, v in gmatch((gsub(s,"^{(.*)}$", "%1")),"([^%s,=:]+)[=:]([^%s,]+)") do
t[k] = v
end
return t
@@ -189,7 +189,7 @@ local readables = { }
local usingjit = jit
if not caches.namespace or caches.namespace == "" or caches.namespace == "context" then
- caches.namespace = 'generic-dev'
+ caches.namespace = 'generic'
end
do
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua
index 0fb768cf83f..67abf707b17 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua
@@ -66,9 +66,10 @@ for k, v in next, disccodes do
disccodes[v] = k
end
-nodes.nodecodes = nodecodes
-nodes.glyphcodes = glyphcodes
-nodes.disccodes = disccodes
+nodes.nodecodes = nodecodes
+nodes.glyphcodes = glyphcodes
+nodes.disccodes = disccodes
+nodes.dirvalues = { lefttoright = 0, righttoleft = 1 }
nodes.handlers.protectglyphs = node.protect_glyphs -- beware: nodes!
nodes.handlers.unprotectglyphs = node.unprotect_glyphs -- beware: nodes!
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua
index 72b0a038f17..b7d45392d60 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-cff'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -609,12 +610,15 @@ do
+ p_unsupported
)^1
- parsedictionaries = function(data,dictionaries,what)
+ parsedictionaries = function(data,dictionaries,version)
stack = { }
strings = data.strings
+ if trace_charstrings then
+ report("charstring format %a",version)
+ end
for i=1,#dictionaries do
top = 0
- result = what == "cff" and {
+ result = version == "cff" and {
monospaced = false,
italicangle = 0,
underlineposition = -100,
@@ -1517,7 +1521,7 @@ do
end
end
else
- -- error
+ top = top - nofregions * n
end
end
@@ -2261,8 +2265,8 @@ do
end
-local function readglobals(f,data)
- local routines = readlengths(f)
+local function readglobals(f,data,version)
+ local routines = readlengths(f,version == "cff2")
for i=1,#routines do
routines[i] = readbytetable(f,routines[i])
end
@@ -2320,14 +2324,14 @@ local function readprivates(f,data)
end
end
-local function readlocals(f,data,dictionary)
+local function readlocals(f,data,dictionary,version)
local header = data.header
local private = dictionary.private
if private then
local subroutineoffset = private.data.subroutines
if subroutineoffset ~= 0 then
setposition(f,header.offset+private.offset+subroutineoffset)
- local subroutines = readlengths(f)
+ local subroutines = readlengths(f,version == "cff2")
for i=1,#subroutines do
subroutines[i] = readbytetable(f,subroutines[i])
end
@@ -2344,7 +2348,7 @@ end
-- These charstrings are little programs and described in: Technical Note #5177. A truetype
-- font has only one dictionary.
-local function readcharstrings(f,data,what)
+local function readcharstrings(f,data,version)
local header = data.header
local dictionaries = data.dictionaries
local dictionary = dictionaries[1]
@@ -2355,7 +2359,7 @@ local function readcharstrings(f,data,what)
elseif stringtype == 2 then
setposition(f,header.offset+offset)
-- could be a metatable .. delayed loading
- local charstrings = readlengths(f,what=="cff2")
+ local charstrings = readlengths(f,version=="cff2")
local nofglyphs = #charstrings
for i=1,nofglyphs do
charstrings[i] = readstring(f,charstrings[i])
@@ -2390,7 +2394,8 @@ readers.parsecharstrings = parsecharstrings -- used in font-onr.lua (type 1)
local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionaries = data.dictionaries
local dictionary = dictionaries[1]
- readglobals(f,data)
+ local cid = not dictionary.private and dictionary.cid
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version == "cff2" then
dictionary.charset = nil
@@ -2398,9 +2403,27 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
readencodings(f,data)
readcharsets(f,data,dictionary)
end
+ if cid then
+ local fdarray = cid.fdarray
+ if fdarray then
+ setposition(f,data.header.offset + fdarray)
+ local dictionaries = readlengths(f,version=="cff2")
+ local nofdictionaries = #dictionaries
+ if nofdictionaries > 0 then
+ for i=1,nofdictionaries do
+ dictionaries[i] = readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ dictionary.private = dictionaries[1].private
+ if nofdictionaries > 1 then
+ report("ignoring dictionaries > 1 in cid font")
+ end
+ end
+ end
+ end
readprivates(f,data)
parseprivates(data,data.dictionaries)
- readlocals(f,data,dictionary)
+ readlocals(f,data,dictionary,version)
startparsing(fontdata,data,streams)
parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
stopparsing(fontdata,data)
@@ -2412,7 +2435,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionary = dictionaries[1]
local cid = dictionary.cid
local cidselect = cid and cid.fdselect
- readglobals(f,data)
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version ~= "cff2" then
readencodings(f,data)
@@ -2458,7 +2481,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local cidarray = cid.fdarray
if cidarray then
setposition(f,header.offset+cidarray)
- local dictionaries = readlengths(f)
+ local dictionaries = readlengths(f,version == "cff2")
for i=1,#dictionaries do
dictionaries[i] = readstring(f,dictionaries[i])
end
@@ -2466,7 +2489,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
cid.dictionaries = dictionaries
readcidprivates(f,data)
for i=1,#dictionaries do
- readlocals(f,data,dictionaries[i])
+ readlocals(f,data,dictionaries[i],version)
end
startparsing(fontdata,data,streams)
for i=1,#charstrings do
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua
index 1bb63aa5192..7162338c66e 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua
@@ -191,6 +191,9 @@ function constructors.assignmathparameters(target,original) -- simple variant, n
if not mathparameters.FractionDelimiterDisplayStyleSize then
targetmathparameters.FractionDelimiterDisplayStyleSize = 2.40 * targetparameters.size
end
+ if not targetmathparameters.SpaceBeforeScript then
+ targetmathparameters.SpaceBeforeScript = targetmathparameters.SpaceAfterScript
+ end
target.mathparameters = targetmathparameters
end
end
@@ -210,60 +213,45 @@ end
-- we default to false, so a macro package has to enable it explicitly. In
-- LuaTeX the fullname is used to identify a font as being unique.
-constructors.sharefonts = false
-constructors.nofsharedfonts = 0
-local sharednames = { }
+local nofinstances = 0
+local instances = setmetatableindex(function(t,k)
+ nofinstances = nofinstances + 1
+ t[k] = nofinstances
+ return nofinstances
+end)
function constructors.trytosharefont(target,tfmdata)
- if constructors.sharefonts then -- not robust !
- local characters = target.characters
- local n = 1
- local t = { target.psname }
- local u = sortedkeys(characters)
- for i=1,#u do
- local k = u[i]
- n = n + 1 ; t[n] = k
- n = n + 1 ; t[n] = characters[k].index or k
+ local properties = target.properties
+ local instance = properties.instance
+ if instance then
+ local fullname = target.fullname
+ local fontname = target.fontname
+ local psname = target.psname
+ local format = tfmdata.properties.format
+ if format == "opentype" then
+ target.streamprovider = 1
+ elseif format == "truetype" then
+ target.streamprovider = 2
+ else
+ target.streamprovider = 0
end
- local h = md5.HEX(concat(t," "))
- local s = sharednames[h]
- if s then
- if trace_defining then
- report_defining("font %a uses backend resources of font %a",target.fullname,s)
+ if target.streamprovider > 0 then
+ if fullname then
+ fullname = fullname .. ":" .. instances[instance]
+ target.fullname = fullname
+ end
+ if fontname then
+ fontname = fontname .. ":" .. instances[instance]
+ target.fontname = fontname
+ end
+ if psname then
+ psname = psname .. ":" .. instances[instance]
+ target.psname = psname
end
- target.fullname = s
- constructors.nofsharedfonts = constructors.nofsharedfonts + 1
- target.properties.sharedwith = s
- else
- sharednames[h] = target.fullname
end
end
end
--- function constructors.enhanceparameters(parameters)
--- local xheight = parameters.x_height
--- local quad = parameters.quad
--- local space = parameters.space
--- local stretch = parameters.space_stretch
--- local shrink = parameters.space_shrink
--- local extra = parameters.extra_space
--- local slant = parameters.slant
--- -- synonyms
--- parameters.xheight = xheight
--- parameters.spacestretch = stretch
--- parameters.spaceshrink = shrink
--- parameters.extraspace = extra
--- parameters.em = quad
--- parameters.ex = xheight
--- parameters.slantperpoint = slant
--- parameters.spacing = {
--- width = space,
--- stretch = stretch,
--- shrink = shrink,
--- extra = extra,
--- }
--- end
-
local synonyms = {
exheight = "x_height",
xheight = "x_height",
@@ -463,6 +451,7 @@ function constructors.scale(tfmdata,specification)
target.format = properties.format
target.cache = constructors.cacheintex and "yes" or "renew"
--
+ local original = properties.original or tfmdata.original
local fontname = properties.fontname or tfmdata.fontname
local fullname = properties.fullname or tfmdata.fullname
local filename = properties.filename or tfmdata.filename
@@ -474,6 +463,7 @@ function constructors.scale(tfmdata,specification)
--
local psname, psfixed = fixedpsname(psname,fontname or fullname or file.nameonly(filename))
--
+ target.original = original
target.fontname = fontname
target.fullname = fullname
target.filename = filename
@@ -578,6 +568,15 @@ function constructors.scale(tfmdata,specification)
targetparameters.quad = targetquad
targetparameters.extra_space = targetextra_space
--
+ local hshift = parameters.hshift
+ if hshift then
+ targetparameters.hshift = delta * hshift
+ end
+ local vshift = parameters.vshift
+ if vshift then
+ targetparameters.vshift = delta * vshift
+ end
+ --
local ascender = parameters.ascender
if ascender then
targetparameters.ascender = delta * ascender
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
index e287bf79ce5..b752b3258c4 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
@@ -207,9 +207,6 @@ function resolvers.name(specification)
features.normal = normal
end
normal.instance = instance
- -- if not callbacks.supported.glyph_stream_provider then
- -- normal.variableshapes = true -- for the moment
- -- end
end
--
local suffix = lower(suffixonly(resolved))
@@ -492,7 +489,9 @@ function definers.read(specification,size,id) -- id can be optional, name can al
end
else
tfmdata = definers.loadfont(specification) -- can be overloaded
+-- put in properties instead
if tfmdata then
+ tfmdata.original = specification.specification
if trace_defining then
report_defining("loaded and hashed: %s",hash)
end
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua
index 3058be37b9a..0cff896e8d9 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-dsp'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -302,7 +303,7 @@ end)
-- values can be anything the min/max permits so we can either think of
-- real values of a fraction along the axis (probably easier)
--- wght:400,wdth:100,ital:1
+-- wght=400,wdth=100,ital=1
local function axistofactors(str)
local t = settings_to_hash(str)
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua
index cc6e4c0bf88..bd6cce87952 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua
@@ -280,6 +280,9 @@ end
-- local show_effect = { "lua", "print('!')" }
+----- shiftmode = false -- test in mkiv and lmtx
+local shiftmode = CONTEXTLMTXMODE > 0
+
local function manipulateeffect(tfmdata)
local effect = tfmdata.properties.effect
if effect then
@@ -301,42 +304,49 @@ local function manipulateeffect(tfmdata)
local factor = (1 + effect.factor) * factor
local hfactor = (1 + effect.hfactor) * hfactor
local vfactor = (1 + effect.vfactor) * vfactor
- local vshift = vshift ~= 0 and upcommand[vshift] or false
+ if shiftmode then
+ parameters.hshift = hshift
+ parameters.vshift = vshift
+ else
+ vshift = vshift ~= 0 and upcommand[vshift] or false
+ hshift = rightcommand[hshift]
+ end
for unicode, character in next, characters do
local oldwidth = character.width
local oldheight = character.height
local olddepth = character.depth
if oldwidth and oldwidth > 0 then
character.width = oldwidth + wdelta
- local commands = character.commands
- local hshift = rightcommand[hshift]
- if vshift then
- if commands then
- prependcommands ( commands,
--- show_effect,
- hshift,
- vshift
- )
- else
- character.commands = {
--- show_effect,
- hshift,
- vshift,
- charcommand[unicode]
- }
- end
- else
- if commands then
- prependcommands ( commands,
--- show_effect,
- hshift
- )
+ if not shiftmode then
+ local commands = character.commands
+ if vshift then
+ if commands then
+ prependcommands ( commands,
+ -- show_effect,
+ hshift,
+ vshift
+ )
+ else
+ character.commands = {
+ -- show_effect,
+ hshift,
+ vshift,
+ charcommand[unicode]
+ }
+ end
else
- character.commands = {
--- show_effect,
- hshift,
- charcommand[unicode]
- }
+ if commands then
+ prependcommands ( commands,
+ -- show_effect,
+ hshift
+ )
+ else
+ character.commands = {
+ -- show_effect,
+ hshift,
+ charcommand[unicode]
+ }
+ end
end
end
end
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-italics.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-italics.lua
index 83c785d3876..3e172bedee6 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-italics.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-italics.lua
@@ -79,33 +79,25 @@ if context then
registerotffeature(specification)
registerafmfeature(specification)
-end
-
--- no longer used
-
--- if context then
---
--- -- local function initializemathitalics(tfmdata,value) -- yes no delay
--- -- tfmdata.properties.mathitalics = toboolean(value)
--- -- end
--- --
--- -- local specification = {
--- -- name = "mathitalics",
--- -- description = "use alternative math italic correction",
--- -- initializers = {
--- -- base = initializemathitalics,
--- -- node = initializemathitalics,
--- -- }
--- -- }
--- --
--- -- registerotffeature(specification)
--- -- registerafmfeature(specification)
---
--- end
-
--- -- also not used, only when testing
-
-if context then
+ -- no longer used
+
+ -- local function initializemathitalics(tfmdata,value) -- yes no delay
+ -- tfmdata.properties.mathitalics = toboolean(value)
+ -- end
+ --
+ -- local specification = {
+ -- name = "mathitalics",
+ -- description = "use alternative math italic correction",
+ -- initializers = {
+ -- base = initializemathitalics,
+ -- node = initializemathitalics,
+ -- }
+ -- }
+ --
+ -- registerotffeature(specification)
+ -- registerafmfeature(specification)
+
+ -- only used when testing
local letter = characters.is_letter
local always = true
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-map.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-map.lua
index 84a28a8b7ed..c983ea96343 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-map.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-map.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-map'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -103,6 +104,7 @@ local hash = { }
local conc = { }
table.setmetatableindex(hash,function(t,k)
+ local v
if k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
v = f_single(k)
else
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua
index 094e8b88ee6..e6a38af5c3e 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua
@@ -5,12 +5,8 @@ if not modules then modules = { } end modules ['font-ocl'] = {
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
--- patched version 2020-05-06 UF (colr/restorefix --
--- todo : user list of colors
-if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then
- return
-end
+-- todo : user list of colors
local tostring, tonumber, next = tostring, tonumber, next
local round, max = math.round, math.round
@@ -151,85 +147,17 @@ local function convert(t,k)
return v
end
-local start = { "pdf", "mode", "font" } -- force text mode (so get q Q right)
------ stop = { "pdf", "mode", "page" } -- force page mode (else overlap)
-local push = { "pdf", "page", "q" }
-local pop = { "pdf", "page", "Q" }
-
--- -- This one results in color directives inside BT ET but has less q Q pairs. It
--- -- only shows the first glyph in acrobat and nothing more. No problem with other
--- -- renderers.
---
--- local function initializeoverlay(tfmdata,kind,value) -- hm, always value
--- if value then
--- local resources = tfmdata.resources
--- local palettes = resources.colorpalettes
--- if palettes then
--- --
--- local converted = resources.converted
--- if not converted then
--- converted = setmetatableindex(convert)
--- resources.converted = converted
--- end
--- local colorvalues = sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or { }
--- local classes = #colorvalues
--- if classes == 0 then
--- return
--- end
--- --
--- local characters = tfmdata.characters
--- local descriptions = tfmdata.descriptions
--- local properties = tfmdata.properties
--- --
--- properties.virtualized = true
--- tfmdata.fonts = {
--- { id = 0 }
--- }
--- --
--- local getactualtext = otf.getactualtext
--- local default = colorvalues[#colorvalues]
--- local b, e = getactualtext(tounicode(0xFFFD))
--- local actualb = { "pdf", "page", b } -- saves tables
--- local actuale = { "pdf", "page", e } -- saves tables
--- --
--- for unicode, character in next, characters do
--- local description = descriptions[unicode]
--- if description then
--- local colorlist = description.colors
--- if colorlist then
--- local u = description.unicode or characters[unicode].unicode
--- local w = character.width or 0
--- local s = #colorlist
--- local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same
--- local t = {
--- start,
--- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) },
--- push,
--- }
--- local n = 3
--- local l = nil
--- for i=1,s do
--- local entry = colorlist[i]
--- local v = colorvalues[entry.class] or default
--- if v and l ~= v then
--- n = n + 1 t[n] = v
--- l = v
--- end
--- n = n + 1 t[n] = charcommand[entry.slot]
--- if s > 1 and i < s and goback then
--- n = n + 1 t[n] = goback
--- end
--- end
--- n = n + 1 t[n] = pop
--- n = n + 1 t[n] = actuale
--- n = n + 1 t[n] = stop
--- character.commands = t
--- end
--- end
--- end
--- end
--- end
--- end
+-- At some point 'font' mode was added to the engine and we can assume that most distributions
+-- ship a luatex that has it; ancient versions are no longer supported anyway. Begin 2020 there
+-- was an actualtext related mail exchange with RM etc. that might result in similar mode keys
+-- in other tex->pdf programs because there is a bit of inconsistency in the way this is dealt
+-- with. Best is not to touch this code too much.
+
+local mode = { "pdf", "mode", "font" }
+local push = { "pdf", "page", "q" }
+local pop = { "pdf", "page", "Q" }
+
+-- see context git repository for older variant (pre 20200501 cleanup)
local function initializeoverlay(tfmdata,kind,value)
if value then
@@ -278,7 +206,7 @@ local function initializeoverlay(tfmdata,kind,value)
local s = #colorlist
local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same
local t = {
- start,
+ mode,
not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) },
push,
}
@@ -437,7 +365,7 @@ do
local savedata = io.savedata
local remove = os.remove
- if context and xml.convert then
+if context then
local xmlconvert = xml.convert
local xmlfirst = xml.first
@@ -452,13 +380,13 @@ do
return data
end
- else
+else
function otfsvg.filterglyph(entry,index) -- can be overloaded
return entry.data
end
- end
+end
local runner = sandbox and sandbox.registerrunner {
name = "otfsvg",
@@ -485,6 +413,16 @@ do
-- Because a generic setup can be flawed we need to catch bad inkscape runs which add a bit of
-- ugly overhead. Bah.
+ local new = nil
+
+ local function inkscapeformat(suffix)
+ if new == nil then
+ new = os.resultof("inkscape --version") or ""
+ new = new == "" or not find(new,"Inkscape%s*0")
+ end
+ return new and "filename" or suffix
+ end
+
function otfsvg.topdf(svgshapes,tfmdata)
local pdfshapes = { }
local inkscape = runner()
@@ -494,7 +432,7 @@ do
local nofshapes = #svgshapes
local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"]
local f_pdffile = formatters["temp-otf-svg-shape-%i.pdf"]
- local f_convert = formatters["%s --export-pdf=%s\n"]
+ local f_convert = formatters["%s --export-%s=%s\n"]
local filterglyph = otfsvg.filterglyph
local nofdone = 0
local processed = { }
@@ -508,7 +446,7 @@ do
local svgfile = f_svgfile(index)
local pdffile = f_pdffile(index)
savedata(svgfile,data)
- inkscape:write(f_convert(svgfile,pdffile))
+ inkscape:write(f_convert(svgfile,inkscapeformat("pdf"),pdffile))
processed[index] = true
nofdone = nofdone + 1
if nofdone % 25 == 0 then
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua
index 5387516b4d5..a76c9298599 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-one'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua
index fc6bead5889..c33b09f9e2a 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-onr'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ota.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ota.lua
index 6cbf4bb86fe..ce1b22b50d7 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ota.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ota.lua
@@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['font-ota'] = {
-- context only
local type = type
+local setmetatableindex = table.setmetatableindex
if not trackers then trackers = { register = function() end } end
@@ -285,7 +286,7 @@ if not classifiers then
local f_nko, l_nko = characters.blockrange("nko")
local f_ext_a, l_ext_a = characters.blockrange("arabicextendeda")
- classifiers = table.setmetatableindex(function(t,k)
+ classifiers = setmetatableindex(function(t,k)
if type(k) == "number" then
local c = chardata[k]
local v = false
@@ -461,6 +462,119 @@ methods.syrc = methods.arab
methods.mand = methods.arab
methods.nko = methods.arab
+-- a quick first attemp .. more later
+
+do
+
+ -- https://github.com/n8willis/opentype-shaping-documents/blob/master/opentype-shaping-mongolian.md#joining-properties
+ -- todo syrc
+
+ local joining = setmetatableindex(function(t,k)
+ if type(k) == "number" then
+ local c = chardata[k]
+ local v = false
+ if c then
+ local mongolian = c.mongolian
+ --
+ v = mongolian
+ end
+ t[k] = v
+ return v
+ end
+ end)
+
+ function methods.mong(head,font,attr)
+ local first, last
+ local current = head
+ local done = false
+ local prevjoin = nil
+ local prestate = nil
+ current = tonut(current)
+
+ local function wrapup()
+ if last then
+ if last ~= first then
+ local s = getstate(last)
+ if s == s_medi then
+ setstate(last,s_fina)
+ elseif s == s_init then
+ setstate(last,s_isol)
+ end
+ end
+ last = nil
+ first = nil
+ prevjoin = nil
+ prestate = nil
+ end
+ end
+
+ while current do
+ local char, id = ischar(current,font)
+ if char and not getstate(current) then
+ local currjoin = joining[char]
+ done = true
+ if not last then
+ setstate(current,s_isol)
+ prevjoin = currjoin
+ first = current
+ last = current
+ prevstate = s_isol
+ elseif currjoin == "t" then -- transparent
+ -- keep state
+ last = current
+ elseif prevjoin == "d" or prevjoin == "jc" or prevjoin == "l" then
+ if currjoin == "d" or prevjoin == "jc" or prevjoin == "r" then
+ local s = getstate(last)
+ if s == s_isol then
+ setstate(last,s_init)
+ elseif s == s_fina then
+ setstate(last,s_medi)
+ end
+ setstate(current,s_fina)
+ prevstate = s_fina
+ elseif prevjoin == "nj" or prevjoin == "l" then
+ local s = getstate(last)
+ if s == s_medi then
+ setstate(last,s_fina)
+ elseif s == s_init then
+ setstate(last,s_isol)
+ end
+ setstate(current,s_isol)
+ prevstate = s_isol
+ end
+ prevjoin = currjoin
+ last = current
+ elseif prevjoin == "nj" or prevjoin == "r" then
+ if s == s_medi then
+ setstate(last,s_fina)
+ elseif s == s_init then
+ setstate(last,s_isol)
+ end
+ setstate(current,s_isol)
+ prevjoin = currjoin
+ prevstate = s_isol
+ last = current
+ elseif last then
+ wrapup()
+ end
+ else
+ if last then
+ wrapup()
+ end
+ if id == math_code then -- a bit duplicate as we test for glyphs twice
+ current = end_of_math(current)
+ end
+ end
+ current = getnext(current)
+ end
+ if last then
+ wrapup()
+ end
+ return head, done
+ end
+
+end
+
directives.register("otf.analyze.useunicodemarks",function(v)
analyzers.useunicodemarks = v
end)
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
index bec52d813fb..bb02044dca6 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-otj'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua
index e726053202f..531f665de72 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-otr'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -2084,8 +2085,6 @@ local function readtable(tag,f,fontdata,specification,...)
end
end
-local variablefonts_supported = (context and true) or (logs and logs.application and true) or false
-
local function readdata(f,offset,specification)
local fontdata, tables = loadtables(f,specification,offset)
@@ -2094,12 +2093,6 @@ local function readdata(f,offset,specification)
prepareglyps(fontdata)
end
- if not variablefonts_supported then
- specification.instance = nil
- specification.variable = nil
- specification.factors = nil
- end
-
fontdata.temporary = { }
readtable("name",f,fontdata,specification)
@@ -2118,71 +2111,66 @@ local function readdata(f,offset,specification)
readtable("avar",f,fontdata,specification)
readtable("fvar",f,fontdata,specification)
- if variablefonts_supported then
-
- local variabledata = fontdata.variabledata
-
- if variabledata then
- local instances = variabledata.instances
- local axis = variabledata.axis
- if axis and (not instances or #instances == 0) then
- instances = { }
- variabledata.instances = instances
- local function add(n,subfamily,value)
- local values = { }
- for i=1,#axis do
- local a = axis[i]
- values[i] = {
- axis = a.tag,
- value = i == n and value or a.default,
- }
- end
- instances[#instances+1] = {
- subfamily = subfamily,
- values = values,
- }
- end
+ local variabledata = fontdata.variabledata
+
+ if variabledata then
+ local instances = variabledata.instances
+ local axis = variabledata.axis
+ if axis and (not instances or #instances == 0) then
+ instances = { }
+ variabledata.instances = instances
+ local function add(n,subfamily,value)
+ local values = { }
for i=1,#axis do
- local a = axis[i]
- local tag = a.tag
- add(i,"default"..tag,a.default)
- add(i,"minimum"..tag,a.minimum)
- add(i,"maximum"..tag,a.maximum)
+ local a = axis[i]
+ values[i] = {
+ axis = a.tag,
+ value = i == n and value or a.default,
+ }
end
- -- report("%i fake instances added",#instances)
+ instances[#instances+1] = {
+ subfamily = subfamily,
+ values = values,
+ }
end
- end
-
- if not specification.factors then
- local instance = specification.instance
- if type(instance) == "string" then
- local factors = helpers.getfactors(fontdata,instance)
- if factors then
- specification.factors = factors
- fontdata.factors = factors
- fontdata.instance = instance
- report("user instance: %s, factors: % t",instance,factors)
- else
- report("user instance: %s, bad factors",instance)
- end
+ for i=1,#axis do
+ local a = axis[i]
+ local tag = a.tag
+ add(i,"default"..tag,a.default)
+ add(i,"minimum"..tag,a.minimum)
+ add(i,"maximum"..tag,a.maximum)
end
+ -- report("%i fake instances added",#instances)
end
-
- if not fontdata.factors then
- if fontdata.variabledata then
- local factors = helpers.getfactors(fontdata,true)
- if factors then
- specification.factors = factors
- fontdata.factors = factors
- -- report("factors: % t",factors)
- -- else
- -- report("bad factors")
- end
+ end
+ if not specification.factors then
+ local instance = specification.instance
+ if type(instance) == "string" then
+ local factors = helpers.getfactors(fontdata,instance)
+ if factors then
+ specification.factors = factors
+ fontdata.factors = factors
+ fontdata.instance = instance
+ report("user instance: %s, factors: % t",instance,factors)
else
- -- report("unknown instance")
+ report("user instance: %s, bad factors",instance)
end
end
+ end
+ if not fontdata.factors then
+ if fontdata.variabledata then
+ local factors = helpers.getfactors(fontdata,true)
+ if factors then
+ specification.factors = factors
+ fontdata.factors = factors
+ -- report("factors: % t",factors)
+ -- else
+ -- report("bad factors")
+ end
+ else
+ -- report("unknown instance")
+ end
end
readtable("os/2",f,fontdata,specification)
@@ -2433,6 +2421,7 @@ function readers.loadfont(filename,n,instance)
hascolor = fontdata.hascolor or false,
instance = fontdata.instance,
factors = fontdata.factors,
+ nofsubfonts = fontdata.subfonts and #fontdata.subfonts or nil,
},
resources = {
-- filename = fontdata.filename,
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
index 3b6ea6a7269..490f28de699 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-ots'] = { -- sequences
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -25,7 +26,7 @@ effect that suddenly fonts behave differently. We don't want to catch all font
issues.</p>
<p>After a lot of experiments (mostly by Taco, me and Idris) the first implementation
-becaus quite useful. When it did most of what we wanted, a more optimized version
+was already quite useful. When it did most of what we wanted, a more optimized version
evolved. Of course all errors are mine and of course the code can be improved. There
are quite some optimizations going on here and processing speed is currently quite
acceptable and has been improved over time. Many complex scripts are not yet supported
@@ -252,6 +253,9 @@ local math_code = nodecodes.math
local dir_code = nodecodes.dir
local localpar_code = nodecodes.localpar
+local lefttoright_code = nodes.dirvalues.lefttoright
+local righttoleft_code = nodes.dirvalues.righttoleft
+
local discretionarydisc_code = disccodes.discretionary
local ligatureglyph_code = glyphcodes.ligature
@@ -2056,6 +2060,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local sweepnode = sweepnode
local sweeptype = sweeptype
local sweepoverflow = false
+ local checkdisc = getprev(head)
local keepdisc = not sweepnode
local lookaheaddisc = nil
local backtrackdisc = nil
@@ -2089,6 +2094,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
sweepnode = current
current = getnext(current)
else
+ -- we can use an iterator
while replace and i <= l do
if getid(replace) == glyph_code then
i = i + 1
@@ -2189,7 +2195,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local current = prev
local i = f
local t = sweeptype == "pre" or sweeptype == "replace"
- if not current and t and current == checkdisk then
+ if not current and t and current == checkdisc then
current = getprev(sweepnode)
end
while current and i > 1 do -- missing getprev added / moved outside
@@ -2218,7 +2224,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
end
end
current = getprev(current)
- if t and current == checkdisk then
+ if t and current == checkdisc then
current = getprev(sweepnode)
end
end
@@ -2443,6 +2449,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local current = start
local last = start
+ if s == 1 then
+ goto next
+ end
+
-- current match
if l > f then
@@ -2512,10 +2522,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
break
end
end
- -- commented, for Kai to check
- -- if n <= l then
- -- notmatchpre[last] = true
- -- end
+ if n <= l then
+ notmatchpre[last] = true
+ end
else
notmatchpre[last] = true
end
@@ -3620,8 +3629,6 @@ end
local txtdirstate, pardirstate do -- this might change (no need for nxt in pardirstate)
local getdirection = nuts.getdirection
- local lefttoright = 0
- local righttoleft = 1
txtdirstate = function(start,stack,top,rlparmode)
local dir, pop = getdirection(start)
@@ -3630,19 +3637,19 @@ local txtdirstate, pardirstate do -- this might change (no need for nxt in pard
return 0, rlparmode
else
top = top - 1
- if stack[top] == righttoleft then
+ if stack[top] == righttoleft_code then
return top, -1
else
return top, 1
end
end
- elseif dir == lefttoright then
+ elseif dir == lefttoright_code then
top = top + 1
- stack[top] = lefttoright
+ stack[top] = lefttoright_code
return top, 1
- elseif dir == righttoleft then
+ elseif dir == righttoleft_code then
top = top + 1
- stack[top] = righttoleft
+ stack[top] = righttoleft_code
return top, -1
else
return top, rlparmode
@@ -3651,14 +3658,9 @@ local txtdirstate, pardirstate do -- this might change (no need for nxt in pard
pardirstate = function(start)
local dir = getdirection(start)
- if dir == lefttoright then
- return 1, 1
- elseif dir == righttoleft then
- return -1, -1
- -- for old times sake we we handle strings too
- elseif dir == "TLT" then
+ if dir == lefttoright_code then
return 1, 1
- elseif dir == "TRT" then
+ elseif dir == righttoleft_code then
return -1, -1
else
return 0, 0
@@ -3759,7 +3761,7 @@ do
if getid(head) == localpar_code and start_of_par(head) then
initialrl = pardirstate(head)
- elseif direction == 1 or direction == "TRT" then
+ elseif direction == righttoleft_code then
initialrl = -1
end
@@ -4054,7 +4056,7 @@ do
local done = false
local dirstack = { nil } -- could move outside function but we can have local runs (maybe a few more nils)
local start = head
- local initialrl = (direction == 1 or direction == "TRT") and -1 or 0
+ local initialrl = (direction == righttoleft_code) and -1 or 0
local rlmode = initialrl
local rlparmode = initialrl
local topstack = 0
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ott.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ott.lua
index c9e467f2253..f4d7e05a137 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ott.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ott.lua
@@ -1117,41 +1117,6 @@ local checkers = {
end
}
--- Keep this:
---
--- function otf.features.normalize(features)
--- if features then
--- local h = { }
--- for k, v in next, features do
--- k = lower(k)
--- if k == "language" then
--- v = gsub(lower(v),"[^a-z0-9]","")
--- h.language = rawget(verboselanguages,v) or (languages[v] and v) or "dflt" -- auto adds
--- elseif k == "script" then
--- v = gsub(lower(v),"[^a-z0-9]","")
--- h.script = rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" -- auto adds
--- else
--- if type(v) == "string" then
--- local b = is_boolean(v)
--- if type(b) == "nil" then
--- v = tonumber(v) or lower(v)
--- else
--- v = b
--- end
--- end
--- if not rawget(features,k) then
--- k = rawget(verbosefeatures,k) or k
--- end
--- local c = checkers[k]
--- h[k] = c and c(v) or v
--- end
--- end
--- return h
--- end
--- end
-
--- inspect(fonts.handlers.otf.statistics.usedfeatures)
-
if not storage then
return
end
@@ -1178,9 +1143,6 @@ function otffeatures.normalize(features,wrap) -- wrap is for context
h.script = rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" -- auto adds
elseif k == "axis" then
h[k] = normalizedaxis(value)
- if not callbacks.supported.glyph_stream_provider then
- h.variableshapes = true -- for the moment
- end
else
local uk = usedfeatures[key]
local uv = uk[value]
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua
new file mode 100644
index 00000000000..c3fea6d4601
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua
@@ -0,0 +1,395 @@
+if not modules then modules = { } end modules ['font-shp'] = {
+ 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 tonumber, next = tonumber, next
+local concat = table.concat
+local formatters = string.formatters
+
+local otf = fonts.handlers.otf
+local afm = fonts.handlers.afm
+local pfb = fonts.handlers.pfb
+
+local hashes = fonts.hashes
+local identifiers = hashes.identifiers
+
+local version = 0.009
+local shapescache = containers.define("fonts", "shapes", version, true)
+local streamscache = containers.define("fonts", "streams", version, true)
+
+-- shapes (can be come a separate file at some point)
+
+local compact_streams = false
+
+directives.register("fonts.streams.compact", function(v) compact_streams = v end)
+
+local function packoutlines(data,makesequence)
+ local subfonts = data.subfonts
+ if subfonts then
+ for i=1,#subfonts do
+ packoutlines(subfonts[i],makesequence)
+ end
+ return
+ end
+ local common = data.segments
+ if common then
+ return
+ end
+ local glyphs = data.glyphs
+ if not glyphs then
+ return
+ end
+ if makesequence then
+ for index=0,#glyphs do
+ local glyph = glyphs[index]
+ if glyph then
+ local segments = glyph.segments
+ if segments then
+ local sequence = { }
+ local nofsequence = 0
+ for i=1,#segments do
+ local segment = segments[i]
+ local nofsegment = #segment
+ -- why last first ... needs documenting
+ nofsequence = nofsequence + 1
+ sequence[nofsequence] = segment[nofsegment]
+ for i=1,nofsegment-1 do
+ nofsequence = nofsequence + 1
+ sequence[nofsequence] = segment[i]
+ end
+ end
+ glyph.sequence = sequence
+ glyph.segments = nil
+ end
+ end
+ end
+ else
+ local hash = { }
+ local common = { }
+ local reverse = { }
+ local last = 0
+ for index=0,#glyphs do
+ local glyph = glyphs[index]
+ if glyph then
+ local segments = glyph.segments
+ if segments then
+ for i=1,#segments do
+ local h = concat(segments[i]," ")
+ hash[h] = (hash[h] or 0) + 1
+ end
+ end
+ end
+ end
+ for index=0,#glyphs do
+ local glyph = glyphs[index]
+ if glyph then
+ local segments = glyph.segments
+ if segments then
+ for i=1,#segments do
+ local segment = segments[i]
+ local h = concat(segment," ")
+ if hash[h] > 1 then -- minimal one shared in order to hash
+ local idx = reverse[h]
+ if not idx then
+ last = last + 1
+ reverse[h] = last
+ common[last] = segment
+ idx = last
+ end
+ segments[i] = idx
+ end
+ end
+ end
+ end
+ end
+ if last > 0 then
+ data.segments = common
+ end
+ end
+end
+
+local function unpackoutlines(data)
+ local subfonts = data.subfonts
+ if subfonts then
+ for i=1,#subfonts do
+ unpackoutlines(subfonts[i])
+ end
+ return
+ end
+ local common = data.segments
+ if not common then
+ return
+ end
+ local glyphs = data.glyphs
+ if not glyphs then
+ return
+ end
+ for index=0,#glyphs do
+ local glyph = glyphs[index]
+ if glyph then
+ local segments = glyph.segments
+ if segments then
+ for i=1,#segments do
+ local c = common[segments[i]]
+ if c then
+ segments[i] = c
+ end
+ end
+ end
+ end
+ end
+ data.segments = nil
+end
+
+-- todo: loaders per format
+
+local readers = otf.readers
+local cleanname = otf.readers.helpers.cleanname
+
+local function makehash(filename,sub,instance)
+ local name = cleanname(file.basename(filename))
+ if instance then
+ return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance))
+ else
+ return formatters["%s-%s"] (name,sub or 0)
+ end
+end
+
+local function loadoutlines(cache,filename,sub,instance)
+ local base = file.basename(filename)
+ local name = file.removesuffix(base)
+ local kind = file.suffix(filename)
+ local attr = lfs.attributes(filename)
+ local size = attr and attr.size or 0
+ local time = attr and attr.modification or 0
+ local sub = tonumber(sub)
+
+ -- fonts.formats
+
+ if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then
+ local hash = makehash(filename,sub,instance)
+ data = containers.read(cache,hash)
+ if not data or data.time ~= time or data.size ~= size then
+ data = otf.readers.loadshapes(filename,sub,instance)
+ if data then
+ data.size = size
+ data.format = data.format or (kind == "otf" and "opentype") or "truetype"
+ data.time = time
+ packoutlines(data)
+ containers.write(cache,hash,data)
+ data = containers.read(cache,hash) -- frees old mem
+ end
+ end
+ unpackoutlines(data)
+ elseif size > 0 and (kind == "pfb") then
+ local hash = containers.cleanname(base) -- including suffix
+ data = containers.read(cache,hash)
+ if not data or data.time ~= time or data.size ~= size then
+ data = afm.readers.loadshapes(filename)
+ if data then
+ data.size = size
+ data.format = "type1"
+ data.time = time
+ packoutlines(data)
+ containers.write(cache,hash,data)
+ data = containers.read(cache,hash) -- frees old mem
+ end
+ end
+ unpackoutlines(data)
+ else
+ data = {
+ filename = filename,
+ size = 0,
+ time = time,
+ format = "unknown",
+ units = 1000,
+ glyphs = { }
+ }
+ end
+ return data
+end
+
+local function cachethem(cache,hash,data)
+ containers.write(cache,hash,data,compact_streams) -- arg 4 aka fast
+ return containers.read(cache,hash) -- frees old mem
+end
+
+local function loadstreams(cache,filename,sub,instance)
+ local base = file.basename(filename)
+ local name = file.removesuffix(base)
+ local kind = file.suffix(filename)
+ local attr = lfs.attributes(filename)
+ local size = attr and attr.size or 0
+ local time = attr and attr.modification or 0
+ local sub = tonumber(sub)
+ if size > 0 and (kind == "otf" or kind == "ttf" or kind == "ttc") then
+ local hash = makehash(filename,sub,instance)
+ data = containers.read(cache,hash)
+ if not data or data.time ~= time or data.size ~= size then
+ data = otf.readers.loadshapes(filename,sub,instance,true)
+ if data then
+ local glyphs = data.glyphs
+ local streams = { }
+ if glyphs then
+ for i=0,#glyphs do
+ local glyph = glyphs[i]
+ if glyph then
+ streams[i] = glyph.stream or ""
+ else
+ streams[i] = ""
+ end
+ end
+ end
+ data.streams = streams
+ data.glyphs = nil
+ data.size = size
+ data.format = data.format or (kind == "otf" and "opentype") or "truetype"
+ data.time = time
+ data = cachethem(cache,hash,data)
+ end
+ end
+ elseif size > 0 and (kind == "pfb") then
+ local hash = makehash(filename,sub,instance)
+ data = containers.read(cache,hash)
+ if not data or data.time ~= time or data.size ~= size then
+ local names, encoding, streams, metadata = pfb.loadvector(filename,false,true)
+ if streams then
+ local fontbbox = metadata.fontbbox or { 0, 0, 0, 0 }
+ for i=0,#streams do
+ streams[i] = streams[i].stream or "\14"
+ end
+ data = {
+ filename = filename,
+ size = size,
+ time = time,
+ format = "type1",
+ streams = streams,
+ fontheader = {
+ fontversion = metadata.version,
+ units = 1000, -- can this be different?
+ xmin = fontbbox[1],
+ ymin = fontbbox[2],
+ xmax = fontbbox[3],
+ ymax = fontbbox[4],
+ },
+ horizontalheader = {
+ ascender = 0,
+ descender = 0,
+ },
+ maximumprofile = {
+ nofglyphs = #streams + 1,
+ },
+ names = {
+ copyright = metadata.copyright,
+ family = metadata.familyname,
+ fullname = metadata.fullname,
+ fontname = metadata.fontname,
+ subfamily = metadata.subfamilyname,
+ trademark = metadata.trademark,
+ notice = metadata.notice,
+ version = metadata.version,
+ },
+ cffinfo = {
+ familyname = metadata.familyname,
+ fullname = metadata.fullname,
+ italicangle = metadata.italicangle,
+ monospaced = metadata.isfixedpitch and true or false,
+ underlineposition = metadata.underlineposition,
+ underlinethickness = metadata.underlinethickness,
+ weight = metadata.weight,
+ },
+ }
+ data = cachethem(cache,hash,data)
+ end
+ end
+ else
+ data = {
+ filename = filename,
+ size = 0,
+ time = time,
+ format = "unknown",
+ streams = { }
+ }
+ end
+ return data
+end
+
+local loadedshapes = { }
+local loadedstreams = { }
+
+local function loadoutlinedata(fontdata,streams)
+ local properties = fontdata.properties
+ local filename = properties.filename
+ local subindex = fontdata.subindex
+ local instance = properties.instance
+ local hash = makehash(filename,subindex,instance)
+ local loaded = loadedshapes[hash]
+ if not loaded then
+ loaded = loadoutlines(shapescache,filename,subindex,instance)
+ loadedshapes[hash] = loaded
+ end
+ return loaded
+end
+
+hashes.shapes = table.setmetatableindex(function(t,k)
+ local f = identifiers[k]
+ if f then
+ return loadoutlinedata(f)
+ end
+end)
+
+local function getstreamhash(fontid)
+ local fontdata = identifiers[fontid]
+ if fontdata then
+ local properties = fontdata.properties
+ return makehash(properties.filename,properties.subfont,properties.instance)
+ end
+end
+
+local function loadstreamdata(fontdata)
+ local properties = fontdata.properties
+ local shared = fontdata.shared
+ local rawdata = shared and shared.rawdata
+ local metadata = rawdata and rawdata.metadata
+ local filename = properties.filename
+ local subindex = metadata and metadata.subfontindex
+ local instance = properties.instance
+ local hash = makehash(filename,subindex,instance)
+ local loaded = loadedstreams[hash]
+ if not loaded then
+ loaded = loadstreams(streamscache,filename,subindex,instance)
+ loadedstreams[hash] = loaded
+ end
+ return loaded
+end
+
+hashes.streams = table.setmetatableindex(function(t,k)
+ local f = identifiers[k]
+ if f then
+ return loadstreamdata(f)
+ end
+end)
+
+otf.loadoutlinedata = loadoutlinedata -- not public
+otf.loadstreamdata = loadstreamdata -- not public
+otf.loadshapes = loadshapes
+otf.getstreamhash = getstreamhash -- not public, might move to other namespace
+
+local streams = fonts.hashes.streams
+
+-- we can now assume that luatex has this one
+
+callback.register("glyph_stream_provider",function(id,index,mode)
+ if id > 0 then
+ local streams = streams[id].streams
+ -- print(id,index,streams[index])
+ if streams then
+ return streams[index] or ""
+ end
+ end
+ return ""
+end)
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua
index 651ede17e21..865f8e6e30b 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['font-ttf'] = {
version = 1.001,
+ optimize = true,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-vfc.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-vfc.lua
index dfe6b3afc46..eff0aa6c636 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-vfc.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-vfc.lua
@@ -13,7 +13,7 @@ local fonts = fonts
local helpers = fonts.helpers
local setmetatableindex = table.setmetatableindex
-local makeweak = table.makeweak
+----- makeweak = table.makeweak
-- Helpers dealing with virtual fonts: beware, these are final values so
-- don't change the content of tables gotten this way!
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua
index 7979a40fb94..b0868ba4886 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua
@@ -203,12 +203,14 @@ local collapser = Cs(spacer^0/"" * nonspacer^0 * ((spacer^0/" " * nonspac
local nospacer = Cs((whitespace^1/"" + nonwhitespace^1)^0)
local b_collapser = Cs( whitespace^0 /"" * (nonwhitespace^1 + whitespace^1/" ")^0)
-local e_collapser = Cs((whitespace^1 * endofstring/"" + nonwhitespace^1 + whitespace^1/" ")^0)
local m_collapser = Cs( (nonwhitespace^1 + whitespace^1/" ")^0)
+local e_collapser = Cs((whitespace^1 * endofstring/"" + nonwhitespace^1 + whitespace^1/" ")^0)
+local x_collapser = Cs( (nonwhitespace^1 + whitespace^1/"" )^0)
local b_stripper = Cs( spacer^0 /"" * (nonspacer^1 + spacer^1/" ")^0)
-local e_stripper = Cs((spacer^1 * endofstring/"" + nonspacer^1 + spacer^1/" ")^0)
local m_stripper = Cs( (nonspacer^1 + spacer^1/" ")^0)
+local e_stripper = Cs((spacer^1 * endofstring/"" + nonspacer^1 + spacer^1/" ")^0)
+local x_stripper = Cs( (nonspacer^1 + spacer^1/"" )^0)
patterns.stripper = stripper
patterns.fullstripper = fullstripper
@@ -218,10 +220,12 @@ patterns.nospacer = nospacer
patterns.b_collapser = b_collapser
patterns.m_collapser = m_collapser
patterns.e_collapser = e_collapser
+patterns.x_collapser = x_collapser
patterns.b_stripper = b_stripper
patterns.m_stripper = m_stripper
patterns.e_stripper = e_stripper
+patterns.x_stripper = x_stripper
patterns.lowercase = lowercase
patterns.uppercase = uppercase
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua
index f411230d4aa..00989c5cea7 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua
@@ -195,12 +195,6 @@ function optionalrequire(...)
end
end
--- nice for non ascii scripts (this might move):
-
-if lua then
- lua.mask = load([[τεχ = 1]]) and "utf" or "ascii"
-end
-
local flush = io.flush
if flush then
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua
index c57aaf33ebc..03016ed9010 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['l-unicode'] = {
version = 1.001,
+ optimize = true,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua
index 9f381d358a7..df4f3593c20 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua
@@ -1,7 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2020-04-30 11:10
--- patched on 2020-05-06 (colr-restore fix
+-- merge date : 2020-08-31 22:01
do -- begin closure to overcome local limits and interference
@@ -100,9 +99,6 @@ function optionalrequire(...)
return result
end
end
-if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
-end
local flush=io.flush
if flush then
local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
@@ -226,11 +222,13 @@ local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0)
-local e_collapser=Cs((whitespace^1*endofstring/""+nonwhitespace^1+whitespace^1/" ")^0)
local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0)
+local e_collapser=Cs((whitespace^1*endofstring/""+nonwhitespace^1+whitespace^1/" ")^0)
+local x_collapser=Cs((nonwhitespace^1+whitespace^1/"" )^0)
local b_stripper=Cs(spacer^0/""*(nonspacer^1+spacer^1/" ")^0)
-local e_stripper=Cs((spacer^1*endofstring/""+nonspacer^1+spacer^1/" ")^0)
local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0)
+local e_stripper=Cs((spacer^1*endofstring/""+nonspacer^1+spacer^1/" ")^0)
+local x_stripper=Cs((nonspacer^1+spacer^1/"" )^0)
patterns.stripper=stripper
patterns.fullstripper=fullstripper
patterns.collapser=collapser
@@ -238,9 +236,11 @@ patterns.nospacer=nospacer
patterns.b_collapser=b_collapser
patterns.m_collapser=m_collapser
patterns.e_collapser=e_collapser
+patterns.x_collapser=x_collapser
patterns.b_stripper=b_stripper
patterns.m_stripper=m_stripper
patterns.e_stripper=e_stripper
+patterns.x_stripper=x_stripper
patterns.lowercase=lowercase
patterns.uppercase=uppercase
patterns.letter=patterns.lowercase+patterns.uppercase
@@ -3762,33 +3762,36 @@ local format_extension=function(extensions,f,name)
local extension=extensions[name] or "tostring(%s)"
local f=tonumber(f) or 1
local w=find(extension,"%.%.%.")
- if w then
- if f==0 then
+ if f==0 then
+ if w then
extension=gsub(extension,"%.%.%.","")
- return extension
- elseif f==1 then
+ end
+ return extension
+ elseif f==1 then
+ if w then
extension=gsub(extension,"%.%.%.","%%s")
- n=n+1
- local a="a"..n
- return format(extension,a,a)
- elseif f<0 then
+ end
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ if w then
+ extension=gsub(extension,"%.%.%.","")
+ return extension
+ else
local a="a"..(n+f+1)
return format(extension,a,a)
- else
- extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- local t={}
- for i=1,f do
- n=n+1
- t[i]="a"..n
- end
- return format(extension,unpack(t))
end
else
- extension=gsub(extension,"%%s",function()
+ if w then
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ end
+ local t={}
+ for i=1,f do
n=n+1
- return "a"..n
- end)
- return extension
+ t[i]="a"..n
+ end
+ return format(extension,unpack(t))
end
end
local builder=Cs { "start",
@@ -3990,6 +3993,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['util-fil']={
version=1.001,
+ optimize=true,
comment="companion to luat-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -4438,14 +4442,14 @@ utilities.parsers=utilities.parsers or {
end,
settings_to_hash=function(s)
local t={}
- for k,v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do
+ for k,v in gmatch((gsub(s,"^{(.*)}$","%1")),"([^%s,=]+)=([^%s,]+)") do
t[k]=v
end
return t
end,
settings_to_hash_colon_too=function(s)
local t={}
- for k,v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do
+ for k,v in gmatch((gsub(s,"^{(.*)}$","%1")),"([^%s,=:]+)[=:]([^%s,]+)") do
t[k]=v
end
return t
@@ -4910,6 +4914,7 @@ end
nodes.nodecodes=nodecodes
nodes.glyphcodes=glyphcodes
nodes.disccodes=disccodes
+nodes.dirvalues={ lefttoright=0,righttoleft=1 }
nodes.handlers.protectglyphs=node.protect_glyphs
nodes.handlers.unprotectglyphs=node.unprotect_glyphs
local direct=node.direct
@@ -8917,6 +8922,9 @@ function constructors.assignmathparameters(target,original)
if not mathparameters.FractionDelimiterDisplayStyleSize then
targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
end
+ if not targetmathparameters.SpaceBeforeScript then
+ targetmathparameters.SpaceBeforeScript=targetmathparameters.SpaceAfterScript
+ end
target.mathparameters=targetmathparameters
end
end
@@ -8924,31 +8932,40 @@ function constructors.beforecopyingcharacters(target,original)
end
function constructors.aftercopyingcharacters(target,original)
end
-constructors.sharefonts=false
-constructors.nofsharedfonts=0
-local sharednames={}
+local nofinstances=0
+local instances=setmetatableindex(function(t,k)
+ nofinstances=nofinstances+1
+ t[k]=nofinstances
+ return nofinstances
+end)
function constructors.trytosharefont(target,tfmdata)
- if constructors.sharefonts then
- local characters=target.characters
- local n=1
- local t={ target.psname }
- local u=sortedkeys(characters)
- for i=1,#u do
- local k=u[i]
- n=n+1;t[n]=k
- n=n+1;t[n]=characters[k].index or k
- end
- local h=md5.HEX(concat(t," "))
- local s=sharednames[h]
- if s then
- if trace_defining then
- report_defining("font %a uses backend resources of font %a",target.fullname,s)
- end
- target.fullname=s
- constructors.nofsharedfonts=constructors.nofsharedfonts+1
- target.properties.sharedwith=s
+ local properties=target.properties
+ local instance=properties.instance
+ if instance then
+ local fullname=target.fullname
+ local fontname=target.fontname
+ local psname=target.psname
+ local format=tfmdata.properties.format
+ if format=="opentype" then
+ target.streamprovider=1
+ elseif format=="truetype" then
+ target.streamprovider=2
else
- sharednames[h]=target.fullname
+ target.streamprovider=0
+ end
+ if target.streamprovider>0 then
+ if fullname then
+ fullname=fullname..":"..instances[instance]
+ target.fullname=fullname
+ end
+ if fontname then
+ fontname=fontname..":"..instances[instance]
+ target.fontname=fontname
+ end
+ if psname then
+ psname=psname..":"..instances[instance]
+ target.psname=psname
+ end
end
end
end
@@ -9114,12 +9131,14 @@ function constructors.scale(tfmdata,specification)
target.cidinfo=properties.cidinfo
target.format=properties.format
target.cache=constructors.cacheintex and "yes" or "renew"
+ local original=properties.original or tfmdata.original
local fontname=properties.fontname or tfmdata.fontname
local fullname=properties.fullname or tfmdata.fullname
local filename=properties.filename or tfmdata.filename
local psname=properties.psname or tfmdata.psname
local name=properties.name or tfmdata.name
local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+ target.original=original
target.fontname=fontname
target.fullname=fullname
target.filename=filename
@@ -9209,6 +9228,14 @@ function constructors.scale(tfmdata,specification)
targetparameters.x_height=targetx_height
targetparameters.quad=targetquad
targetparameters.extra_space=targetextra_space
+ local hshift=parameters.hshift
+ if hshift then
+ targetparameters.hshift=delta*hshift
+ end
+ local vshift=parameters.vshift
+ if vshift then
+ targetparameters.vshift=delta*vshift
+ end
local ascender=parameters.ascender
if ascender then
targetparameters.ascender=delta*ascender
@@ -10370,6 +10397,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-map']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -10454,6 +10482,7 @@ end
local hash={}
local conc={}
table.setmetatableindex(hash,function(t,k)
+ local v
if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
v=f_single(k)
else
@@ -10865,7 +10894,6 @@ local insert=table.insert
local fonts=fonts
local helpers=fonts.helpers
local setmetatableindex=table.setmetatableindex
-local makeweak=table.makeweak
local push={ "push" }
local pop={ "pop" }
local dummy={ "comment" }
@@ -10955,6 +10983,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-otr']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -12396,17 +12425,11 @@ local function readtable(tag,f,fontdata,specification,...)
reader(f,fontdata,specification,...)
end
end
-local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
local function readdata(f,offset,specification)
local fontdata,tables=loadtables(f,specification,offset)
if specification.glyphs then
prepareglyps(fontdata)
end
- if not variablefonts_supported then
- specification.instance=nil
- specification.variable=nil
- specification.factors=nil
- end
fontdata.temporary={}
readtable("name",f,fontdata,specification)
local askedname=specification.askedname
@@ -12421,62 +12444,60 @@ local function readdata(f,offset,specification)
readtable("stat",f,fontdata,specification)
readtable("avar",f,fontdata,specification)
readtable("fvar",f,fontdata,specification)
- if variablefonts_supported then
- local variabledata=fontdata.variabledata
- if variabledata then
- local instances=variabledata.instances
- local axis=variabledata.axis
- if axis and (not instances or #instances==0) then
- instances={}
- variabledata.instances=instances
- local function add(n,subfamily,value)
- local values={}
- for i=1,#axis do
- local a=axis[i]
- values[i]={
- axis=a.tag,
- value=i==n and value or a.default,
- }
- end
- instances[#instances+1]={
- subfamily=subfamily,
- values=values,
- }
- end
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ if axis and (not instances or #instances==0) then
+ instances={}
+ variabledata.instances=instances
+ local function add(n,subfamily,value)
+ local values={}
for i=1,#axis do
local a=axis[i]
- local tag=a.tag
- add(i,"default"..tag,a.default)
- add(i,"minimum"..tag,a.minimum)
- add(i,"maximum"..tag,a.maximum)
- end
- end
- end
- if not specification.factors then
- local instance=specification.instance
- if type(instance)=="string" then
- local factors=helpers.getfactors(fontdata,instance)
- if factors then
- specification.factors=factors
- fontdata.factors=factors
- fontdata.instance=instance
- report("user instance: %s, factors: % t",instance,factors)
- else
- report("user instance: %s, bad factors",instance)
+ values[i]={
+ axis=a.tag,
+ value=i==n and value or a.default,
+ }
end
+ instances[#instances+1]={
+ subfamily=subfamily,
+ values=values,
+ }
+ end
+ for i=1,#axis do
+ local a=axis[i]
+ local tag=a.tag
+ add(i,"default"..tag,a.default)
+ add(i,"minimum"..tag,a.minimum)
+ add(i,"maximum"..tag,a.maximum)
end
end
- if not fontdata.factors then
- if fontdata.variabledata then
- local factors=helpers.getfactors(fontdata,true)
- if factors then
- specification.factors=factors
- fontdata.factors=factors
- end
+ end
+ if not specification.factors then
+ local instance=specification.instance
+ if type(instance)=="string" then
+ local factors=helpers.getfactors(fontdata,instance)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ fontdata.instance=instance
+ report("user instance: %s, factors: % t",instance,factors)
else
+ report("user instance: %s, bad factors",instance)
end
end
end
+ if not fontdata.factors then
+ if fontdata.variabledata then
+ local factors=helpers.getfactors(fontdata,true)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ end
+ else
+ end
+ end
readtable("os/2",f,fontdata,specification)
readtable("head",f,fontdata,specification)
readtable("maxp",f,fontdata,specification)
@@ -12698,6 +12719,7 @@ function readers.loadfont(filename,n,instance)
hascolor=fontdata.hascolor or false,
instance=fontdata.instance,
factors=fontdata.factors,
+ nofsubfonts=fontdata.subfonts and #fontdata.subfonts or nil,
},
resources={
filename=filename,
@@ -12805,1274 +12827,9 @@ end -- closure
do -- begin closure to overcome local limits and interference
-if not modules then modules={} end modules ['font-oti']={
- 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 lower=string.lower
-local fonts=fonts
-local constructors=fonts.constructors
-local otf=constructors.handlers.otf
-local otffeatures=constructors.features.otf
-local registerotffeature=otffeatures.register
-local otftables=otf.tables or {}
-otf.tables=otftables
-local allocate=utilities.storage.allocate
-registerotffeature {
- name="features",
- description="initialization of feature handler",
- default=true,
-}
-local function setmode(tfmdata,value)
- if value then
- tfmdata.properties.mode=lower(value)
- end
-end
-otf.modeinitializer=setmode
-local function setlanguage(tfmdata,value)
- if value then
- local cleanvalue=lower(value)
- local languages=otftables and otftables.languages
- local properties=tfmdata.properties
- if not languages then
- properties.language=cleanvalue
- elseif languages[value] then
- properties.language=cleanvalue
- else
- properties.language="dflt"
- end
- end
-end
-local function setscript(tfmdata,value)
- if value then
- local cleanvalue=lower(value)
- local scripts=otftables and otftables.scripts
- local properties=tfmdata.properties
- if not scripts then
- properties.script=cleanvalue
- elseif scripts[value] then
- properties.script=cleanvalue
- else
- properties.script="dflt"
- end
- end
-end
-registerotffeature {
- name="mode",
- description="mode",
- initializers={
- base=setmode,
- node=setmode,
- plug=setmode,
- }
-}
-registerotffeature {
- name="language",
- description="language",
- initializers={
- base=setlanguage,
- node=setlanguage,
- plug=setlanguage,
- }
-}
-registerotffeature {
- name="script",
- description="script",
- initializers={
- base=setscript,
- node=setscript,
- plug=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
-
-do -- begin closure to overcome local limits and interference
-
-if not modules then modules={} end modules ["font-ott"]={
- 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 type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset
-local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find
-local sequenced=table.sequenced
-local is_boolean=string.is_boolean
-local setmetatableindex=table.setmetatableindex
-local setmetatablenewindex=table.setmetatablenewindex
-local allocate=utilities.storage.allocate
-local fonts=fonts
-local otf=fonts.handlers.otf
-local otffeatures=otf.features
-local tables=otf.tables or {}
-otf.tables=tables
-local statistics=otf.statistics or {}
-otf.statistics=statistics
-local scripts=allocate {
- ["adlm"]="adlam",
- ["aghb"]="caucasian albanian",
- ["ahom"]="ahom",
- ["arab"]="arabic",
- ["armi"]="imperial aramaic",
- ["armn"]="armenian",
- ["avst"]="avestan",
- ["bali"]="balinese",
- ["bamu"]="bamum",
- ["bass"]="bassa vah",
- ["batk"]="batak",
- ["beng"]="bengali",
- ["bhks"]="bhaiksuki",
- ["bng2"]="bengali variant 2",
- ["bopo"]="bopomofo",
- ["brah"]="brahmi",
- ["brai"]="braille",
- ["bugi"]="buginese",
- ["buhd"]="buhid",
- ["byzm"]="byzantine music",
- ["cakm"]="chakma",
- ["cans"]="canadian syllabics",
- ["cari"]="carian",
- ["cham"]="cham",
- ["cher"]="cherokee",
- ["copt"]="coptic",
- ["cprt"]="cypriot syllabary",
- ["cyrl"]="cyrillic",
- ["dev2"]="devanagari variant 2",
- ["deva"]="devanagari",
- ["dogr"]="dogra",
- ["dsrt"]="deseret",
- ["dupl"]="duployan",
- ["egyp"]="egyptian heiroglyphs",
- ["elba"]="elbasan",
- ["ethi"]="ethiopic",
- ["geor"]="georgian",
- ["gjr2"]="gujarati variant 2",
- ["glag"]="glagolitic",
- ["gong"]="gunjala gondi",
- ["gonm"]="masaram gondi",
- ["goth"]="gothic",
- ["gran"]="grantha",
- ["grek"]="greek",
- ["gujr"]="gujarati",
- ["gur2"]="gurmukhi variant 2",
- ["guru"]="gurmukhi",
- ["hang"]="hangul",
- ["hani"]="cjk ideographic",
- ["hano"]="hanunoo",
- ["hatr"]="hatran",
- ["hebr"]="hebrew",
- ["hluw"]="anatolian hieroglyphs",
- ["hmng"]="pahawh hmong",
- ["hung"]="old hungarian",
- ["ital"]="old italic",
- ["jamo"]="hangul jamo",
- ["java"]="javanese",
- ["kali"]="kayah li",
- ["kana"]="hiragana and katakana",
- ["khar"]="kharosthi",
- ["khmr"]="khmer",
- ["khoj"]="khojki",
- ["knd2"]="kannada variant 2",
- ["knda"]="kannada",
- ["kthi"]="kaithi",
- ["lana"]="tai tham",
- ["lao" ]="lao",
- ["latn"]="latin",
- ["lepc"]="lepcha",
- ["limb"]="limbu",
- ["lina"]="linear a",
- ["linb"]="linear b",
- ["lisu"]="lisu",
- ["lyci"]="lycian",
- ["lydi"]="lydian",
- ["mahj"]="mahajani",
- ["maka"]="makasar",
- ["mand"]="mandaic and mandaean",
- ["mani"]="manichaean",
- ["marc"]="marchen",
- ["math"]="mathematical alphanumeric symbols",
- ["medf"]="medefaidrin",
- ["mend"]="mende kikakui",
- ["merc"]="meroitic cursive",
- ["mero"]="meroitic hieroglyphs",
- ["mlm2"]="malayalam variant 2",
- ["mlym"]="malayalam",
- ["modi"]="modi",
- ["mong"]="mongolian",
- ["mroo"]="mro",
- ["mtei"]="meitei Mayek",
- ["mult"]="multani",
- ["musc"]="musical symbols",
- ["mym2"]="myanmar variant 2",
- ["mymr"]="myanmar",
- ["narb"]="old north arabian",
- ["nbat"]="nabataean",
- ["newa"]="newa",
- ["nko" ]='n"ko',
- ["nshu"]="nüshu",
- ["ogam"]="ogham",
- ["olck"]="ol chiki",
- ["orkh"]="old turkic and orkhon runic",
- ["ory2"]="odia variant 2",
- ["orya"]="oriya",
- ["osge"]="osage",
- ["osma"]="osmanya",
- ["palm"]="palmyrene",
- ["pauc"]="pau cin hau",
- ["perm"]="old permic",
- ["phag"]="phags-pa",
- ["phli"]="inscriptional pahlavi",
- ["phlp"]="psalter pahlavi",
- ["phnx"]="phoenician",
- ["plrd"]="miao",
- ["prti"]="inscriptional parthian",
- ["rjng"]="rejang",
- ["rohg"]="hanifi rohingya",
- ["runr"]="runic",
- ["samr"]="samaritan",
- ["sarb"]="old south arabian",
- ["saur"]="saurashtra",
- ["sgnw"]="sign writing",
- ["shaw"]="shavian",
- ["shrd"]="sharada",
- ["sidd"]="siddham",
- ["sind"]="khudawadi",
- ["sinh"]="sinhala",
- ["sogd"]="sogdian",
- ["sogo"]="old sogdian",
- ["sora"]="sora sompeng",
- ["soyo"]="soyombo",
- ["sund"]="sundanese",
- ["sylo"]="syloti nagri",
- ["syrc"]="syriac",
- ["tagb"]="tagbanwa",
- ["takr"]="takri",
- ["tale"]="tai le",
- ["talu"]="tai lu",
- ["taml"]="tamil",
- ["tang"]="tangut",
- ["tavt"]="tai viet",
- ["tel2"]="telugu variant 2",
- ["telu"]="telugu",
- ["tfng"]="tifinagh",
- ["tglg"]="tagalog",
- ["thaa"]="thaana",
- ["thai"]="thai",
- ["tibt"]="tibetan",
- ["tirh"]="tirhuta",
- ["tml2"]="tamil variant 2",
- ["ugar"]="ugaritic cuneiform",
- ["vai" ]="vai",
- ["wara"]="warang citi",
- ["xpeo"]="old persian cuneiform",
- ["xsux"]="sumero-akkadian cuneiform",
- ["yi" ]="yi",
- ["zanb"]="zanabazar square",
-}
-local languages=allocate {
- ["aba" ]="abaza",
- ["abk" ]="abkhazian",
- ["ach" ]="acholi",
- ["acr" ]="achi",
- ["ady" ]="adyghe",
- ["afk" ]="afrikaans",
- ["afr" ]="afar",
- ["agw" ]="agaw",
- ["aio" ]="aiton",
- ["aka" ]="akan",
- ["als" ]="alsatian",
- ["alt" ]="altai",
- ["amh" ]="amharic",
- ["ang" ]="anglo-saxon",
- ["apph"]="phonetic transcription—americanist conventions",
- ["ara" ]="arabic",
- ["arg" ]="aragonese",
- ["ari" ]="aari",
- ["ark" ]="rakhine",
- ["asm" ]="assamese",
- ["ast" ]="asturian",
- ["ath" ]="athapaskan",
- ["avr" ]="avar",
- ["awa" ]="awadhi",
- ["aym" ]="aymara",
- ["azb" ]="torki",
- ["aze" ]="azerbaijani",
- ["bad" ]="badaga",
- ["bad0"]="banda",
- ["bag" ]="baghelkhandi",
- ["bal" ]="balkar",
- ["ban" ]="balinese",
- ["bar" ]="bavarian",
- ["bau" ]="baulé",
- ["bbc" ]="batak toba",
- ["bbr" ]="berber",
- ["bch" ]="bench",
- ["bcr" ]="bible cree",
- ["bdy" ]="bandjalang",
- ["bel" ]="belarussian",
- ["bem" ]="bemba",
- ["ben" ]="bengali",
- ["bgc" ]="haryanvi",
- ["bgq" ]="bagri",
- ["bgr" ]="bulgarian",
- ["bhi" ]="bhili",
- ["bho" ]="bhojpuri",
- ["bik" ]="bikol",
- ["bil" ]="bilen",
- ["bis" ]="bislama",
- ["bjj" ]="kanauji",
- ["bkf" ]="blackfoot",
- ["bli" ]="baluchi",
- ["blk" ]="pa'o karen",
- ["bln" ]="balante",
- ["blt" ]="balti",
- ["bmb" ]="bambara (bamanankan)",
- ["bml" ]="bamileke",
- ["bos" ]="bosnian",
- ["bpy" ]="bishnupriya manipuri",
- ["bre" ]="breton",
- ["brh" ]="brahui",
- ["bri" ]="braj bhasha",
- ["brm" ]="burmese",
- ["brx" ]="bodo",
- ["bsh" ]="bashkir",
- ["bsk" ]="burushaski",
- ["bti" ]="beti",
- ["bts" ]="batak simalungun",
- ["bug" ]="bugis",
- ["byv" ]="medumba",
- ["cak" ]="kaqchikel",
- ["cat" ]="catalan",
- ["cbk" ]="zamboanga chavacano",
- ["cchn"]="chinantec",
- ["ceb" ]="cebuano",
- ["cgg" ]="chiga",
- ["cha" ]="chamorro",
- ["che" ]="chechen",
- ["chg" ]="chaha gurage",
- ["chh" ]="chattisgarhi",
- ["chi" ]="chichewa (chewa, nyanja)",
- ["chk" ]="chukchi",
- ["chk0"]="chuukese",
- ["cho" ]="choctaw",
- ["chp" ]="chipewyan",
- ["chr" ]="cherokee",
- ["chu" ]="chuvash",
- ["chy" ]="cheyenne",
- ["cja" ]="western cham",
- ["cjm" ]="eastern cham",
- ["cmr" ]="comorian",
- ["cop" ]="coptic",
- ["cor" ]="cornish",
- ["cos" ]="corsican",
- ["cpp" ]="creoles",
- ["cre" ]="cree",
- ["crr" ]="carrier",
- ["crt" ]="crimean tatar",
- ["csb" ]="kashubian",
- ["csl" ]="church slavonic",
- ["csy" ]="czech",
- ["ctg" ]="chittagonian",
- ["cuk" ]="san blas kuna",
- ["dan" ]="danish",
- ["dar" ]="dargwa",
- ["dax" ]="dayi",
- ["dcr" ]="woods cree",
- ["deu" ]="german",
- ["dgo" ]="dogri",
- ["dgr" ]="dogri",
- ["dhg" ]="dhangu",
- ["dhv" ]="divehi (dhivehi, maldivian)",
- ["diq" ]="dimli",
- ["div" ]="divehi (dhivehi, maldivian)",
- ["djr" ]="zarma",
- ["djr0"]="djambarrpuyngu",
- ["dng" ]="dangme",
- ["dnj" ]="dan",
- ["dnk" ]="dinka",
- ["dri" ]="dari",
- ["duj" ]="dhuwal",
- ["dun" ]="dungan",
- ["dzn" ]="dzongkha",
- ["ebi" ]="ebira",
- ["ecr" ]="eastern cree",
- ["edo" ]="edo",
- ["efi" ]="efik",
- ["ell" ]="greek",
- ["emk" ]="eastern maninkakan",
- ["eng" ]="english",
- ["erz" ]="erzya",
- ["esp" ]="spanish",
- ["esu" ]="central yupik",
- ["eti" ]="estonian",
- ["euq" ]="basque",
- ["evk" ]="evenki",
- ["evn" ]="even",
- ["ewe" ]="ewe",
- ["fan" ]="french antillean",
- ["fan0"]=" fang",
- ["far" ]="persian",
- ["fat" ]="fanti",
- ["fin" ]="finnish",
- ["fji" ]="fijian",
- ["fle" ]="dutch (flemish)",
- ["fmp" ]="fe’fe’",
- ["fne" ]="forest nenets",
- ["fon" ]="fon",
- ["fos" ]="faroese",
- ["fra" ]="french",
- ["frc" ]="cajun french",
- ["fri" ]="frisian",
- ["frl" ]="friulian",
- ["frp" ]="arpitan",
- ["fta" ]="futa",
- ["ful" ]="fulah",
- ["fuv" ]="nigerian fulfulde",
- ["gad" ]="ga",
- ["gae" ]="scottish gaelic (gaelic)",
- ["gag" ]="gagauz",
- ["gal" ]="galician",
- ["gar" ]="garshuni",
- ["gaw" ]="garhwali",
- ["gez" ]="ge'ez",
- ["gih" ]="githabul",
- ["gil" ]="gilyak",
- ["gil0"]="kiribati (gilbertese)",
- ["gkp" ]="kpelle (guinea)",
- ["glk" ]="gilaki",
- ["gmz" ]="gumuz",
- ["gnn" ]="gumatj",
- ["gog" ]="gogo",
- ["gon" ]="gondi",
- ["grn" ]="greenlandic",
- ["gro" ]="garo",
- ["gua" ]="guarani",
- ["guc" ]="wayuu",
- ["guf" ]="gupapuyngu",
- ["guj" ]="gujarati",
- ["guz" ]="gusii",
- ["hai" ]="haitian (haitian creole)",
- ["hal" ]="halam",
- ["har" ]="harauti",
- ["hau" ]="hausa",
- ["haw" ]="hawaiian",
- ["hay" ]="haya",
- ["haz" ]="hazaragi",
- ["hbn" ]="hammer-banna",
- ["her" ]="herero",
- ["hil" ]="hiligaynon",
- ["hin" ]="hindi",
- ["hma" ]="high mari",
- ["hmn" ]="hmong",
- ["hmo" ]="hiri motu",
- ["hnd" ]="hindko",
- ["ho" ]="ho",
- ["hri" ]="harari",
- ["hrv" ]="croatian",
- ["hun" ]="hungarian",
- ["hye" ]="armenian",
- ["hye0"]="armenian east",
- ["iba" ]="iban",
- ["ibb" ]="ibibio",
- ["ibo" ]="igbo",
- ["ido" ]="ido",
- ["ijo" ]="ijo languages",
- ["ile" ]="interlingue",
- ["ilo" ]="ilokano",
- ["ina" ]="interlingua",
- ["ind" ]="indonesian",
- ["ing" ]="ingush",
- ["inu" ]="inuktitut",
- ["ipk" ]="inupiat",
- ["ipph"]="phonetic transcription—ipa conventions",
- ["iri" ]="irish",
- ["irt" ]="irish traditional",
- ["isl" ]="icelandic",
- ["ism" ]="inari sami",
- ["ita" ]="italian",
- ["iwr" ]="hebrew",
- ["jam" ]="jamaican creole",
- ["jan" ]="japanese",
- ["jav" ]="javanese",
- ["jbo" ]="lojban",
- ["jct" ]="krymchak",
- ["jii" ]="yiddish",
- ["jud" ]="ladino",
- ["jul" ]="jula",
- ["kab" ]="kabardian",
- ["kab0"]="kabyle",
- ["kac" ]="kachchi",
- ["kal" ]="kalenjin",
- ["kan" ]="kannada",
- ["kar" ]="karachay",
- ["kat" ]="georgian",
- ["kaz" ]="kazakh",
- ["kde" ]="makonde",
- ["kea" ]="kabuverdianu (crioulo)",
- ["keb" ]="kebena",
- ["kek" ]="kekchi",
- ["kge" ]="khutsuri georgian",
- ["kha" ]="khakass",
- ["khk" ]="khanty-kazim",
- ["khm" ]="khmer",
- ["khs" ]="khanty-shurishkar",
- ["kht" ]="khamti shan",
- ["khv" ]="khanty-vakhi",
- ["khw" ]="khowar",
- ["kik" ]="kikuyu (gikuyu)",
- ["kir" ]="kirghiz (kyrgyz)",
- ["kis" ]="kisii",
- ["kiu" ]="kirmanjki",
- ["kjd" ]="southern kiwai",
- ["kjp" ]="eastern pwo karen",
- ["kjz" ]="bumthangkha",
- ["kkn" ]="kokni",
- ["klm" ]="kalmyk",
- ["kmb" ]="kamba",
- ["kmn" ]="kumaoni",
- ["kmo" ]="komo",
- ["kms" ]="komso",
- ["kmz" ]="khorasani turkic",
- ["knr" ]="kanuri",
- ["kod" ]="kodagu",
- ["koh" ]="korean old hangul",
- ["kok" ]="konkani",
- ["kom" ]="komi",
- ["kon" ]="kikongo",
- ["kon0"]="kongo",
- ["kop" ]="komi-permyak",
- ["kor" ]="korean",
- ["kos" ]="kosraean",
- ["koz" ]="komi-zyrian",
- ["kpl" ]="kpelle",
- ["kri" ]="krio",
- ["krk" ]="karakalpak",
- ["krl" ]="karelian",
- ["krm" ]="karaim",
- ["krn" ]="karen",
- ["krt" ]="koorete",
- ["ksh" ]="kashmiri",
- ["ksh0"]="ripuarian",
- ["ksi" ]="khasi",
- ["ksm" ]="kildin sami",
- ["ksw" ]="s’gaw karen",
- ["kua" ]="kuanyama",
- ["kui" ]="kui",
- ["kul" ]="kulvi",
- ["kum" ]="kumyk",
- ["kur" ]="kurdish",
- ["kuu" ]="kurukh",
- ["kuy" ]="kuy",
- ["kyk" ]="koryak",
- ["kyu" ]="western kayah",
- ["lad" ]="ladin",
- ["lah" ]="lahuli",
- ["lak" ]="lak",
- ["lam" ]="lambani",
- ["lao" ]="lao",
- ["lat" ]="latin",
- ["laz" ]="laz",
- ["lcr" ]="l-cree",
- ["ldk" ]="ladakhi",
- ["lez" ]="lezgi",
- ["lij" ]="ligurian",
- ["lim" ]="limburgish",
- ["lin" ]="lingala",
- ["lis" ]="lisu",
- ["ljp" ]="lampung",
- ["lki" ]="laki",
- ["lma" ]="low mari",
- ["lmb" ]="limbu",
- ["lmo" ]="lombard",
- ["lmw" ]="lomwe",
- ["lom" ]="loma",
- ["lrc" ]="luri",
- ["lsb" ]="lower sorbian",
- ["lsm" ]="lule sami",
- ["lth" ]="lithuanian",
- ["ltz" ]="luxembourgish",
- ["lua" ]="luba-lulua",
- ["lub" ]="luba-katanga",
- ["lug" ]="ganda",
- ["luh" ]="luyia",
- ["luo" ]="luo",
- ["lvi" ]="latvian",
- ["mad" ]="madura",
- ["mag" ]="magahi",
- ["mah" ]="marshallese",
- ["maj" ]="majang",
- ["mak" ]="makhuwa",
- ["mal" ]="malayalam reformed",
- ["mam" ]="mam",
- ["man" ]="mansi",
- ["map" ]="mapudungun",
- ["mar" ]="marathi",
- ["maw" ]="marwari",
- ["mbn" ]="mbundu",
- ["mbo" ]="mbo",
- ["mch" ]="manchu",
- ["mcr" ]="moose cree",
- ["mde" ]="mende",
- ["mdr" ]="mandar",
- ["men" ]="me'en",
- ["mer" ]="meru",
- ["mfa" ]="pattani malay",
- ["mfe" ]="morisyen",
- ["min" ]="minangkabau",
- ["miz" ]="mizo",
- ["mkd" ]="macedonian",
- ["mkr" ]="makasar",
- ["mkw" ]="kituba",
- ["mle" ]="male",
- ["mlg" ]="malagasy",
- ["mln" ]="malinke",
- ["mlr" ]="malayalam reformed",
- ["mly" ]="malay",
- ["mnd" ]="mandinka",
- ["mng" ]="mongolian",
- ["mni" ]="manipuri",
- ["mnk" ]="maninka",
- ["mnx" ]="manx",
- ["moh" ]="mohawk",
- ["mok" ]="moksha",
- ["mol" ]="moldavian",
- ["mon" ]="mon",
- ["mor" ]="moroccan",
- ["mos" ]="mossi",
- ["mri" ]="maori",
- ["mth" ]="maithili",
- ["mts" ]="maltese",
- ["mun" ]="mundari",
- ["mus" ]="muscogee",
- ["mwl" ]="mirandese",
- ["mww" ]="hmong daw",
- ["myn" ]="mayan",
- ["mzn" ]="mazanderani",
- ["nag" ]="naga-assamese",
- ["nah" ]="nahuatl",
- ["nan" ]="nanai",
- ["nap" ]="neapolitan",
- ["nas" ]="naskapi",
- ["nau" ]="nauruan",
- ["nav" ]="navajo",
- ["ncr" ]="n-cree",
- ["ndb" ]="ndebele",
- ["ndc" ]="ndau",
- ["ndg" ]="ndonga",
- ["nds" ]="low saxon",
- ["nep" ]="nepali",
- ["new" ]="newari",
- ["nga" ]="ngbaka",
- ["ngr" ]="nagari",
- ["nhc" ]="norway house cree",
- ["nis" ]="nisi",
- ["niu" ]="niuean",
- ["nkl" ]="nyankole",
- ["nko" ]="n'ko",
- ["nld" ]="dutch",
- ["noe" ]="nimadi",
- ["nog" ]="nogai",
- ["nor" ]="norwegian",
- ["nov" ]="novial",
- ["nsm" ]="northern sami",
- ["nso" ]="sotho, northern",
- ["nta" ]="northern tai",
- ["nto" ]="esperanto",
- ["nym" ]="nyamwezi",
- ["nyn" ]="norwegian nynorsk",
- ["nza" ]="mbembe tigon",
- ["oci" ]="occitan",
- ["ocr" ]="oji-cree",
- ["ojb" ]="ojibway",
- ["ori" ]="odia",
- ["oro" ]="oromo",
- ["oss" ]="ossetian",
- ["paa" ]="palestinian aramaic",
- ["pag" ]="pangasinan",
- ["pal" ]="pali",
- ["pam" ]="pampangan",
- ["pan" ]="punjabi",
- ["pap" ]="palpa",
- ["pap0"]="papiamentu",
- ["pas" ]="pashto",
- ["pau" ]="palauan",
- ["pcc" ]="bouyei",
- ["pcd" ]="picard",
- ["pdc" ]="pennsylvania german",
- ["pgr" ]="polytonic greek",
- ["phk" ]="phake",
- ["pih" ]="norfolk",
- ["pil" ]="filipino",
- ["plg" ]="palaung",
- ["plk" ]="polish",
- ["pms" ]="piemontese",
- ["pnb" ]="western panjabi",
- ["poh" ]="pocomchi",
- ["pon" ]="pohnpeian",
- ["pro" ]="provencal",
- ["ptg" ]="portuguese",
- ["pwo" ]="western pwo karen",
- ["qin" ]="chin",
- ["quc" ]="k’iche’",
- ["quh" ]="quechua (bolivia)",
- ["quz" ]="quechua",
- ["qvi" ]="quechua (ecuador)",
- ["qwh" ]="quechua (peru)",
- ["raj" ]="rajasthani",
- ["rar" ]="rarotongan",
- ["rbu" ]="russian buriat",
- ["rcr" ]="r-cree",
- ["rej" ]="rejang",
- ["ria" ]="riang",
- ["rif" ]="tarifit",
- ["rit" ]="ritarungo",
- ["rkw" ]="arakwal",
- ["rms" ]="romansh",
- ["rmy" ]="vlax romani",
- ["rom" ]="romanian",
- ["roy" ]="romany",
- ["rsy" ]="rusyn",
- ["rtm" ]="rotuman",
- ["rua" ]="kinyarwanda",
- ["run" ]="rundi",
- ["rup" ]="aromanian",
- ["rus" ]="russian",
- ["sad" ]="sadri",
- ["san" ]="sanskrit",
- ["sas" ]="sasak",
- ["sat" ]="santali",
- ["say" ]="sayisi",
- ["scn" ]="sicilian",
- ["sco" ]="scots",
- ["scs" ]="north slavey",
- ["sek" ]="sekota",
- ["sel" ]="selkup",
- ["sga" ]="old irish",
- ["sgo" ]="sango",
- ["sgs" ]="samogitian",
- ["shi" ]="tachelhit",
- ["shn" ]="shan",
- ["sib" ]="sibe",
- ["sid" ]="sidamo",
- ["sig" ]="silte gurage",
- ["sks" ]="skolt sami",
- ["sky" ]="slovak",
- ["sla" ]="slavey",
- ["slv" ]="slovenian",
- ["sml" ]="somali",
- ["smo" ]="samoan",
- ["sna" ]="sena",
- ["sna0"]="shona",
- ["snd" ]="sindhi",
- ["snh" ]="sinhala (sinhalese)",
- ["snk" ]="soninke",
- ["sog" ]="sodo gurage",
- ["sop" ]="songe",
- ["sot" ]="sotho, southern",
- ["sqi" ]="albanian",
- ["srb" ]="serbian",
- ["srd" ]="sardinian",
- ["srk" ]="saraiki",
- ["srr" ]="serer",
- ["ssl" ]="south slavey",
- ["ssm" ]="southern sami",
- ["stq" ]="saterland frisian",
- ["suk" ]="sukuma",
- ["sun" ]="sundanese",
- ["sur" ]="suri",
- ["sva" ]="svan",
- ["sve" ]="swedish",
- ["swa" ]="swadaya aramaic",
- ["swk" ]="swahili",
- ["swz" ]="swati",
- ["sxt" ]="sutu",
- ["sxu" ]="upper saxon",
- ["syl" ]="sylheti",
- ["syr" ]="syriac",
- ["syre"]="estrangela syriac",
- ["syrj"]="western syriac",
- ["syrn"]="eastern syriac",
- ["szl" ]="silesian",
- ["tab" ]="tabasaran",
- ["taj" ]="tajiki",
- ["tam" ]="tamil",
- ["tat" ]="tatar",
- ["tcr" ]="th-cree",
- ["tdd" ]="dehong dai",
- ["tel" ]="telugu",
- ["tet" ]="tetum",
- ["tgl" ]="tagalog",
- ["tgn" ]="tongan",
- ["tgr" ]="tigre",
- ["tgy" ]="tigrinya",
- ["tha" ]="thai",
- ["tht" ]="tahitian",
- ["tib" ]="tibetan",
- ["tiv" ]="tiv",
- ["tkm" ]="turkmen",
- ["tmh" ]="tamashek",
- ["tmn" ]="temne",
- ["tna" ]="tswana",
- ["tne" ]="tundra nenets",
- ["tng" ]="tonga",
- ["tod" ]="todo",
- ["tod0"]="toma",
- ["tpi" ]="tok pisin",
- ["trk" ]="turkish",
- ["tsg" ]="tsonga",
- ["tsj" ]="tshangla",
- ["tua" ]="turoyo aramaic",
- ["tul" ]="tulu",
- ["tum" ]="tulu",
- ["tuv" ]="tuvin",
- ["tvl" ]="tuvalu",
- ["twi" ]="twi",
- ["tyz" ]="tày",
- ["tzm" ]="tamazight",
- ["tzo" ]="tzotzil",
- ["udm" ]="udmurt",
- ["ukr" ]="ukrainian",
- ["umb" ]="umbundu",
- ["urd" ]="urdu",
- ["usb" ]="upper sorbian",
- ["uyg" ]="uyghur",
- ["uzb" ]="uzbek",
- ["vec" ]="venetian",
- ["ven" ]="venda",
- ["vit" ]="vietnamese",
- ["vol" ]="volapük",
- ["vro" ]="võro",
- ["wa" ]="wa",
- ["wag" ]="wagdi",
- ["war" ]="waray-waray",
- ["wcr" ]="west-cree",
- ["wel" ]="welsh",
- ["wlf" ]="wolof",
- ["wln" ]="walloon",
- ["wtm" ]="mewati",
- ["xbd" ]="lü",
- ["xhs" ]="xhosa",
- ["xjb" ]="minjangbal",
- ["xkf" ]="khengkha",
- ["xog" ]="soga",
- ["xpe" ]="kpelle (liberia)",
- ["yak" ]="sakha",
- ["yao" ]="yao",
- ["yap" ]="yapese",
- ["yba" ]="yoruba",
- ["ycr" ]="y-cree",
- ["yic" ]="yi classic",
- ["yim" ]="yi modern",
- ["zea" ]="zealandic",
- ["zgh" ]="standard morrocan tamazigh",
- ["zha" ]="zhuang",
- ["zhh" ]="chinese, hong kong sar",
- ["zhp" ]="chinese phonetic",
- ["zhs" ]="chinese simplified",
- ["zht" ]="chinese traditional",
- ["znd" ]="zande",
- ["zul" ]="zulu",
- ["zza" ]="zazaki",
-}
-local features=allocate {
- ["aalt"]="access all alternates",
- ["abvf"]="above-base forms",
- ["abvm"]="above-base mark positioning",
- ["abvs"]="above-base substitutions",
- ["afrc"]="alternative fractions",
- ["akhn"]="akhands",
- ["blwf"]="below-base forms",
- ["blwm"]="below-base mark positioning",
- ["blws"]="below-base substitutions",
- ["c2pc"]="petite capitals from capitals",
- ["c2sc"]="small capitals from capitals",
- ["calt"]="contextual alternates",
- ["case"]="case-sensitive forms",
- ["ccmp"]="glyph composition/decomposition",
- ["cfar"]="conjunct form after ro",
- ["cjct"]="conjunct forms",
- ["clig"]="contextual ligatures",
- ["cpct"]="centered cjk punctuation",
- ["cpsp"]="capital spacing",
- ["cswh"]="contextual swash",
- ["curs"]="cursive positioning",
- ["dflt"]="default processing",
- ["dist"]="distances",
- ["dlig"]="discretionary ligatures",
- ["dnom"]="denominators",
- ["dtls"]="dotless forms",
- ["expt"]="expert forms",
- ["falt"]="final glyph alternates",
- ["fin2"]="terminal forms #2",
- ["fin3"]="terminal forms #3",
- ["fina"]="terminal forms",
- ["flac"]="flattened accents over capitals",
- ["frac"]="fractions",
- ["fwid"]="full width",
- ["half"]="half forms",
- ["haln"]="halant forms",
- ["halt"]="alternate half width",
- ["hist"]="historical forms",
- ["hkna"]="horizontal kana alternates",
- ["hlig"]="historical ligatures",
- ["hngl"]="hangul",
- ["hojo"]="hojo kanji forms",
- ["hwid"]="half width",
- ["init"]="initial forms",
- ["isol"]="isolated forms",
- ["ital"]="italics",
- ["jalt"]="justification alternatives",
- ["jp04"]="jis2004 forms",
- ["jp78"]="jis78 forms",
- ["jp83"]="jis83 forms",
- ["jp90"]="jis90 forms",
- ["kern"]="kerning",
- ["lfbd"]="left bounds",
- ["liga"]="standard ligatures",
- ["ljmo"]="leading jamo forms",
- ["lnum"]="lining figures",
- ["locl"]="localized forms",
- ["ltra"]="left-to-right alternates",
- ["ltrm"]="left-to-right mirrored forms",
- ["mark"]="mark positioning",
- ["med2"]="medial forms #2",
- ["medi"]="medial forms",
- ["mgrk"]="mathematical greek",
- ["mkmk"]="mark to mark positioning",
- ["mset"]="mark positioning via substitution",
- ["nalt"]="alternate annotation forms",
- ["nlck"]="nlc kanji forms",
- ["nukt"]="nukta forms",
- ["numr"]="numerators",
- ["onum"]="old style figures",
- ["opbd"]="optical bounds",
- ["ordn"]="ordinals",
- ["ornm"]="ornaments",
- ["palt"]="proportional alternate width",
- ["pcap"]="petite capitals",
- ["pkna"]="proportional kana",
- ["pnum"]="proportional figures",
- ["pref"]="pre-base forms",
- ["pres"]="pre-base substitutions",
- ["pstf"]="post-base forms",
- ["psts"]="post-base substitutions",
- ["pwid"]="proportional widths",
- ["qwid"]="quarter widths",
- ["rand"]="randomize",
- ["rclt"]="required contextual alternates",
- ["rkrf"]="rakar forms",
- ["rlig"]="required ligatures",
- ["rphf"]="reph form",
- ["rtbd"]="right bounds",
- ["rtla"]="right-to-left alternates",
- ["rtlm"]="right to left mirrored forms",
- ["rvrn"]="required variation alternates",
- ["ruby"]="ruby notation forms",
- ["salt"]="stylistic alternates",
- ["sinf"]="scientific inferiors",
- ["size"]="optical size",
- ["smcp"]="small capitals",
- ["smpl"]="simplified forms",
- ["ssty"]="script style",
- ["stch"]="stretching glyph decomposition",
- ["subs"]="subscript",
- ["sups"]="superscript",
- ["swsh"]="swash",
- ["titl"]="titling",
- ["tjmo"]="trailing jamo forms",
- ["tnam"]="traditional name forms",
- ["tnum"]="tabular figures",
- ["trad"]="traditional forms",
- ["twid"]="third widths",
- ["unic"]="unicase",
- ["valt"]="alternate vertical metrics",
- ["vatu"]="vattu variants",
- ["vert"]="vertical writing",
- ["vhal"]="alternate vertical half metrics",
- ["vjmo"]="vowel jamo forms",
- ["vkna"]="vertical kana alternates",
- ["vkrn"]="vertical kerning",
- ["vpal"]="proportional alternate vertical metrics",
- ["vrtr"]="vertical alternates for rotation",
- ["vrt2"]="vertical rotation",
- ["zero"]="slashed zero",
- ["trep"]="traditional tex replacements",
- ["tlig"]="traditional tex ligatures",
- ["ss.."]="stylistic set ..",
- ["cv.."]="character variant ..",
- ["js.."]="justification ..",
- ["dv.."]="devanagari ..",
- ["ml.."]="malayalam ..",
-}
-local baselines=allocate {
- ["hang"]="hanging baseline",
- ["icfb"]="ideographic character face bottom edge baseline",
- ["icft"]="ideographic character face tope edige baseline",
- ["ideo"]="ideographic em-box bottom edge baseline",
- ["idtp"]="ideographic em-box top edge baseline",
- ["math"]="mathematical centered baseline",
- ["romn"]="roman baseline"
-}
-tables.scripts=scripts
-tables.languages=languages
-tables.features=features
-tables.baselines=baselines
-local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
-local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
-local report_checks=logs.reporter("fonts","checks")
-if otffeatures.features then
- for k,v in next,otffeatures.features do
- features[k]=v
- end
- otffeatures.features=features
-end
-local function swapped(h)
- local r={}
- for k,v in next,h do
- r[gsub(v,"[^a-z0-9]","")]=k
- end
- return r
-end
-local verbosescripts=allocate(swapped(scripts ))
-local verboselanguages=allocate(swapped(languages))
-local verbosefeatures=allocate(swapped(features ))
-local verbosebaselines=allocate(swapped(baselines))
-local function resolve(t,k)
- if k then
- k=gsub(lower(k),"[^a-z0-9]","")
- local v=rawget(t,k)
- if v then
- return v
- end
- end
-end
-setmetatableindex(verbosescripts,resolve)
-setmetatableindex(verboselanguages,resolve)
-setmetatableindex(verbosefeatures,resolve)
-setmetatableindex(verbosebaselines,resolve)
-setmetatableindex(scripts,function(t,k)
- if k then
- k=lower(k)
- if k=="dflt" then
- return k
- end
- local v=rawget(t,k)
- if v then
- return v
- end
- k=gsub(k," ","")
- v=rawget(t,v)
- if v then
- return v
- elseif acceptscripts then
- report_checks("registering extra script %a",k)
- rawset(t,k,k)
- return k
- end
- end
- return "dflt"
-end)
-setmetatableindex(languages,function(t,k)
- if k then
- k=lower(k)
- if k=="dflt" then
- return k
- end
- local v=rawget(t,k)
- if v then
- return v
- end
- k=gsub(k," ","")
- v=rawget(t,v)
- if v then
- return v
- elseif acceptlanguages then
- report_checks("registering extra language %a",k)
- rawset(t,k,k)
- return k
- end
- end
- return "dflt"
-end)
-if setmetatablenewindex then
- setmetatablenewindex(languages,"ignore")
- setmetatablenewindex(scripts,"ignore")
- setmetatablenewindex(baselines,"ignore")
-end
-local function resolve(t,k)
- if k then
- k=lower(k)
- local v=rawget(t,k)
- if v then
- return v
- end
- k=gsub(k," ","")
- local v=rawget(t,k)
- if v then
- return v
- end
- local tag,dd=match(k,"(..)(%d+)")
- if tag and dd then
- local v=rawget(t,tag)
- if v then
- return v
- else
- local v=rawget(t,tag.."..")
- if v then
- return (gsub(v,"%.%.",tonumber(dd)))
- end
- end
- end
- end
- return k
-end
-setmetatableindex(features,resolve)
-local function assign(t,k,v)
- if k and v then
- v=lower(v)
- rawset(t,k,v)
- end
-end
-if setmetatablenewindex then
- setmetatablenewindex(features,assign)
-end
-local checkers={
- rand=function(v)
- return v==true and "random" or v
- end
-}
-if not storage then
- return
-end
-local usedfeatures=statistics.usedfeatures or {}
-statistics.usedfeatures=usedfeatures
-table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end)
-storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" )
-local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end
-function otffeatures.normalize(features,wrap)
- if features then
- local h={}
- for key,value in next,features do
- local k=lower(key)
- if k=="language" then
- local v=gsub(lower(value),"[^a-z0-9]","")
- h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt"
- elseif k=="script" then
- local v=gsub(lower(value),"[^a-z0-9]","")
- h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt"
- elseif k=="axis" then
- h[k]=normalizedaxis(value)
- if not callbacks.supported.glyph_stream_provider then
- h.variableshapes=true
- end
- else
- local uk=usedfeatures[key]
- local uv=uk[value]
- if uv then
- else
- uv=tonumber(value)
- if uv then
- elseif type(value)=="string" then
- local b=is_boolean(value)
- if type(b)=="nil" then
- if wrap and find(value,",") then
- uv="{"..lower(value).."}"
- else
- uv=lower(value)
- end
- else
- uv=b
- end
- elseif type(value)=="table" then
- uv=sequenced(t,",")
- else
- uv=value
- end
- if not rawget(features,k) then
- k=rawget(verbosefeatures,k) or k
- end
- local c=checkers[k]
- if c then
- uv=c(uv) or vc
- end
- uk[value]=uv
- end
- h[k]=uv
- end
- end
- return h
- end
-end
-
-end -- closure
-
-do -- begin closure to overcome local limits and interference
-
if not modules then modules={} end modules ['font-cff']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -14520,12 +13277,15 @@ do
local p_dictionary=(
p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
)^1
- parsedictionaries=function(data,dictionaries,what)
+ parsedictionaries=function(data,dictionaries,version)
stack={}
strings=data.strings
+ if trace_charstrings then
+ report("charstring format %a",version)
+ end
for i=1,#dictionaries do
top=0
- result=what=="cff" and {
+ result=version=="cff" and {
monospaced=false,
italicangle=0,
underlineposition=-100,
@@ -15324,6 +14084,7 @@ do
end
end
else
+ top=top-nofregions*n
end
end
local actions={ [0]=unsupported,
@@ -15899,8 +14660,8 @@ do
processshape(tab,index-1)
end
end
-local function readglobals(f,data)
- local routines=readlengths(f)
+local function readglobals(f,data,version)
+ local routines=readlengths(f,version=="cff2")
for i=1,#routines do
routines[i]=readbytetable(f,routines[i])
end
@@ -15954,14 +14715,14 @@ local function readprivates(f,data)
private.data=readstring(f,private.size)
end
end
-local function readlocals(f,data,dictionary)
+local function readlocals(f,data,dictionary,version)
local header=data.header
local private=dictionary.private
if private then
local subroutineoffset=private.data.subroutines
if subroutineoffset~=0 then
setposition(f,header.offset+private.offset+subroutineoffset)
- local subroutines=readlengths(f)
+ local subroutines=readlengths(f,version=="cff2")
for i=1,#subroutines do
subroutines[i]=readbytetable(f,subroutines[i])
end
@@ -15974,7 +14735,7 @@ local function readlocals(f,data,dictionary)
dictionary.subroutines={}
end
end
-local function readcharstrings(f,data,what)
+local function readcharstrings(f,data,version)
local header=data.header
local dictionaries=data.dictionaries
local dictionary=dictionaries[1]
@@ -15983,7 +14744,7 @@ local function readcharstrings(f,data,what)
if type(offset)~="number" then
elseif stringtype==2 then
setposition(f,header.offset+offset)
- local charstrings=readlengths(f,what=="cff2")
+ local charstrings=readlengths(f,version=="cff2")
local nofglyphs=#charstrings
for i=1,nofglyphs do
charstrings[i]=readstring(f,charstrings[i])
@@ -16013,7 +14774,8 @@ readers.parsecharstrings=parsecharstrings
local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionaries=data.dictionaries
local dictionary=dictionaries[1]
- readglobals(f,data)
+ local cid=not dictionary.private and dictionary.cid
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version=="cff2" then
dictionary.charset=nil
@@ -16021,9 +14783,27 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
readencodings(f,data)
readcharsets(f,data,dictionary)
end
+ if cid then
+ local fdarray=cid.fdarray
+ if fdarray then
+ setposition(f,data.header.offset+fdarray)
+ local dictionaries=readlengths(f,version=="cff2")
+ local nofdictionaries=#dictionaries
+ if nofdictionaries>0 then
+ for i=1,nofdictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ dictionary.private=dictionaries[1].private
+ if nofdictionaries>1 then
+ report("ignoring dictionaries > 1 in cid font")
+ end
+ end
+ end
+ end
readprivates(f,data)
parseprivates(data,data.dictionaries)
- readlocals(f,data,dictionary)
+ readlocals(f,data,dictionary,version)
startparsing(fontdata,data,streams)
parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
stopparsing(fontdata,data)
@@ -16034,7 +14814,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionary=dictionaries[1]
local cid=dictionary.cid
local cidselect=cid and cid.fdselect
- readglobals(f,data)
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version~="cff2" then
readencodings(f,data)
@@ -16078,7 +14858,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local cidarray=cid.fdarray
if cidarray then
setposition(f,header.offset+cidarray)
- local dictionaries=readlengths(f)
+ local dictionaries=readlengths(f,version=="cff2")
for i=1,#dictionaries do
dictionaries[i]=readstring(f,dictionaries[i])
end
@@ -16086,7 +14866,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
cid.dictionaries=dictionaries
readcidprivates(f,data)
for i=1,#dictionaries do
- readlocals(f,data,dictionaries[i])
+ readlocals(f,data,dictionaries[i],version)
end
startparsing(fontdata,data,streams)
for i=1,#charstrings do
@@ -16246,6 +15026,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-ttf']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -17418,6 +16199,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-dsp']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -20695,2643 +19477,1263 @@ end -- closure
do -- begin closure to overcome local limits and interference
-if not modules then modules={} end modules ['font-oup']={
+if not modules then modules={} end modules ['font-oti']={
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,type=next,type
-local P,R,S=lpeg.P,lpeg.R,lpeg.S
-local lpegmatch=lpeg.match
-local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
-local formatters=string.formatters
-local sortedkeys=table.sortedkeys
-local sortedhash=table.sortedhash
-local tohash=table.tohash
-local setmetatableindex=table.setmetatableindex
-local report_error=logs.reporter("otf reader","error")
-local report_markwidth=logs.reporter("otf reader","markwidth")
-local report_cleanup=logs.reporter("otf reader","cleanup")
-local report_optimizations=logs.reporter("otf reader","merges")
-local report_unicodes=logs.reporter("otf reader","unicodes")
-local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
-local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end)
-local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end)
-local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end)
-local readers=fonts.handlers.otf.readers
-local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
-local f_private=formatters["P%05X"]
-local f_unicode=formatters["U%05X"]
-local f_index=formatters["I%05X"]
-local f_character_y=formatters["%C"]
-local f_character_n=formatters["[ %C ]"]
-local check_duplicates=true
-local check_soft_hyphen=true
-directives.register("otf.checksofthyphen",function(v)
- check_soft_hyphen=v
-end)
-local function replaced(list,index,replacement)
- if type(list)=="number" then
- return replacement
- elseif type(replacement)=="table" then
- local t={}
- local n=index-1
- for i=1,n do
- t[i]=list[i]
- end
- for i=1,#replacement do
- n=n+1
- t[n]=replacement[i]
- end
- for i=index+1,#list do
- n=n+1
- t[n]=list[i]
- end
- else
- list[index]=replacement
- return list
- end
-end
-local function unifyresources(fontdata,indices)
- local descriptions=fontdata.descriptions
- local resources=fontdata.resources
- if not descriptions or not resources then
- return
- end
- local nofindices=#indices
- local variants=fontdata.resources.variants
- if variants then
- for selector,unicodes in next,variants do
- for unicode,index in next,unicodes do
- unicodes[unicode]=indices[index]
- end
- end
- end
- local function remark(marks)
- if marks then
- local newmarks={}
- for k,v in next,marks do
- local u=indices[k]
- if u then
- newmarks[u]=v
- elseif trace_optimizations then
- report_optimizations("discarding mark %i",k)
- end
- end
- return newmarks
- end
- end
- local marks=resources.marks
- if marks then
- resources.marks=remark(marks)
- end
- local markclasses=resources.markclasses
- if markclasses then
- for class,marks in next,markclasses do
- markclasses[class]=remark(marks)
- end
- end
- local marksets=resources.marksets
- if marksets then
- for class,marks in next,marksets do
- marksets[class]=remark(marks)
- end
- end
- local done={}
- local duplicates=check_duplicates and resources.duplicates
- if duplicates and not next(duplicates) then
- duplicates=false
- end
- local function recover(cover)
- for i=1,#cover do
- local c=cover[i]
- if not done[c] then
- local t={}
- for k,v in next,c do
- local ug=indices[k]
- if ug then
- t[ug]=v
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices)
- end
- end
- cover[i]=t
- done[c]=d
- end
- end
- end
- local function recursed(c,kind)
- local t={}
- for g,d in next,c do
- if type(d)=="table" then
- local ug=indices[g]
- if ug then
- t[ug]=recursed(d,kind)
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices)
- end
- else
- t[g]=indices[d]
- end
- end
- return t
- end
- local function unifythem(sequences)
- if not sequences then
- return
- end
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local features=sequence.features
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gsub_single" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- local ud1=indices[d1]
- if ud1 then
- t1[ug1]=ud1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=ud1
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices)
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=indices[d1]
- else
- report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
- end
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gpos_pair" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- local t2=done[d1]
- if not t2 then
- t2={}
- for g2,d2 in next,d1 do
- local ug2=indices[g2]
- if ug2 then
- t2[ug2]=d2
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices)
- end
- end
- done[d1]=t2
- end
- t1[ug1]=t2
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gsub_ligature" then
- local c=step.coverage
- if c then
- step.coverage=recursed(c,kind)
- end
- elseif kind=="gsub_alternate" or kind=="gsub_multiple" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- for i=1,#d1 do
- local d1i=d1[i]
- local d1u=indices[d1i]
- if d1u then
- d1[i]=d1u
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices)
- end
- end
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=copy(d1)
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- for i=1,#d1 do
- local d1i=d1[i]
- local d1u=indices[d1i]
- if d1u then
- d1[i]=d1u
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices)
- end
- end
- t1[indices[g1]]=d1
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gpos_single" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=d1
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- local c=step.baseclasses
- if c then
- local t1=done[c]
- if not t1 then
- for g1,d1 in next,c do
- local t2=done[d1]
- if not t2 then
- t2={}
- for g2,d2 in next,d1 do
- local ug2=indices[g2]
- if ug2 then
- t2[ug2]=d2
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices)
- end
- end
- done[d1]=t2
- end
- c[g1]=t2
- end
- done[c]=c
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=copy(d1)
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local before=rule.before if before then recover(before) end
- local after=rule.after if after then recover(after) end
- local current=rule.current if current then recover(current) end
- local replacements=rule.replacements
- if replacements then
- if not done[replacements] then
- local r={}
- for k,v in next,replacements do
- r[indices[k]]=indices[v]
- end
- rule.replacements=r
- done[replacements]=r
- end
- end
- end
- end
- end
- end
- end
- end
- unifythem(resources.sequences)
- unifythem(resources.sublookups)
-end
-local function copyduplicates(fontdata)
- if check_duplicates then
- local descriptions=fontdata.descriptions
- local resources=fontdata.resources
- local duplicates=resources.duplicates
- if check_soft_hyphen then
- local ds=descriptions[0xAD]
- if not ds or ds.width==0 then
- if ds then
- descriptions[0xAD]=nil
- if trace_unicodes then
- report_unicodes("patching soft hyphen")
- end
- else
- if trace_unicodes then
- report_unicodes("adding soft hyphen")
- end
- end
- if not duplicates then
- duplicates={}
- resources.duplicates=duplicates
- end
- local dh=duplicates[0x2D]
- if dh then
- dh[#dh+1]={ [0xAD]=true }
- else
- duplicates[0x2D]={ [0xAD]=true }
- end
- end
- end
- if duplicates then
- for u,d in next,duplicates do
- local du=descriptions[u]
- if du then
- local t={ f_character_y(u),"@",f_index(du.index),"->" }
- local n=0
- local m=25
- for u in next,d do
- if descriptions[u] then
- if n<m then
- t[n+4]=f_character_n(u)
- end
- else
- local c=copy(du)
- c.unicode=u
- descriptions[u]=c
- if n<m then
- t[n+4]=f_character_y(u)
- end
- end
- n=n+1
- end
- if trace_unicodes then
- if n<=m then
- report_unicodes("%i : % t",n,t)
- else
- report_unicodes("%i : % t ...",n,t)
- end
- end
- else
- end
- end
- end
- end
-end
-local ignore={
- ["notdef"]=true,
- [".notdef"]=true,
- ["null"]=true,
- [".null"]=true,
- ["nonmarkingreturn"]=true,
+local lower=string.lower
+local fonts=fonts
+local constructors=fonts.constructors
+local otf=constructors.handlers.otf
+local otffeatures=constructors.features.otf
+local registerotffeature=otffeatures.register
+local otftables=otf.tables or {}
+otf.tables=otftables
+local allocate=utilities.storage.allocate
+registerotffeature {
+ name="features",
+ description="initialization of feature handler",
+ default=true,
}
-local function checklookups(fontdata,missing,nofmissing)
- local descriptions=fontdata.descriptions
- local resources=fontdata.resources
- if missing and nofmissing and nofmissing<=0 then
- return
- end
- local singles={}
- local alternates={}
- local ligatures={}
- if not missing then
- missing={}
- nofmissing=0
- for u,d in next,descriptions do
- if not d.unicode then
- nofmissing=nofmissing+1
- missing[u]=true
- end
- end
- end
- local function collectthem(sequences)
- if not sequences then
- return
- end
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gsub_single" then
- local c=step.coverage
- if c then
- singles[#singles+1]=c
- end
- elseif kind=="gsub_alternate" then
- local c=step.coverage
- if c then
- alternates[#alternates+1]=c
- end
- elseif kind=="gsub_ligature" then
- local c=step.coverage
- if c then
- ligatures[#ligatures+1]=c
- end
- end
- end
- end
- end
- end
- collectthem(resources.sequences)
- collectthem(resources.sublookups)
- local loops=0
- while true do
- loops=loops+1
- local old=nofmissing
- for i=1,#singles do
- local c=singles[i]
- for g1,g2 in next,c do
- if missing[g1] then
- local u2=descriptions[g2].unicode
- if u2 then
- missing[g1]=false
- descriptions[g1].unicode=u2
- nofmissing=nofmissing-1
- end
- end
- if missing[g2] then
- local u1=descriptions[g1].unicode
- if u1 then
- missing[g2]=false
- descriptions[g2].unicode=u1
- nofmissing=nofmissing-1
- end
- end
- end
- end
- for i=1,#alternates do
- local c=alternates[i]
- for g1,d1 in next,c do
- if missing[g1] then
- for i=1,#d1 do
- local g2=d1[i]
- local u2=descriptions[g2].unicode
- if u2 then
- missing[g1]=false
- descriptions[g1].unicode=u2
- nofmissing=nofmissing-1
- end
- end
- end
- if not missing[g1] then
- for i=1,#d1 do
- local g2=d1[i]
- if missing[g2] then
- local u1=descriptions[g1].unicode
- if u1 then
- missing[g2]=false
- descriptions[g2].unicode=u1
- nofmissing=nofmissing-1
- end
- end
- end
- end
- end
- end
- if nofmissing<=0 then
- if trace_unicodes then
- report_unicodes("all missings done in %s loops",loops)
- end
- return
- elseif old==nofmissing then
- break
- end
- end
- local t,n
- local function recursed(c)
- for g,d in next,c do
- if g~="ligature" then
- local u=descriptions[g].unicode
- if u then
- n=n+1
- t[n]=u
- recursed(d)
- n=n-1
- end
- elseif missing[d] then
- local l={}
- local m=0
- for i=1,n do
- local u=t[i]
- if type(u)=="table" then
- for i=1,#u do
- m=m+1
- l[m]=u[i]
- end
- else
- m=m+1
- l[m]=u
- end
- end
- missing[d]=false
- descriptions[d].unicode=l
- nofmissing=nofmissing-1
- end
- end
- end
- if nofmissing>0 then
- t={}
- n=0
- local loops=0
- while true do
- loops=loops+1
- local old=nofmissing
- for i=1,#ligatures do
- recursed(ligatures[i])
- end
- if nofmissing<=0 then
- if trace_unicodes then
- report_unicodes("all missings done in %s loops",loops)
- end
- return
- elseif old==nofmissing then
- break
- end
- end
- t=nil
- n=0
- end
- if trace_unicodes and nofmissing>0 then
- local done={}
- for i,r in next,missing do
- if r then
- local data=descriptions[i]
- local name=data and data.name or f_index(i)
- if not ignore[name] then
- done[name]=true
- end
- end
- end
- if next(done) then
- report_unicodes("not unicoded: % t",sortedkeys(done))
- end
+local function setmode(tfmdata,value)
+ if value then
+ tfmdata.properties.mode=lower(value)
end
end
-local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
-local puafirst=0xE000
-local pualast=0xF8FF
-local function unifymissing(fontdata)
- if not fonts.mappings then
- require("font-map")
- require("font-agl")
- end
- local unicodes={}
- local resources=fontdata.resources
- resources.unicodes=unicodes
- for unicode,d in next,fontdata.descriptions do
- if unicode<privateoffset then
- if unicode>=puafirst and unicode<=pualast then
- else
- local name=d.name
- if name then
- unicodes[name]=unicode
- end
- end
+otf.modeinitializer=setmode
+local function setlanguage(tfmdata,value)
+ if value then
+ local cleanvalue=lower(value)
+ local languages=otftables and otftables.languages
+ local properties=tfmdata.properties
+ if not languages then
+ properties.language=cleanvalue
+ elseif languages[value] then
+ properties.language=cleanvalue
else
+ properties.language="dflt"
end
end
- fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
- resources.unicodes=nil
-end
-local function unifyglyphs(fontdata,usenames)
- local private=fontdata.private or privateoffset
- local glyphs=fontdata.glyphs
- local indices={}
- local descriptions={}
- local names=usenames and {}
- local resources=fontdata.resources
- local zero=glyphs[0]
- local zerocode=zero.unicode
- if not zerocode then
- zerocode=private
- zero.unicode=zerocode
- private=private+1
- end
- descriptions[zerocode]=zero
- if names then
- local name=glyphs[0].name or f_private(zerocode)
- indices[0]=name
- names[name]=zerocode
- else
- indices[0]=zerocode
- end
- if names then
- for index=1,#glyphs do
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=private
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- private=private+1
- elseif unicode>=firstprivate then
- unicode=private
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- private=private+1
- elseif unicode>=puafirst and unicode<=pualast then
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- elseif descriptions[unicode] then
- unicode=private
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- private=private+1
- else
- local name=glyph.name or f_unicode(unicode)
- indices[index]=name
- names[name]=unicode
- end
- descriptions[unicode]=glyph
- end
- elseif trace_unicodes then
- for index=1,#glyphs do
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=firstprivate then
- local name=glyph.name
- if name then
- report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private)
- else
- report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
- end
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=puafirst and unicode<=pualast then
- local name=glyph.name
- if name then
- report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index)
- else
- report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index)
- end
- indices[index]=unicode
- elseif descriptions[unicode] then
- local name=glyph.name
- if name then
- report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index)
- else
- report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index)
- end
- unicode=private
- indices[index]=unicode
- private=private+1
- else
- indices[index]=unicode
- end
- descriptions[unicode]=glyph
- end
- else
- for index=1,#glyphs do
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=firstprivate then
- local name=glyph.name
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=puafirst and unicode<=pualast then
- local name=glyph.name
- indices[index]=unicode
- elseif descriptions[unicode] then
- local name=glyph.name
- unicode=private
- indices[index]=unicode
- private=private+1
- else
- indices[index]=unicode
- end
- descriptions[unicode]=glyph
- end
- end
- for index=1,#glyphs do
- local math=glyphs[index].math
- if math then
- local list=math.vparts
- if list then
- for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
- end
- local list=math.hparts
- if list then
- for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
- end
- local list=math.vvariants
- if list then
- for i=1,#list do list[i]=indices[list[i]] end
- end
- local list=math.hvariants
- if list then
- for i=1,#list do list[i]=indices[list[i]] end
- end
- end
- end
- local colorpalettes=resources.colorpalettes
- if colorpalettes then
- for index=1,#glyphs do
- local colors=glyphs[index].colors
- if colors then
- for i=1,#colors do
- local c=colors[i]
- c.slot=indices[c.slot]
- end
- end
- end
- end
- fontdata.private=private
- fontdata.glyphs=nil
- fontdata.names=names
- fontdata.descriptions=descriptions
- fontdata.hashmethod=hashmethod
- return indices,names
end
-local p_crappyname do
- local p_hex=R("af","AF","09")
- local p_digit=R("09")
- local p_done=S("._-")^0+P(-1)
- local p_alpha=R("az","AZ")
- local p_ALPHA=R("AZ")
- p_crappyname=(
- lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
-+lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
-+lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
-+p_digit*p_hex^3+p_alpha*p_digit^1
-+P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
- )*p_done
-end
-local forcekeep=false
-directives.register("otf.keepnames",function(v)
- report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
- forcekeep=v
-end)
-local function stripredundant(fontdata)
- local descriptions=fontdata.descriptions
- if descriptions then
- local n=0
- local c=0
- if (not context and fonts.privateoffsets.keepnames) or forcekeep then
- for unicode,d in next,descriptions do
- if d.class=="base" then
- d.class=nil
- c=c+1
- end
- end
+local function setscript(tfmdata,value)
+ if value then
+ local cleanvalue=lower(value)
+ local scripts=otftables and otftables.scripts
+ local properties=tfmdata.properties
+ if not scripts then
+ properties.script=cleanvalue
+ elseif scripts[value] then
+ properties.script=cleanvalue
else
- for unicode,d in next,descriptions do
- local name=d.name
- if name and lpegmatch(p_crappyname,name) then
- d.name=nil
- n=n+1
- end
- if d.class=="base" then
- d.class=nil
- c=c+1
- end
- end
- end
- if trace_cleanup then
- if n>0 then
- report_cleanup("%s bogus names removed (verbose unicode)",n)
- end
- if c>0 then
- report_cleanup("%s base class tags removed (default is base)",c)
- end
- end
- end
-end
-readers.stripredundant=stripredundant
-function readers.getcomponents(fontdata)
- local resources=fontdata.resources
- if resources then
- local sequences=resources.sequences
- if sequences then
- local collected={}
- for i=1,#sequences do
- local sequence=sequences[i]
- if sequence.type=="gsub_ligature" then
- local steps=sequence.steps
- if steps then
- local l={}
- local function traverse(p,k,v)
- if k=="ligature" then
- collected[v]={ unpack(l) }
- else
- insert(l,k)
- for k,vv in next,v do
- traverse(p,k,vv)
- end
- remove(l)
- end
- end
- for i=1,#steps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- traverse(k,k,v)
- end
- end
- end
- end
- end
- end
- if next(collected) then
- while true do
- local done=false
- for k,v in next,collected do
- for i=1,#v do
- local vi=v[i]
- if vi==k then
- collected[k]=nil
- break
- else
- local c=collected[vi]
- if c then
- done=true
- local t={}
- local n=i-1
- for j=1,n do
- t[j]=v[j]
- end
- for j=1,#c do
- n=n+1
- t[n]=c[j]
- end
- for j=i+1,#v do
- n=n+1
- t[n]=v[j]
- end
- collected[k]=t
- break
- end
- end
- end
- end
- if not done then
- break
- end
- end
- return collected
- end
+ properties.script="dflt"
end
end
end
-readers.unifymissing=unifymissing
-function readers.rehash(fontdata,hashmethod)
- if not (fontdata and fontdata.glyphs) then
- return
- end
- if hashmethod=="indices" then
- fontdata.hashmethod="indices"
- elseif hashmethod=="names" then
- fontdata.hashmethod="names"
- local indices=unifyglyphs(fontdata,true)
- unifyresources(fontdata,indices)
- copyduplicates(fontdata)
- unifymissing(fontdata)
- else
- fontdata.hashmethod="unicodes"
- local indices=unifyglyphs(fontdata)
- unifyresources(fontdata,indices)
- copyduplicates(fontdata)
- unifymissing(fontdata)
- stripredundant(fontdata)
- end
-end
-function readers.checkhash(fontdata)
- local hashmethod=fontdata.hashmethod
- if hashmethod=="unicodes" then
- fontdata.names=nil
- elseif hashmethod=="names" and fontdata.names then
- unifyresources(fontdata,fontdata.names)
- copyduplicates(fontdata)
- fontdata.hashmethod="unicodes"
- fontdata.names=nil
- else
- readers.rehash(fontdata,"unicodes")
- end
-end
-function readers.addunicodetable(fontdata)
- local resources=fontdata.resources
- local unicodes=resources.unicodes
- if not unicodes then
- local descriptions=fontdata.descriptions
- if descriptions then
- unicodes={}
- resources.unicodes=unicodes
- for u,d in next,descriptions do
- local n=d.name
- if n then
- unicodes[n]=u
- end
+registerotffeature {
+ name="mode",
+ description="mode",
+ initializers={
+ base=setmode,
+ node=setmode,
+ plug=setmode,
+ }
+}
+registerotffeature {
+ name="language",
+ description="language",
+ initializers={
+ base=setlanguage,
+ node=setlanguage,
+ plug=setlanguage,
+ }
+}
+registerotffeature {
+ name="script",
+ description="script",
+ initializers={
+ base=setscript,
+ node=setscript,
+ plug=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
- end
- end
-end
-local concat,sort=table.concat,table.sort
-local next,type,tostring=next,type,tostring
-local criterium=1
-local threshold=0
-local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end)
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
-local report_otf=logs.reporter("fonts","otf loading")
-local function tabstr_normal(t)
- local s={}
- local n=0
- for k,v in next,t do
- n=n+1
- if type(v)=="table" then
- s[n]=k..">"..tabstr_normal(v)
- elseif v==true then
- s[n]=k.."+"
- elseif v then
- s[n]=k.."="..v
- else
- s[n]=k.."-"
- end
- end
- if n==0 then
- return ""
- elseif n==1 then
- return s[1]
- else
- sort(s)
- return concat(s,",")
- end
-end
-local function tabstr_flat(t)
- local s={}
- local n=0
- for k,v in next,t do
- n=n+1
- s[n]=k.."="..v
- end
- if n==0 then
- return ""
- elseif n==1 then
- return s[1]
- else
- sort(s)
- return concat(s,",")
- end
-end
-local function tabstr_mixed(t)
- local s={}
- local n=#t
- if n==0 then
- return ""
- elseif n==1 then
- local k=t[1]
- if k==true then
- return "++"
- elseif k==false then
- return "--"
else
- return tostring(k)
end
- else
- for i=1,n do
- local k=t[i]
- if k==true then
- s[i]="++"
- elseif k==false then
- s[i]="--"
- else
- s[i]=k
+ elseif featuretype=="substitution" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="substitution" or autoscript==true then
+ return default
end
end
- return concat(s,",")
end
end
-local function tabstr_boolean(t)
- local s={}
- local n=0
- for k,v in next,t do
- n=n+1
- if v then
- s[n]=k.."+"
- else
- s[n]=k.."-"
- end
- end
- if n==0 then
- return ""
- elseif n==1 then
- return s[1]
- else
- sort(s)
- return concat(s,",")
- end
-end
-function readers.pack(data)
- if data then
- local h,t,c={},{},{}
- local hh,tt,cc={},{},{}
- local nt,ntt=0,0
- local function pack_normal(v)
- local tag=tabstr_normal(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_normal_cc(v)
- local tag=tabstr_normal(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- v[1]=0
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_flat(v)
- local tag=tabstr_flat(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_indexed(v)
- local tag=concat(v," ")
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_mixed(v)
- local tag=tabstr_mixed(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_boolean(v)
- local tag=tabstr_boolean(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_final(v)
- if c[v]<=criterium then
- return t[v]
- else
- local hv=hh[v]
- if hv then
- return hv
- else
- ntt=ntt+1
- tt[ntt]=t[v]
- hh[v]=ntt
- cc[ntt]=c[v]
- return ntt
- end
- end
- end
- local function pack_final_cc(v)
- if c[v]<=criterium then
- return t[v]
- else
- local hv=hh[v]
- if hv then
- return hv
- else
- ntt=ntt+1
- tt[ntt]=t[v]
- hh[v]=ntt
- cc[ntt]=c[v]
- return ntt
- end
- end
- end
- local function success(stage,pass)
- if nt==0 then
- if trace_loading or trace_packing then
- report_otf("pack quality: nothing to pack")
- end
- return false
- elseif nt>=threshold then
- local one=0
- local two=0
- local rest=0
- if pass==1 then
- for k,v in next,c do
- if v==1 then
- one=one+1
- elseif v==2 then
- two=two+1
- else
- rest=rest+1
- end
- end
- else
- for k,v in next,cc do
- if v>20 then
- rest=rest+1
- elseif v>10 then
- two=two+1
- else
- one=one+1
- end
- end
- data.tables=tt
- end
- if trace_loading or trace_packing then
- report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
- stage,pass,one+two+rest,one,two,rest,criterium)
- end
- return true
- else
- if trace_loading or trace_packing then
- report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
- stage,pass,nt,threshold)
- end
- return false
- end
- end
- local function packers(pass)
- if pass==1 then
- return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc
+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
- return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc
- end
- end
- local resources=data.resources
- local sequences=resources.sequences
- local sublookups=resources.sublookups
- local features=resources.features
- local palettes=resources.colorpalettes
- local variable=resources.variabledata
- local chardata=characters and characters.data
- local descriptions=data.descriptions or data.glyphs
- if not descriptions then
- return
- end
- for pass=1,2 do
- if trace_packing then
- report_otf("start packing: stage 1, pass %s",pass)
- end
- local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
- for unicode,description in next,descriptions do
- local boundingbox=description.boundingbox
- if boundingbox then
- description.boundingbox=pack_indexed(boundingbox)
- end
- local math=description.math
- if math then
- local kerns=math.kerns
- if kerns then
- for tag,kern in next,kerns do
- kerns[tag]=pack_normal(kern)
- end
- end
- end
- end
- local function packthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local order=sequence.order
- local features=sequence.features
- local flags=sequence.flags
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format~="pair" then
- for g1,d1 in next,c do
- c[g1]=pack_normal(d1)
- end
- elseif step.shared then
- local shared={}
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- if not shared[d2] then
- local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
- local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
- shared[d2]=true
- end
- end
- end
- if pass==2 then
- step.shared=nil
- end
- else
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
- local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
- end
- end
- end
- end
- elseif kind=="gpos_single" then
- local c=step.coverage
- if c then
- if step.format=="single" then
- for g1,d1 in next,c do
- if d1 and d1~=true then
- c[g1]=pack_indexed(d1)
- end
- end
- else
- step.coverage=pack_normal(c)
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local f=d1[2] if f then d1[2]=pack_indexed(f) end
- local s=d1[3] if s then d1[3]=pack_indexed(s) end
- end
- end
- elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- d1[g2]=pack_indexed(d2)
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- d1[2]=pack_indexed(d1[2])
- end
- end
- elseif kind=="gpos_mark2ligature" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- for g3,d3 in next,d2 do
- d2[g3]=pack_indexed(d3)
- end
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- d1[2]=pack_indexed(d1[2])
- end
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
- local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
- local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
- local r=rule.replacements if r then rule.replacements=pack_flat (r) end
- end
- end
- end
- end
- if order then
- sequence.order=pack_indexed(order)
- end
- if features then
- for script,feature in next,features do
- features[script]=pack_normal(feature)
- end
- end
- if flags then
- sequence.flags=pack_normal(flags)
- end
- end
- end
- if sequences then
- packthem(sequences)
- end
- if sublookups then
- packthem(sublookups)
- end
- if features then
- for k,list in next,features do
- for feature,spec in next,list do
- list[feature]=pack_normal(spec)
- end
- end
- end
- if palettes then
- for i=1,#palettes do
- local p=palettes[i]
- for j=1,#p do
- p[j]=pack_indexed(p[j])
- end
- end
- end
- if variable then
- local instances=variable.instances
- if instances then
- for i=1,#instances do
- local v=instances[i].values
- for j=1,#v do
- v[j]=pack_normal(v[j])
- end
- end
- end
- local function packdeltas(main)
- if main then
- local deltas=main.deltas
- if deltas then
- for i=1,#deltas do
- local di=deltas[i]
- local d=di.deltas
- for j=1,#d do
- d[j]=pack_indexed(d[j])
- end
- di.regions=pack_indexed(di.regions)
- end
- end
- local regions=main.regions
- if regions then
- for i=1,#regions do
- local r=regions[i]
- for j=1,#r do
- r[j]=pack_normal(r[j])
- end
- end
- end
- end
- end
- packdeltas(variable.global)
- packdeltas(variable.horizontal)
- packdeltas(variable.vertical)
- packdeltas(variable.metrics)
- end
- if not success(1,pass) then
- return
+ report_otf("language feature %s not applied, enable default positioning")
end
+ else
end
- if nt>0 then
- for pass=1,2 do
- if trace_packing then
- report_otf("start packing: stage 2, pass %s",pass)
- end
- local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
- for unicode,description in next,descriptions do
- local math=description.math
- if math then
- local kerns=math.kerns
- if kerns then
- math.kerns=pack_normal(kerns)
- end
- end
- end
- local function packthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local features=sequence.features
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format=="pair" then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- d1[g2]=pack_normal(d2)
- end
- end
- end
- end
- elseif kind=="gpos_mark2ligature" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- d1[g2]=pack_normal(d2)
- end
- end
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local r=rule.before if r then rule.before=pack_normal(r) end
- local r=rule.after if r then rule.after=pack_normal(r) end
- local r=rule.current if r then rule.current=pack_normal(r) end
- end
- end
- end
- end
- if features then
- sequence.features=pack_normal(features)
- end
- end
- end
- if sequences then
- packthem(sequences)
- end
- if sublookups then
- packthem(sublookups)
- end
- if variable then
- local function unpackdeltas(main)
- if main then
- local regions=main.regions
- if regions then
- main.regions=pack_normal(regions)
- end
- end
- end
- unpackdeltas(variable.global)
- unpackdeltas(variable.horizontal)
- unpackdeltas(variable.vertical)
- unpackdeltas(variable.metrics)
- end
- end
- for pass=1,2 do
- if trace_packing then
- report_otf("start packing: stage 3, pass %s",pass)
- end
- local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
- local function packthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local features=sequence.features
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format=="pair" then
- for g1,d1 in next,c do
- c[g1]=pack_normal(d1)
- end
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- c[g1]=pack_normal_cc(d1)
- end
- end
- end
- end
- end
- end
- end
- if sequences then
- packthem(sequences)
- end
- if sublookups then
- packthem(sublookups)
- 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
-local unpacked_mt={
- __index=function(t,k)
- t[k]=false
- return k
- end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ["font-ott"]={
+ 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",
}
-function readers.unpack(data)
- if data then
- local tables=data.tables
- if tables then
- local resources=data.resources
- local descriptions=data.descriptions or data.glyphs
- local sequences=resources.sequences
- local sublookups=resources.sublookups
- local features=resources.features
- local palettes=resources.colorpalettes
- local variable=resources.variabledata
- local unpacked={}
- setmetatable(unpacked,unpacked_mt)
- for unicode,description in next,descriptions do
- local tv=tables[description.boundingbox]
- if tv then
- description.boundingbox=tv
- end
- local math=description.math
- if math then
- local kerns=math.kerns
- if kerns then
- local tm=tables[kerns]
- if tm then
- math.kerns=tm
- kerns=unpacked[tm]
- end
- if kerns then
- for k,kern in next,kerns do
- local tv=tables[kern]
- if tv then
- kerns[k]=tv
- end
- end
- end
- end
- end
- end
- local function unpackthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local order=sequence.order
- local features=sequence.features
- local flags=sequence.flags
- local markclass=sequence.markclass
- if features then
- local tv=tables[features]
- if tv then
- sequence.features=tv
- features=tv
- end
- for script,feature in next,features do
- local tv=tables[feature]
- if tv then
- features[script]=tv
- end
- end
- end
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format=="pair" then
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- c[g1]=tv
- d1=tv
- end
- for g2,d2 in next,d1 do
- local tv=tables[d2]
- if tv then
- d1[g2]=tv
- d2=tv
- end
- local f=tables[d2[1]] if f then d2[1]=f end
- local s=tables[d2[2]] if s then d2[2]=s end
- end
- end
- else
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- c[g1]=tv
- end
- end
- end
- end
- elseif kind=="gpos_single" then
- local c=step.coverage
- if c then
- if step.format=="single" then
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- c[g1]=tv
- end
- end
- else
- local tv=tables[c]
- if tv then
- step.coverage=tv
- end
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- d1=tv
- c[g1]=d1
- end
- local f=tables[d1[2]] if f then d1[2]=f end
- local s=tables[d1[3]] if s then d1[3]=s end
- end
- end
- elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- local tv=tables[d2]
- if tv then
- d1[g2]=tv
- end
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local tv=tables[d1[2]]
- if tv then
- d1[2]=tv
- end
- end
- end
- elseif kind=="gpos_mark2ligature" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- local tv=tables[d2]
- if tv then
- d2=tv
- d1[g2]=d2
- end
- for g3,d3 in next,d2 do
- local tv=tables[d2[g3]]
- if tv then
- d2[g3]=tv
- end
- end
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local tv=tables[d1[2]]
- if tv then
- d1[2]=tv
- end
- end
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local before=rule.before
- if before then
- local tv=tables[before]
- if tv then
- rule.before=tv
- before=tv
- end
- for i=1,#before do
- local tv=tables[before[i]]
- if tv then
- before[i]=tv
- end
- end
- end
- local after=rule.after
- if after then
- local tv=tables[after]
- if tv then
- rule.after=tv
- after=tv
- end
- for i=1,#after do
- local tv=tables[after[i]]
- if tv then
- after[i]=tv
- end
- end
- end
- local current=rule.current
- if current then
- local tv=tables[current]
- if tv then
- rule.current=tv
- current=tv
- end
- for i=1,#current do
- local tv=tables[current[i]]
- if tv then
- current[i]=tv
- end
- end
- end
- local replacements=rule.replacements
- if replacements then
- local tv=tables[replacements]
- if tv then
- rule.replacements=tv
- end
- end
- end
- end
- end
- end
- if order then
- local tv=tables[order]
- if tv then
- sequence.order=tv
- end
- end
- if flags then
- local tv=tables[flags]
- if tv then
- sequence.flags=tv
- end
- end
- end
- end
- if sequences then
- unpackthem(sequences)
- end
- if sublookups then
- unpackthem(sublookups)
- end
- if features then
- for k,list in next,features do
- for feature,spec in next,list do
- local tv=tables[spec]
- if tv then
- list[feature]=tv
- end
- end
- end
- end
- if palettes then
- for i=1,#palettes do
- local p=palettes[i]
- for j=1,#p do
- local tv=tables[p[j]]
- if tv then
- p[j]=tv
- end
- end
- end
- end
- if variable then
- local instances=variable.instances
- if instances then
- for i=1,#instances do
- local v=instances[i].values
- for j=1,#v do
- local tv=tables[v[j]]
- if tv then
- v[j]=tv
- end
- end
- end
- end
- local function unpackdeltas(main)
- if main then
- local deltas=main.deltas
- if deltas then
- for i=1,#deltas do
- local di=deltas[i]
- local d=di.deltas
- local r=di.regions
- for j=1,#d do
- local tv=tables[d[j]]
- if tv then
- d[j]=tv
- end
- end
- local tv=di.regions
- if tv then
- di.regions=tv
- end
- end
- end
- local regions=main.regions
- if regions then
- local tv=tables[regions]
- if tv then
- main.regions=tv
- regions=tv
- end
- for i=1,#regions do
- local r=regions[i]
- for j=1,#r do
- local tv=tables[r[j]]
- if tv then
- r[j]=tv
- end
- end
- end
- end
- end
- end
- unpackdeltas(variable.global)
- unpackdeltas(variable.horizontal)
- unpackdeltas(variable.vertical)
- unpackdeltas(variable.metrics)
- end
- data.tables=nil
- end
- end
-end
-local mt={
- __index=function(t,k)
- if k=="height" then
- local ht=t.boundingbox[4]
- return ht<0 and 0 or ht
- elseif k=="depth" then
- local dp=-t.boundingbox[2]
- return dp<0 and 0 or dp
- elseif k=="width" then
- return 0
- elseif k=="name" then
- return forcenotdef and ".notdef"
- end
- end
+local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset
+local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find
+local sequenced=table.sequenced
+local is_boolean=string.is_boolean
+local setmetatableindex=table.setmetatableindex
+local setmetatablenewindex=table.setmetatablenewindex
+local allocate=utilities.storage.allocate
+local fonts=fonts
+local otf=fonts.handlers.otf
+local otffeatures=otf.features
+local tables=otf.tables or {}
+otf.tables=tables
+local statistics=otf.statistics or {}
+otf.statistics=statistics
+local scripts=allocate {
+ ["adlm"]="adlam",
+ ["aghb"]="caucasian albanian",
+ ["ahom"]="ahom",
+ ["arab"]="arabic",
+ ["armi"]="imperial aramaic",
+ ["armn"]="armenian",
+ ["avst"]="avestan",
+ ["bali"]="balinese",
+ ["bamu"]="bamum",
+ ["bass"]="bassa vah",
+ ["batk"]="batak",
+ ["beng"]="bengali",
+ ["bhks"]="bhaiksuki",
+ ["bng2"]="bengali variant 2",
+ ["bopo"]="bopomofo",
+ ["brah"]="brahmi",
+ ["brai"]="braille",
+ ["bugi"]="buginese",
+ ["buhd"]="buhid",
+ ["byzm"]="byzantine music",
+ ["cakm"]="chakma",
+ ["cans"]="canadian syllabics",
+ ["cari"]="carian",
+ ["cham"]="cham",
+ ["cher"]="cherokee",
+ ["copt"]="coptic",
+ ["cprt"]="cypriot syllabary",
+ ["cyrl"]="cyrillic",
+ ["dev2"]="devanagari variant 2",
+ ["deva"]="devanagari",
+ ["dogr"]="dogra",
+ ["dsrt"]="deseret",
+ ["dupl"]="duployan",
+ ["egyp"]="egyptian heiroglyphs",
+ ["elba"]="elbasan",
+ ["ethi"]="ethiopic",
+ ["geor"]="georgian",
+ ["gjr2"]="gujarati variant 2",
+ ["glag"]="glagolitic",
+ ["gong"]="gunjala gondi",
+ ["gonm"]="masaram gondi",
+ ["goth"]="gothic",
+ ["gran"]="grantha",
+ ["grek"]="greek",
+ ["gujr"]="gujarati",
+ ["gur2"]="gurmukhi variant 2",
+ ["guru"]="gurmukhi",
+ ["hang"]="hangul",
+ ["hani"]="cjk ideographic",
+ ["hano"]="hanunoo",
+ ["hatr"]="hatran",
+ ["hebr"]="hebrew",
+ ["hluw"]="anatolian hieroglyphs",
+ ["hmng"]="pahawh hmong",
+ ["hung"]="old hungarian",
+ ["ital"]="old italic",
+ ["jamo"]="hangul jamo",
+ ["java"]="javanese",
+ ["kali"]="kayah li",
+ ["kana"]="hiragana and katakana",
+ ["khar"]="kharosthi",
+ ["khmr"]="khmer",
+ ["khoj"]="khojki",
+ ["knd2"]="kannada variant 2",
+ ["knda"]="kannada",
+ ["kthi"]="kaithi",
+ ["lana"]="tai tham",
+ ["lao" ]="lao",
+ ["latn"]="latin",
+ ["lepc"]="lepcha",
+ ["limb"]="limbu",
+ ["lina"]="linear a",
+ ["linb"]="linear b",
+ ["lisu"]="lisu",
+ ["lyci"]="lycian",
+ ["lydi"]="lydian",
+ ["mahj"]="mahajani",
+ ["maka"]="makasar",
+ ["mand"]="mandaic and mandaean",
+ ["mani"]="manichaean",
+ ["marc"]="marchen",
+ ["math"]="mathematical alphanumeric symbols",
+ ["medf"]="medefaidrin",
+ ["mend"]="mende kikakui",
+ ["merc"]="meroitic cursive",
+ ["mero"]="meroitic hieroglyphs",
+ ["mlm2"]="malayalam variant 2",
+ ["mlym"]="malayalam",
+ ["modi"]="modi",
+ ["mong"]="mongolian",
+ ["mroo"]="mro",
+ ["mtei"]="meitei Mayek",
+ ["mult"]="multani",
+ ["musc"]="musical symbols",
+ ["mym2"]="myanmar variant 2",
+ ["mymr"]="myanmar",
+ ["narb"]="old north arabian",
+ ["nbat"]="nabataean",
+ ["newa"]="newa",
+ ["nko" ]='n"ko',
+ ["nshu"]="nüshu",
+ ["ogam"]="ogham",
+ ["olck"]="ol chiki",
+ ["orkh"]="old turkic and orkhon runic",
+ ["ory2"]="odia variant 2",
+ ["orya"]="oriya",
+ ["osge"]="osage",
+ ["osma"]="osmanya",
+ ["palm"]="palmyrene",
+ ["pauc"]="pau cin hau",
+ ["perm"]="old permic",
+ ["phag"]="phags-pa",
+ ["phli"]="inscriptional pahlavi",
+ ["phlp"]="psalter pahlavi",
+ ["phnx"]="phoenician",
+ ["plrd"]="miao",
+ ["prti"]="inscriptional parthian",
+ ["rjng"]="rejang",
+ ["rohg"]="hanifi rohingya",
+ ["runr"]="runic",
+ ["samr"]="samaritan",
+ ["sarb"]="old south arabian",
+ ["saur"]="saurashtra",
+ ["sgnw"]="sign writing",
+ ["shaw"]="shavian",
+ ["shrd"]="sharada",
+ ["sidd"]="siddham",
+ ["sind"]="khudawadi",
+ ["sinh"]="sinhala",
+ ["sogd"]="sogdian",
+ ["sogo"]="old sogdian",
+ ["sora"]="sora sompeng",
+ ["soyo"]="soyombo",
+ ["sund"]="sundanese",
+ ["sylo"]="syloti nagri",
+ ["syrc"]="syriac",
+ ["tagb"]="tagbanwa",
+ ["takr"]="takri",
+ ["tale"]="tai le",
+ ["talu"]="tai lu",
+ ["taml"]="tamil",
+ ["tang"]="tangut",
+ ["tavt"]="tai viet",
+ ["tel2"]="telugu variant 2",
+ ["telu"]="telugu",
+ ["tfng"]="tifinagh",
+ ["tglg"]="tagalog",
+ ["thaa"]="thaana",
+ ["thai"]="thai",
+ ["tibt"]="tibetan",
+ ["tirh"]="tirhuta",
+ ["tml2"]="tamil variant 2",
+ ["ugar"]="ugaritic cuneiform",
+ ["vai" ]="vai",
+ ["wara"]="warang citi",
+ ["xpeo"]="old persian cuneiform",
+ ["xsux"]="sumero-akkadian cuneiform",
+ ["yi" ]="yi",
+ ["zanb"]="zanabazar square",
}
-local function sameformat(sequence,steps,first,nofsteps,kind)
- return true
-end
-local function mergesteps_1(lookup,strict)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if strict then
- local f=first.format
- for i=2,nofsteps do
- if steps[i].format~=f then
- if trace_optimizations then
- report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
- end
- return 0
- end
- end
- end
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
- for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- if not target[k] then
- target[k]=v
- end
- end
- end
+local languages=allocate {
+ ["aba" ]="abaza",
+ ["abk" ]="abkhazian",
+ ["ach" ]="acholi",
+ ["acr" ]="achi",
+ ["ady" ]="adyghe",
+ ["afk" ]="afrikaans",
+ ["afr" ]="afar",
+ ["agw" ]="agaw",
+ ["aio" ]="aiton",
+ ["aka" ]="akan",
+ ["als" ]="alsatian",
+ ["alt" ]="altai",
+ ["amh" ]="amharic",
+ ["ang" ]="anglo-saxon",
+ ["apph"]="phonetic transcription—americanist conventions",
+ ["ara" ]="arabic",
+ ["arg" ]="aragonese",
+ ["ari" ]="aari",
+ ["ark" ]="rakhine",
+ ["asm" ]="assamese",
+ ["ast" ]="asturian",
+ ["ath" ]="athapaskan",
+ ["avr" ]="avar",
+ ["awa" ]="awadhi",
+ ["aym" ]="aymara",
+ ["azb" ]="torki",
+ ["aze" ]="azerbaijani",
+ ["bad" ]="badaga",
+ ["bad0"]="banda",
+ ["bag" ]="baghelkhandi",
+ ["bal" ]="balkar",
+ ["ban" ]="balinese",
+ ["bar" ]="bavarian",
+ ["bau" ]="baulé",
+ ["bbc" ]="batak toba",
+ ["bbr" ]="berber",
+ ["bch" ]="bench",
+ ["bcr" ]="bible cree",
+ ["bdy" ]="bandjalang",
+ ["bel" ]="belarussian",
+ ["bem" ]="bemba",
+ ["ben" ]="bengali",
+ ["bgc" ]="haryanvi",
+ ["bgq" ]="bagri",
+ ["bgr" ]="bulgarian",
+ ["bhi" ]="bhili",
+ ["bho" ]="bhojpuri",
+ ["bik" ]="bikol",
+ ["bil" ]="bilen",
+ ["bis" ]="bislama",
+ ["bjj" ]="kanauji",
+ ["bkf" ]="blackfoot",
+ ["bli" ]="baluchi",
+ ["blk" ]="pa'o karen",
+ ["bln" ]="balante",
+ ["blt" ]="balti",
+ ["bmb" ]="bambara (bamanankan)",
+ ["bml" ]="bamileke",
+ ["bos" ]="bosnian",
+ ["bpy" ]="bishnupriya manipuri",
+ ["bre" ]="breton",
+ ["brh" ]="brahui",
+ ["bri" ]="braj bhasha",
+ ["brm" ]="burmese",
+ ["brx" ]="bodo",
+ ["bsh" ]="bashkir",
+ ["bsk" ]="burushaski",
+ ["bti" ]="beti",
+ ["bts" ]="batak simalungun",
+ ["bug" ]="bugis",
+ ["byv" ]="medumba",
+ ["cak" ]="kaqchikel",
+ ["cat" ]="catalan",
+ ["cbk" ]="zamboanga chavacano",
+ ["cchn"]="chinantec",
+ ["ceb" ]="cebuano",
+ ["cgg" ]="chiga",
+ ["cha" ]="chamorro",
+ ["che" ]="chechen",
+ ["chg" ]="chaha gurage",
+ ["chh" ]="chattisgarhi",
+ ["chi" ]="chichewa (chewa, nyanja)",
+ ["chk" ]="chukchi",
+ ["chk0"]="chuukese",
+ ["cho" ]="choctaw",
+ ["chp" ]="chipewyan",
+ ["chr" ]="cherokee",
+ ["chu" ]="chuvash",
+ ["chy" ]="cheyenne",
+ ["cja" ]="western cham",
+ ["cjm" ]="eastern cham",
+ ["cmr" ]="comorian",
+ ["cop" ]="coptic",
+ ["cor" ]="cornish",
+ ["cos" ]="corsican",
+ ["cpp" ]="creoles",
+ ["cre" ]="cree",
+ ["crr" ]="carrier",
+ ["crt" ]="crimean tatar",
+ ["csb" ]="kashubian",
+ ["csl" ]="church slavonic",
+ ["csy" ]="czech",
+ ["ctg" ]="chittagonian",
+ ["cuk" ]="san blas kuna",
+ ["dan" ]="danish",
+ ["dar" ]="dargwa",
+ ["dax" ]="dayi",
+ ["dcr" ]="woods cree",
+ ["deu" ]="german",
+ ["dgo" ]="dogri",
+ ["dgr" ]="dogri",
+ ["dhg" ]="dhangu",
+ ["dhv" ]="divehi (dhivehi, maldivian)",
+ ["diq" ]="dimli",
+ ["div" ]="divehi (dhivehi, maldivian)",
+ ["djr" ]="zarma",
+ ["djr0"]="djambarrpuyngu",
+ ["dng" ]="dangme",
+ ["dnj" ]="dan",
+ ["dnk" ]="dinka",
+ ["dri" ]="dari",
+ ["duj" ]="dhuwal",
+ ["dun" ]="dungan",
+ ["dzn" ]="dzongkha",
+ ["ebi" ]="ebira",
+ ["ecr" ]="eastern cree",
+ ["edo" ]="edo",
+ ["efi" ]="efik",
+ ["ell" ]="greek",
+ ["emk" ]="eastern maninkakan",
+ ["eng" ]="english",
+ ["erz" ]="erzya",
+ ["esp" ]="spanish",
+ ["esu" ]="central yupik",
+ ["eti" ]="estonian",
+ ["euq" ]="basque",
+ ["evk" ]="evenki",
+ ["evn" ]="even",
+ ["ewe" ]="ewe",
+ ["fan" ]="french antillean",
+ ["fan0"]=" fang",
+ ["far" ]="persian",
+ ["fat" ]="fanti",
+ ["fin" ]="finnish",
+ ["fji" ]="fijian",
+ ["fle" ]="dutch (flemish)",
+ ["fmp" ]="fe’fe’",
+ ["fne" ]="forest nenets",
+ ["fon" ]="fon",
+ ["fos" ]="faroese",
+ ["fra" ]="french",
+ ["frc" ]="cajun french",
+ ["fri" ]="frisian",
+ ["frl" ]="friulian",
+ ["frp" ]="arpitan",
+ ["fta" ]="futa",
+ ["ful" ]="fulah",
+ ["fuv" ]="nigerian fulfulde",
+ ["gad" ]="ga",
+ ["gae" ]="scottish gaelic (gaelic)",
+ ["gag" ]="gagauz",
+ ["gal" ]="galician",
+ ["gar" ]="garshuni",
+ ["gaw" ]="garhwali",
+ ["gez" ]="ge'ez",
+ ["gih" ]="githabul",
+ ["gil" ]="gilyak",
+ ["gil0"]="kiribati (gilbertese)",
+ ["gkp" ]="kpelle (guinea)",
+ ["glk" ]="gilaki",
+ ["gmz" ]="gumuz",
+ ["gnn" ]="gumatj",
+ ["gog" ]="gogo",
+ ["gon" ]="gondi",
+ ["grn" ]="greenlandic",
+ ["gro" ]="garo",
+ ["gua" ]="guarani",
+ ["guc" ]="wayuu",
+ ["guf" ]="gupapuyngu",
+ ["guj" ]="gujarati",
+ ["guz" ]="gusii",
+ ["hai" ]="haitian (haitian creole)",
+ ["hal" ]="halam",
+ ["har" ]="harauti",
+ ["hau" ]="hausa",
+ ["haw" ]="hawaiian",
+ ["hay" ]="haya",
+ ["haz" ]="hazaragi",
+ ["hbn" ]="hammer-banna",
+ ["her" ]="herero",
+ ["hil" ]="hiligaynon",
+ ["hin" ]="hindi",
+ ["hma" ]="high mari",
+ ["hmn" ]="hmong",
+ ["hmo" ]="hiri motu",
+ ["hnd" ]="hindko",
+ ["ho" ]="ho",
+ ["hri" ]="harari",
+ ["hrv" ]="croatian",
+ ["hun" ]="hungarian",
+ ["hye" ]="armenian",
+ ["hye0"]="armenian east",
+ ["iba" ]="iban",
+ ["ibb" ]="ibibio",
+ ["ibo" ]="igbo",
+ ["ido" ]="ido",
+ ["ijo" ]="ijo languages",
+ ["ile" ]="interlingue",
+ ["ilo" ]="ilokano",
+ ["ina" ]="interlingua",
+ ["ind" ]="indonesian",
+ ["ing" ]="ingush",
+ ["inu" ]="inuktitut",
+ ["ipk" ]="inupiat",
+ ["ipph"]="phonetic transcription—ipa conventions",
+ ["iri" ]="irish",
+ ["irt" ]="irish traditional",
+ ["isl" ]="icelandic",
+ ["ism" ]="inari sami",
+ ["ita" ]="italian",
+ ["iwr" ]="hebrew",
+ ["jam" ]="jamaican creole",
+ ["jan" ]="japanese",
+ ["jav" ]="javanese",
+ ["jbo" ]="lojban",
+ ["jct" ]="krymchak",
+ ["jii" ]="yiddish",
+ ["jud" ]="ladino",
+ ["jul" ]="jula",
+ ["kab" ]="kabardian",
+ ["kab0"]="kabyle",
+ ["kac" ]="kachchi",
+ ["kal" ]="kalenjin",
+ ["kan" ]="kannada",
+ ["kar" ]="karachay",
+ ["kat" ]="georgian",
+ ["kaz" ]="kazakh",
+ ["kde" ]="makonde",
+ ["kea" ]="kabuverdianu (crioulo)",
+ ["keb" ]="kebena",
+ ["kek" ]="kekchi",
+ ["kge" ]="khutsuri georgian",
+ ["kha" ]="khakass",
+ ["khk" ]="khanty-kazim",
+ ["khm" ]="khmer",
+ ["khs" ]="khanty-shurishkar",
+ ["kht" ]="khamti shan",
+ ["khv" ]="khanty-vakhi",
+ ["khw" ]="khowar",
+ ["kik" ]="kikuyu (gikuyu)",
+ ["kir" ]="kirghiz (kyrgyz)",
+ ["kis" ]="kisii",
+ ["kiu" ]="kirmanjki",
+ ["kjd" ]="southern kiwai",
+ ["kjp" ]="eastern pwo karen",
+ ["kjz" ]="bumthangkha",
+ ["kkn" ]="kokni",
+ ["klm" ]="kalmyk",
+ ["kmb" ]="kamba",
+ ["kmn" ]="kumaoni",
+ ["kmo" ]="komo",
+ ["kms" ]="komso",
+ ["kmz" ]="khorasani turkic",
+ ["knr" ]="kanuri",
+ ["kod" ]="kodagu",
+ ["koh" ]="korean old hangul",
+ ["kok" ]="konkani",
+ ["kom" ]="komi",
+ ["kon" ]="kikongo",
+ ["kon0"]="kongo",
+ ["kop" ]="komi-permyak",
+ ["kor" ]="korean",
+ ["kos" ]="kosraean",
+ ["koz" ]="komi-zyrian",
+ ["kpl" ]="kpelle",
+ ["kri" ]="krio",
+ ["krk" ]="karakalpak",
+ ["krl" ]="karelian",
+ ["krm" ]="karaim",
+ ["krn" ]="karen",
+ ["krt" ]="koorete",
+ ["ksh" ]="kashmiri",
+ ["ksh0"]="ripuarian",
+ ["ksi" ]="khasi",
+ ["ksm" ]="kildin sami",
+ ["ksw" ]="s’gaw karen",
+ ["kua" ]="kuanyama",
+ ["kui" ]="kui",
+ ["kul" ]="kulvi",
+ ["kum" ]="kumyk",
+ ["kur" ]="kurdish",
+ ["kuu" ]="kurukh",
+ ["kuy" ]="kuy",
+ ["kyk" ]="koryak",
+ ["kyu" ]="western kayah",
+ ["lad" ]="ladin",
+ ["lah" ]="lahuli",
+ ["lak" ]="lak",
+ ["lam" ]="lambani",
+ ["lao" ]="lao",
+ ["lat" ]="latin",
+ ["laz" ]="laz",
+ ["lcr" ]="l-cree",
+ ["ldk" ]="ladakhi",
+ ["lez" ]="lezgi",
+ ["lij" ]="ligurian",
+ ["lim" ]="limburgish",
+ ["lin" ]="lingala",
+ ["lis" ]="lisu",
+ ["ljp" ]="lampung",
+ ["lki" ]="laki",
+ ["lma" ]="low mari",
+ ["lmb" ]="limbu",
+ ["lmo" ]="lombard",
+ ["lmw" ]="lomwe",
+ ["lom" ]="loma",
+ ["lrc" ]="luri",
+ ["lsb" ]="lower sorbian",
+ ["lsm" ]="lule sami",
+ ["lth" ]="lithuanian",
+ ["ltz" ]="luxembourgish",
+ ["lua" ]="luba-lulua",
+ ["lub" ]="luba-katanga",
+ ["lug" ]="ganda",
+ ["luh" ]="luyia",
+ ["luo" ]="luo",
+ ["lvi" ]="latvian",
+ ["mad" ]="madura",
+ ["mag" ]="magahi",
+ ["mah" ]="marshallese",
+ ["maj" ]="majang",
+ ["mak" ]="makhuwa",
+ ["mal" ]="malayalam reformed",
+ ["mam" ]="mam",
+ ["man" ]="mansi",
+ ["map" ]="mapudungun",
+ ["mar" ]="marathi",
+ ["maw" ]="marwari",
+ ["mbn" ]="mbundu",
+ ["mbo" ]="mbo",
+ ["mch" ]="manchu",
+ ["mcr" ]="moose cree",
+ ["mde" ]="mende",
+ ["mdr" ]="mandar",
+ ["men" ]="me'en",
+ ["mer" ]="meru",
+ ["mfa" ]="pattani malay",
+ ["mfe" ]="morisyen",
+ ["min" ]="minangkabau",
+ ["miz" ]="mizo",
+ ["mkd" ]="macedonian",
+ ["mkr" ]="makasar",
+ ["mkw" ]="kituba",
+ ["mle" ]="male",
+ ["mlg" ]="malagasy",
+ ["mln" ]="malinke",
+ ["mlr" ]="malayalam reformed",
+ ["mly" ]="malay",
+ ["mnd" ]="mandinka",
+ ["mng" ]="mongolian",
+ ["mni" ]="manipuri",
+ ["mnk" ]="maninka",
+ ["mnx" ]="manx",
+ ["moh" ]="mohawk",
+ ["mok" ]="moksha",
+ ["mol" ]="moldavian",
+ ["mon" ]="mon",
+ ["mor" ]="moroccan",
+ ["mos" ]="mossi",
+ ["mri" ]="maori",
+ ["mth" ]="maithili",
+ ["mts" ]="maltese",
+ ["mun" ]="mundari",
+ ["mus" ]="muscogee",
+ ["mwl" ]="mirandese",
+ ["mww" ]="hmong daw",
+ ["myn" ]="mayan",
+ ["mzn" ]="mazanderani",
+ ["nag" ]="naga-assamese",
+ ["nah" ]="nahuatl",
+ ["nan" ]="nanai",
+ ["nap" ]="neapolitan",
+ ["nas" ]="naskapi",
+ ["nau" ]="nauruan",
+ ["nav" ]="navajo",
+ ["ncr" ]="n-cree",
+ ["ndb" ]="ndebele",
+ ["ndc" ]="ndau",
+ ["ndg" ]="ndonga",
+ ["nds" ]="low saxon",
+ ["nep" ]="nepali",
+ ["new" ]="newari",
+ ["nga" ]="ngbaka",
+ ["ngr" ]="nagari",
+ ["nhc" ]="norway house cree",
+ ["nis" ]="nisi",
+ ["niu" ]="niuean",
+ ["nkl" ]="nyankole",
+ ["nko" ]="n'ko",
+ ["nld" ]="dutch",
+ ["noe" ]="nimadi",
+ ["nog" ]="nogai",
+ ["nor" ]="norwegian",
+ ["nov" ]="novial",
+ ["nsm" ]="northern sami",
+ ["nso" ]="sotho, northern",
+ ["nta" ]="northern tai",
+ ["nto" ]="esperanto",
+ ["nym" ]="nyamwezi",
+ ["nyn" ]="norwegian nynorsk",
+ ["nza" ]="mbembe tigon",
+ ["oci" ]="occitan",
+ ["ocr" ]="oji-cree",
+ ["ojb" ]="ojibway",
+ ["ori" ]="odia",
+ ["oro" ]="oromo",
+ ["oss" ]="ossetian",
+ ["paa" ]="palestinian aramaic",
+ ["pag" ]="pangasinan",
+ ["pal" ]="pali",
+ ["pam" ]="pampangan",
+ ["pan" ]="punjabi",
+ ["pap" ]="palpa",
+ ["pap0"]="papiamentu",
+ ["pas" ]="pashto",
+ ["pau" ]="palauan",
+ ["pcc" ]="bouyei",
+ ["pcd" ]="picard",
+ ["pdc" ]="pennsylvania german",
+ ["pgr" ]="polytonic greek",
+ ["phk" ]="phake",
+ ["pih" ]="norfolk",
+ ["pil" ]="filipino",
+ ["plg" ]="palaung",
+ ["plk" ]="polish",
+ ["pms" ]="piemontese",
+ ["pnb" ]="western panjabi",
+ ["poh" ]="pocomchi",
+ ["pon" ]="pohnpeian",
+ ["pro" ]="provencal",
+ ["ptg" ]="portuguese",
+ ["pwo" ]="western pwo karen",
+ ["qin" ]="chin",
+ ["quc" ]="k’iche’",
+ ["quh" ]="quechua (bolivia)",
+ ["quz" ]="quechua",
+ ["qvi" ]="quechua (ecuador)",
+ ["qwh" ]="quechua (peru)",
+ ["raj" ]="rajasthani",
+ ["rar" ]="rarotongan",
+ ["rbu" ]="russian buriat",
+ ["rcr" ]="r-cree",
+ ["rej" ]="rejang",
+ ["ria" ]="riang",
+ ["rif" ]="tarifit",
+ ["rit" ]="ritarungo",
+ ["rkw" ]="arakwal",
+ ["rms" ]="romansh",
+ ["rmy" ]="vlax romani",
+ ["rom" ]="romanian",
+ ["roy" ]="romany",
+ ["rsy" ]="rusyn",
+ ["rtm" ]="rotuman",
+ ["rua" ]="kinyarwanda",
+ ["run" ]="rundi",
+ ["rup" ]="aromanian",
+ ["rus" ]="russian",
+ ["sad" ]="sadri",
+ ["san" ]="sanskrit",
+ ["sas" ]="sasak",
+ ["sat" ]="santali",
+ ["say" ]="sayisi",
+ ["scn" ]="sicilian",
+ ["sco" ]="scots",
+ ["scs" ]="north slavey",
+ ["sek" ]="sekota",
+ ["sel" ]="selkup",
+ ["sga" ]="old irish",
+ ["sgo" ]="sango",
+ ["sgs" ]="samogitian",
+ ["shi" ]="tachelhit",
+ ["shn" ]="shan",
+ ["sib" ]="sibe",
+ ["sid" ]="sidamo",
+ ["sig" ]="silte gurage",
+ ["sks" ]="skolt sami",
+ ["sky" ]="slovak",
+ ["sla" ]="slavey",
+ ["slv" ]="slovenian",
+ ["sml" ]="somali",
+ ["smo" ]="samoan",
+ ["sna" ]="sena",
+ ["sna0"]="shona",
+ ["snd" ]="sindhi",
+ ["snh" ]="sinhala (sinhalese)",
+ ["snk" ]="soninke",
+ ["sog" ]="sodo gurage",
+ ["sop" ]="songe",
+ ["sot" ]="sotho, southern",
+ ["sqi" ]="albanian",
+ ["srb" ]="serbian",
+ ["srd" ]="sardinian",
+ ["srk" ]="saraiki",
+ ["srr" ]="serer",
+ ["ssl" ]="south slavey",
+ ["ssm" ]="southern sami",
+ ["stq" ]="saterland frisian",
+ ["suk" ]="sukuma",
+ ["sun" ]="sundanese",
+ ["sur" ]="suri",
+ ["sva" ]="svan",
+ ["sve" ]="swedish",
+ ["swa" ]="swadaya aramaic",
+ ["swk" ]="swahili",
+ ["swz" ]="swati",
+ ["sxt" ]="sutu",
+ ["sxu" ]="upper saxon",
+ ["syl" ]="sylheti",
+ ["syr" ]="syriac",
+ ["syre"]="estrangela syriac",
+ ["syrj"]="western syriac",
+ ["syrn"]="eastern syriac",
+ ["szl" ]="silesian",
+ ["tab" ]="tabasaran",
+ ["taj" ]="tajiki",
+ ["tam" ]="tamil",
+ ["tat" ]="tatar",
+ ["tcr" ]="th-cree",
+ ["tdd" ]="dehong dai",
+ ["tel" ]="telugu",
+ ["tet" ]="tetum",
+ ["tgl" ]="tagalog",
+ ["tgn" ]="tongan",
+ ["tgr" ]="tigre",
+ ["tgy" ]="tigrinya",
+ ["tha" ]="thai",
+ ["tht" ]="tahitian",
+ ["tib" ]="tibetan",
+ ["tiv" ]="tiv",
+ ["tkm" ]="turkmen",
+ ["tmh" ]="tamashek",
+ ["tmn" ]="temne",
+ ["tna" ]="tswana",
+ ["tne" ]="tundra nenets",
+ ["tng" ]="tonga",
+ ["tod" ]="todo",
+ ["tod0"]="toma",
+ ["tpi" ]="tok pisin",
+ ["trk" ]="turkish",
+ ["tsg" ]="tsonga",
+ ["tsj" ]="tshangla",
+ ["tua" ]="turoyo aramaic",
+ ["tul" ]="tulu",
+ ["tum" ]="tulu",
+ ["tuv" ]="tuvin",
+ ["tvl" ]="tuvalu",
+ ["twi" ]="twi",
+ ["tyz" ]="tày",
+ ["tzm" ]="tamazight",
+ ["tzo" ]="tzotzil",
+ ["udm" ]="udmurt",
+ ["ukr" ]="ukrainian",
+ ["umb" ]="umbundu",
+ ["urd" ]="urdu",
+ ["usb" ]="upper sorbian",
+ ["uyg" ]="uyghur",
+ ["uzb" ]="uzbek",
+ ["vec" ]="venetian",
+ ["ven" ]="venda",
+ ["vit" ]="vietnamese",
+ ["vol" ]="volapük",
+ ["vro" ]="võro",
+ ["wa" ]="wa",
+ ["wag" ]="wagdi",
+ ["war" ]="waray-waray",
+ ["wcr" ]="west-cree",
+ ["wel" ]="welsh",
+ ["wlf" ]="wolof",
+ ["wln" ]="walloon",
+ ["wtm" ]="mewati",
+ ["xbd" ]="lü",
+ ["xhs" ]="xhosa",
+ ["xjb" ]="minjangbal",
+ ["xkf" ]="khengkha",
+ ["xog" ]="soga",
+ ["xpe" ]="kpelle (liberia)",
+ ["yak" ]="sakha",
+ ["yao" ]="yao",
+ ["yap" ]="yapese",
+ ["yba" ]="yoruba",
+ ["ycr" ]="y-cree",
+ ["yic" ]="yi classic",
+ ["yim" ]="yi modern",
+ ["zea" ]="zealandic",
+ ["zgh" ]="standard morrocan tamazigh",
+ ["zha" ]="zhuang",
+ ["zhh" ]="chinese, hong kong sar",
+ ["zhp" ]="chinese phonetic",
+ ["zhs" ]="chinese simplified",
+ ["zht" ]="chinese traditional",
+ ["znd" ]="zande",
+ ["zul" ]="zulu",
+ ["zza" ]="zazaki",
+}
+local features=allocate {
+ ["aalt"]="access all alternates",
+ ["abvf"]="above-base forms",
+ ["abvm"]="above-base mark positioning",
+ ["abvs"]="above-base substitutions",
+ ["afrc"]="alternative fractions",
+ ["akhn"]="akhands",
+ ["blwf"]="below-base forms",
+ ["blwm"]="below-base mark positioning",
+ ["blws"]="below-base substitutions",
+ ["c2pc"]="petite capitals from capitals",
+ ["c2sc"]="small capitals from capitals",
+ ["calt"]="contextual alternates",
+ ["case"]="case-sensitive forms",
+ ["ccmp"]="glyph composition/decomposition",
+ ["cfar"]="conjunct form after ro",
+ ["cjct"]="conjunct forms",
+ ["clig"]="contextual ligatures",
+ ["cpct"]="centered cjk punctuation",
+ ["cpsp"]="capital spacing",
+ ["cswh"]="contextual swash",
+ ["curs"]="cursive positioning",
+ ["dflt"]="default processing",
+ ["dist"]="distances",
+ ["dlig"]="discretionary ligatures",
+ ["dnom"]="denominators",
+ ["dtls"]="dotless forms",
+ ["expt"]="expert forms",
+ ["falt"]="final glyph alternates",
+ ["fin2"]="terminal forms #2",
+ ["fin3"]="terminal forms #3",
+ ["fina"]="terminal forms",
+ ["flac"]="flattened accents over capitals",
+ ["frac"]="fractions",
+ ["fwid"]="full width",
+ ["half"]="half forms",
+ ["haln"]="halant forms",
+ ["halt"]="alternate half width",
+ ["hist"]="historical forms",
+ ["hkna"]="horizontal kana alternates",
+ ["hlig"]="historical ligatures",
+ ["hngl"]="hangul",
+ ["hojo"]="hojo kanji forms",
+ ["hwid"]="half width",
+ ["init"]="initial forms",
+ ["isol"]="isolated forms",
+ ["ital"]="italics",
+ ["jalt"]="justification alternatives",
+ ["jp04"]="jis2004 forms",
+ ["jp78"]="jis78 forms",
+ ["jp83"]="jis83 forms",
+ ["jp90"]="jis90 forms",
+ ["kern"]="kerning",
+ ["lfbd"]="left bounds",
+ ["liga"]="standard ligatures",
+ ["ljmo"]="leading jamo forms",
+ ["lnum"]="lining figures",
+ ["locl"]="localized forms",
+ ["ltra"]="left-to-right alternates",
+ ["ltrm"]="left-to-right mirrored forms",
+ ["mark"]="mark positioning",
+ ["med2"]="medial forms #2",
+ ["medi"]="medial forms",
+ ["mgrk"]="mathematical greek",
+ ["mkmk"]="mark to mark positioning",
+ ["mset"]="mark positioning via substitution",
+ ["nalt"]="alternate annotation forms",
+ ["nlck"]="nlc kanji forms",
+ ["nukt"]="nukta forms",
+ ["numr"]="numerators",
+ ["onum"]="old style figures",
+ ["opbd"]="optical bounds",
+ ["ordn"]="ordinals",
+ ["ornm"]="ornaments",
+ ["palt"]="proportional alternate width",
+ ["pcap"]="petite capitals",
+ ["pkna"]="proportional kana",
+ ["pnum"]="proportional figures",
+ ["pref"]="pre-base forms",
+ ["pres"]="pre-base substitutions",
+ ["pstf"]="post-base forms",
+ ["psts"]="post-base substitutions",
+ ["pwid"]="proportional widths",
+ ["qwid"]="quarter widths",
+ ["rand"]="randomize",
+ ["rclt"]="required contextual alternates",
+ ["rkrf"]="rakar forms",
+ ["rlig"]="required ligatures",
+ ["rphf"]="reph form",
+ ["rtbd"]="right bounds",
+ ["rtla"]="right-to-left alternates",
+ ["rtlm"]="right to left mirrored forms",
+ ["rvrn"]="required variation alternates",
+ ["ruby"]="ruby notation forms",
+ ["salt"]="stylistic alternates",
+ ["sinf"]="scientific inferiors",
+ ["size"]="optical size",
+ ["smcp"]="small capitals",
+ ["smpl"]="simplified forms",
+ ["ssty"]="script style",
+ ["stch"]="stretching glyph decomposition",
+ ["subs"]="subscript",
+ ["sups"]="superscript",
+ ["swsh"]="swash",
+ ["titl"]="titling",
+ ["tjmo"]="trailing jamo forms",
+ ["tnam"]="traditional name forms",
+ ["tnum"]="tabular figures",
+ ["trad"]="traditional forms",
+ ["twid"]="third widths",
+ ["unic"]="unicase",
+ ["valt"]="alternate vertical metrics",
+ ["vatu"]="vattu variants",
+ ["vert"]="vertical writing",
+ ["vhal"]="alternate vertical half metrics",
+ ["vjmo"]="vowel jamo forms",
+ ["vkna"]="vertical kana alternates",
+ ["vkrn"]="vertical kerning",
+ ["vpal"]="proportional alternate vertical metrics",
+ ["vrtr"]="vertical alternates for rotation",
+ ["vrt2"]="vertical rotation",
+ ["zero"]="slashed zero",
+ ["trep"]="traditional tex replacements",
+ ["tlig"]="traditional tex ligatures",
+ ["ss.."]="stylistic set ..",
+ ["cv.."]="character variant ..",
+ ["js.."]="justification ..",
+ ["dv.."]="devanagari ..",
+ ["ml.."]="malayalam ..",
+}
+local baselines=allocate {
+ ["hang"]="hanging baseline",
+ ["icfb"]="ideographic character face bottom edge baseline",
+ ["icft"]="ideographic character face tope edige baseline",
+ ["ideo"]="ideographic em-box bottom edge baseline",
+ ["idtp"]="ideographic em-box top edge baseline",
+ ["math"]="mathematical centered baseline",
+ ["romn"]="roman baseline"
+}
+tables.scripts=scripts
+tables.languages=languages
+tables.features=features
+tables.baselines=baselines
+local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
+local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
+local report_checks=logs.reporter("fonts","checks")
+if otffeatures.features then
+ for k,v in next,otffeatures.features do
+ features[k]=v
end
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
+ otffeatures.features=features
end
-local function mergesteps_2(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if strict then
- local f=first.format
- for i=2,nofsteps do
- if steps[i].format~=f then
- if trace_optimizations then
- report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
- end
- return 0
- end
- end
- end
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
- for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=target[k]
- if tk then
- for kk,vv in next,v do
- if tk[kk]==nil then
- tk[kk]=vv
- end
- end
- else
- target[k]=v
- end
- end
- end
+local function swapped(h)
+ local r={}
+ for k,v in next,h do
+ r[gsub(v,"[^a-z0-9]","")]=k
end
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
+ return r
end
-local function mergesteps_3(lookup,strict)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local coverage={}
- for i=1,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=coverage[k]
- if tk then
- if trace_optimizations then
- report_optimizations("quitting merge due to multiple checks")
- end
- return nofsteps
- else
- coverage[k]=v
- end
- end
- end
- end
- local first=steps[1]
- local baseclasses={}
- for i=1,nofsteps do
- local offset=i*10
- local step=steps[i]
- for k,v in sortedhash(step.baseclasses) do
- baseclasses[offset+k]=v
- end
- for k,v in next,step.coverage do
- v[1]=offset+v[1]
+local verbosescripts=allocate(swapped(scripts ))
+local verboselanguages=allocate(swapped(languages))
+local verbosefeatures=allocate(swapped(features ))
+local verbosebaselines=allocate(swapped(baselines))
+local function resolve(t,k)
+ if k then
+ k=gsub(lower(k),"[^a-z0-9]","")
+ local v=rawget(t,k)
+ if v then
+ return v
end
end
- first.baseclasses=baseclasses
- first.coverage=coverage
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
end
-local function nested(old,new)
- for k,v in next,old do
- if k=="ligature" then
- if not new.ligature then
- new.ligature=v
- end
- else
- local n=new[k]
- if n then
- nested(v,n)
- else
- new[k]=v
- end
+setmetatableindex(verbosescripts,resolve)
+setmetatableindex(verboselanguages,resolve)
+setmetatableindex(verbosefeatures,resolve)
+setmetatableindex(verbosebaselines,resolve)
+setmetatableindex(scripts,function(t,k)
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
end
- end
-end
-local function mergesteps_4(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
- for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=target[k]
- if tk then
- nested(v,tk)
- else
- target[k]=v
- end
- end
+ local v=rawget(t,k)
+ if v then
+ return v
end
- end
- lookup.nofsteps=1
- lookup.steps={ first }
- return nofsteps-1
-end
-local function mergesteps_5(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
- local hash=nil
- for k,v in next,target do
- hash=v[1]
- break
- end
- for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=target[k]
- if tk then
- if not tk[2] then
- tk[2]=v[2]
- end
- if not tk[3] then
- tk[3]=v[3]
- end
- else
- target[k]=v
- v[1]=hash
- end
- end
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptscripts then
+ report_checks("registering extra script %a",k)
+ rawset(t,k,k)
+ return k
end
end
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
-end
-local function checkkerns(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local kerned=0
- for i=1,nofsteps do
- local step=steps[i]
- if step.format=="pair" then
- local coverage=step.coverage
- local kerns=true
- for g1,d1 in next,coverage do
- if d1==true then
- elseif not d1 then
- elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then
- kerns=false
- break
- end
- end
- if kerns then
- if trace_optimizations then
- report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
- end
- local c={}
- for g1,d1 in next,coverage do
- if d1 and d1~=true then
- c[g1]=d1[3]
- end
- end
- step.coverage=c
- step.format="move"
- kerned=kerned+1
- end
+ return "dflt"
+end)
+setmetatableindex(languages,function(t,k)
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
end
- end
- return kerned
-end
-local function checkpairs(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local kerned=0
- local function onlykerns(step)
- local coverage=step.coverage
- for g1,d1 in next,coverage do
- for g2,d2 in next,d1 do
- if d2[2] then
- return false
- else
- local v=d2[1]
- if v==true then
- elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then
- return false
- end
- end
- end
+ local v=rawget(t,k)
+ if v then
+ return v
end
- return coverage
- end
- for i=1,nofsteps do
- local step=steps[i]
- if step.format=="pair" then
- local coverage=onlykerns(step)
- if coverage then
- if trace_optimizations then
- report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
- end
- for g1,d1 in next,coverage do
- local d={}
- for g2,d2 in next,d1 do
- local v=d2[1]
- if v==true then
- elseif v then
- d[g2]=v[3]
- end
- end
- coverage[g1]=d
- end
- step.format="move"
- kerned=kerned+1
- end
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptlanguages then
+ report_checks("registering extra language %a",k)
+ rawset(t,k,k)
+ return k
end
end
- return kerned
+ return "dflt"
+end)
+if setmetatablenewindex then
+ setmetatablenewindex(languages,"ignore")
+ setmetatablenewindex(scripts,"ignore")
+ setmetatablenewindex(baselines,"ignore")
end
-local compact_pairs=true
-local compact_singles=true
-local merge_pairs=true
-local merge_singles=true
-local merge_substitutions=true
-local merge_alternates=true
-local merge_multiples=true
-local merge_ligatures=true
-local merge_cursives=true
-local merge_marks=true
-directives.register("otf.compact.pairs",function(v) compact_pairs=v end)
-directives.register("otf.compact.singles",function(v) compact_singles=v end)
-directives.register("otf.merge.pairs",function(v) merge_pairs=v end)
-directives.register("otf.merge.singles",function(v) merge_singles=v end)
-directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end)
-directives.register("otf.merge.alternates",function(v) merge_alternates=v end)
-directives.register("otf.merge.multiples",function(v) merge_multiples=v end)
-directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end)
-directives.register("otf.merge.cursives",function(v) merge_cursives=v end)
-directives.register("otf.merge.marks",function(v) merge_marks=v end)
-function readers.compact(data)
- if not data or data.compacted then
- return
- else
- data.compacted=true
- end
- local resources=data.resources
- local merged=0
- local kerned=0
- local allsteps=0
- local function compact(what)
- local lookups=resources[what]
- if lookups then
- for i=1,#lookups do
- local lookup=lookups[i]
- local nofsteps=lookup.nofsteps
- local kind=lookup.type
- allsteps=allsteps+nofsteps
- if nofsteps>1 then
- local merg=merged
- if kind=="gsub_single" then
- if merge_substitutions then
- merged=merged+mergesteps_1(lookup)
- end
- elseif kind=="gsub_alternate" then
- if merge_alternates then
- merged=merged+mergesteps_1(lookup)
- end
- elseif kind=="gsub_multiple" then
- if merge_multiples then
- merged=merged+mergesteps_1(lookup)
- end
- elseif kind=="gsub_ligature" then
- if merge_ligatures then
- merged=merged+mergesteps_4(lookup)
- end
- elseif kind=="gpos_single" then
- if merge_singles then
- merged=merged+mergesteps_1(lookup,true)
- end
- if compact_singles then
- kerned=kerned+checkkerns(lookup)
- end
- elseif kind=="gpos_pair" then
- if merge_pairs then
- merged=merged+mergesteps_2(lookup)
- end
- if compact_pairs then
- kerned=kerned+checkpairs(lookup)
- end
- elseif kind=="gpos_cursive" then
- if merge_cursives then
- merged=merged+mergesteps_5(lookup)
- end
- elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then
- if merge_marks then
- merged=merged+mergesteps_3(lookup)
- end
- end
- if merg~=merged then
- lookup.merged=true
- end
- elseif nofsteps==1 then
- local kern=kerned
- if kind=="gpos_single" then
- if compact_singles then
- kerned=kerned+checkkerns(lookup)
- end
- elseif kind=="gpos_pair" then
- if compact_pairs then
- kerned=kerned+checkpairs(lookup)
- end
- end
- if kern~=kerned then
- end
- end
- end
- elseif trace_optimizations then
- report_optimizations("no lookups in %a",what)
- end
- end
- compact("sequences")
- compact("sublookups")
- if trace_optimizations then
- if merged>0 then
- report_optimizations("%i steps of %i removed due to merging",merged,allsteps)
+local function resolve(t,k)
+ if k then
+ k=lower(k)
+ local v=rawget(t,k)
+ if v then
+ return v
end
- if kerned>0 then
- report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
+ k=gsub(k," ","")
+ local v=rawget(t,k)
+ if v then
+ return v
end
- end
-end
-local function mergesteps(t,k)
- if k=="merged" then
- local merged={}
- for i=1,#t do
- local step=t[i]
- local coverage=step.coverage
- for k in next,coverage do
- local m=merged[k]
- if m then
- m[2]=i
- else
- merged[k]={ i,i }
+ local tag,dd=match(k,"(..)(%d+)")
+ if tag and dd then
+ local v=rawget(t,tag)
+ if v then
+ return v
+ else
+ local v=rawget(t,tag.."..")
+ if v then
+ return (gsub(v,"%.%.",tonumber(dd)))
end
end
end
- t.merged=merged
- return merged
end
+ return k
end
-local function checkmerge(sequence)
- local steps=sequence.steps
- if steps then
- setmetatableindex(steps,mergesteps)
+setmetatableindex(features,resolve)
+local function assign(t,k,v)
+ if k and v then
+ v=lower(v)
+ rawset(t,k,v)
end
end
-local function checkflags(sequence,resources)
- if not sequence.skiphash then
- local flags=sequence.flags
- if flags then
- local skipmark=flags[1]
- local skipligature=flags[2]
- local skipbase=flags[3]
- local markclass=sequence.markclass
- local skipsome=skipmark or skipligature or skipbase or markclass or false
- if skipsome then
- sequence.skiphash=setmetatableindex(function(t,k)
- local c=resources.classes[k]
- local v=c==skipmark
- or (markclass and c=="mark" and not markclass[k])
- or c==skipligature
- or c==skipbase
- or false
- t[k]=v
- return v
- end)
- else
- sequence.skiphash=false
- end
- else
- sequence.skiphash=false
- end
- end
+if setmetatablenewindex then
+ setmetatablenewindex(features,assign)
end
-local function checksteps(sequence)
- local steps=sequence.steps
- if steps then
- for i=1,#steps do
- steps[i].index=i
- end
+local checkers={
+ rand=function(v)
+ return v==true and "random" or v
end
+}
+if not storage then
+ return
end
-if fonts.helpers then
- fonts.helpers.checkmerge=checkmerge
- fonts.helpers.checkflags=checkflags
- fonts.helpers.checksteps=checksteps
-end
-function readers.expand(data)
- if not data or data.expanded then
- return
- else
- data.expanded=true
- end
- local resources=data.resources
- local sublookups=resources.sublookups
- local sequences=resources.sequences
- local markclasses=resources.markclasses
- local descriptions=data.descriptions
- if descriptions then
- local defaultwidth=resources.defaultwidth or 0
- local defaultheight=resources.defaultheight or 0
- local defaultdepth=resources.defaultdepth or 0
- local basename=trace_markwidth and file.basename(resources.filename)
- for u,d in next,descriptions do
- local bb=d.boundingbox
- local wd=d.width
- if not wd then
- d.width=defaultwidth
- elseif trace_markwidth and wd~=0 and d.class=="mark" then
- report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
- end
- if bb then
- local ht=bb[4]
- local dp=-bb[2]
- if ht==0 or ht<0 then
- else
- d.height=ht
- end
- if dp==0 or dp<0 then
+local usedfeatures=statistics.usedfeatures or {}
+statistics.usedfeatures=usedfeatures
+table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end)
+storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" )
+local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end
+function otffeatures.normalize(features,wrap)
+ if features then
+ local h={}
+ for key,value in next,features do
+ local k=lower(key)
+ if k=="language" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt"
+ elseif k=="script" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt"
+ elseif k=="axis" then
+ h[k]=normalizedaxis(value)
+ else
+ local uk=usedfeatures[key]
+ local uv=uk[value]
+ if uv then
else
- d.depth=dp
- end
- end
- end
- end
- local function expandlookups(sequences)
- if sequences then
- for i=1,#sequences do
- local sequence=sequences[i]
- local steps=sequence.steps
- if steps then
- local nofsteps=sequence.nofsteps
- local kind=sequence.type
- local markclass=sequence.markclass
- if markclass then
- if not markclasses then
- report_warning("missing markclasses")
- sequence.markclass=false
+ uv=tonumber(value)
+ if uv then
+ elseif type(value)=="string" then
+ local b=is_boolean(value)
+ if type(b)=="nil" then
+ if wrap and find(value,",") then
+ uv="{"..lower(value).."}"
+ else
+ uv=lower(value)
+ end
else
- sequence.markclass=markclasses[markclass]
+ uv=b
end
+ elseif type(value)=="table" then
+ uv=sequenced(t,",")
+ else
+ uv=value
end
- for i=1,nofsteps do
- local step=steps[i]
- local baseclasses=step.baseclasses
- if baseclasses then
- local coverage=step.coverage
- for k,v in next,coverage do
- v[1]=baseclasses[v[1]]
- end
- elseif kind=="gpos_cursive" then
- local coverage=step.coverage
- for k,v in next,coverage do
- v[1]=coverage
- end
- end
- local rules=step.rules
- if rules then
- local rulehash={ n=0 }
- local rulesize=0
- local coverage={}
- local lookuptype=sequence.type
- local nofrules=#rules
- step.coverage=coverage
- for currentrule=1,nofrules do
- local rule=rules[currentrule]
- local current=rule.current
- local before=rule.before
- local after=rule.after
- local replacements=rule.replacements or false
- local sequence={}
- local nofsequences=0
- if before then
- for n=1,#before do
- nofsequences=nofsequences+1
- sequence[nofsequences]=before[n]
- end
- end
- local start=nofsequences+1
- for n=1,#current do
- nofsequences=nofsequences+1
- sequence[nofsequences]=current[n]
- end
- local stop=nofsequences
- if after then
- for n=1,#after do
- nofsequences=nofsequences+1
- sequence[nofsequences]=after[n]
- end
- end
- local lookups=rule.lookups or false
- local subtype=nil
- if lookups then
- for i=1,#lookups do
- local lookups=lookups[i]
- if lookups then
- for k,v in next,lookups do
- local lookup=sublookups[v]
- if lookup then
- lookups[k]=lookup
- if not subtype then
- subtype=lookup.type
- end
- else
- end
- end
- end
- end
- end
- if sequence[1] then
- sequence.n=#sequence
- local ruledata={
- currentrule,
- lookuptype,
- sequence,
- start,
- stop,
- lookups,
- replacements,
- subtype,
- }
- rulesize=rulesize+1
- rulehash[rulesize]=ruledata
- rulehash.n=rulesize
- if true then
- for unic in next,sequence[start] do
- local cu=coverage[unic]
- if cu then
- local n=#cu+1
- cu[n]=ruledata
- cu.n=n
- else
- coverage[unic]={ ruledata,n=1 }
- end
- end
- else
- for unic in next,sequence[start] do
- local cu=coverage[unic]
- if cu then
- else
- coverage[unic]=rulehash
- end
- end
- end
- end
- end
- end
+ if not rawget(features,k) then
+ k=rawget(verbosefeatures,k) or k
end
- checkmerge(sequence)
- checkflags(sequence,resources)
- checksteps(sequence)
+ local c=checkers[k]
+ if c then
+ uv=c(uv) or vc
+ end
+ uk[value]=uv
end
+ h[k]=uv
end
end
+ return h
end
- expandlookups(sequences)
- expandlookups(sublookups)
end
end -- closure
@@ -24506,6 +21908,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-otj']={
version=1.001,
+ optimize=true,
comment="companion to font-lib.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -25993,6 +23396,2649 @@ end -- closure
do -- begin closure to overcome local limits and interference
+if not modules then modules={} end modules ['font-oup']={
+ 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,type=next,type
+local P,R,S=lpeg.P,lpeg.R,lpeg.S
+local lpegmatch=lpeg.match
+local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
+local formatters=string.formatters
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local tohash=table.tohash
+local setmetatableindex=table.setmetatableindex
+local report_error=logs.reporter("otf reader","error")
+local report_markwidth=logs.reporter("otf reader","markwidth")
+local report_cleanup=logs.reporter("otf reader","cleanup")
+local report_optimizations=logs.reporter("otf reader","merges")
+local report_unicodes=logs.reporter("otf reader","unicodes")
+local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
+local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end)
+local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end)
+local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end)
+local readers=fonts.handlers.otf.readers
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local f_private=formatters["P%05X"]
+local f_unicode=formatters["U%05X"]
+local f_index=formatters["I%05X"]
+local f_character_y=formatters["%C"]
+local f_character_n=formatters["[ %C ]"]
+local check_duplicates=true
+local check_soft_hyphen=true
+directives.register("otf.checksofthyphen",function(v)
+ check_soft_hyphen=v
+end)
+local function replaced(list,index,replacement)
+ if type(list)=="number" then
+ return replacement
+ elseif type(replacement)=="table" then
+ local t={}
+ local n=index-1
+ for i=1,n do
+ t[i]=list[i]
+ end
+ for i=1,#replacement do
+ n=n+1
+ t[n]=replacement[i]
+ end
+ for i=index+1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ else
+ list[index]=replacement
+ return list
+ end
+end
+local function unifyresources(fontdata,indices)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if not descriptions or not resources then
+ return
+ end
+ local nofindices=#indices
+ local variants=fontdata.resources.variants
+ if variants then
+ for selector,unicodes in next,variants do
+ for unicode,index in next,unicodes do
+ unicodes[unicode]=indices[index]
+ end
+ end
+ end
+ local function remark(marks)
+ if marks then
+ local newmarks={}
+ for k,v in next,marks do
+ local u=indices[k]
+ if u then
+ newmarks[u]=v
+ elseif trace_optimizations then
+ report_optimizations("discarding mark %i",k)
+ end
+ end
+ return newmarks
+ end
+ end
+ local marks=resources.marks
+ if marks then
+ resources.marks=remark(marks)
+ end
+ local markclasses=resources.markclasses
+ if markclasses then
+ for class,marks in next,markclasses do
+ markclasses[class]=remark(marks)
+ end
+ end
+ local marksets=resources.marksets
+ if marksets then
+ for class,marks in next,marksets do
+ marksets[class]=remark(marks)
+ end
+ end
+ local done={}
+ local duplicates=check_duplicates and resources.duplicates
+ if duplicates and not next(duplicates) then
+ duplicates=false
+ end
+ local function recover(cover)
+ for i=1,#cover do
+ local c=cover[i]
+ if not done[c] then
+ local t={}
+ for k,v in next,c do
+ local ug=indices[k]
+ if ug then
+ t[ug]=v
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices)
+ end
+ end
+ cover[i]=t
+ done[c]=d
+ end
+ end
+ end
+ local function recursed(c,kind)
+ local t={}
+ for g,d in next,c do
+ if type(d)=="table" then
+ local ug=indices[g]
+ if ug then
+ t[ug]=recursed(d,kind)
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices)
+ end
+ else
+ t[g]=indices[d]
+ end
+ end
+ return t
+ end
+ local function unifythem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local ud1=indices[d1]
+ if ud1 then
+ t1[ug1]=ud1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=ud1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices)
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=indices[d1]
+ else
+ report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices)
+ end
+ end
+ done[d1]=t2
+ end
+ t1[ug1]=t2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ step.coverage=recursed(c,kind)
+ end
+ elseif kind=="gsub_alternate" or kind=="gsub_multiple" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices)
+ end
+ end
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices)
+ end
+ end
+ t1[indices[g1]]=d1
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=d1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ local c=step.baseclasses
+ if c then
+ local t1=done[c]
+ if not t1 then
+ for g1,d1 in next,c do
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices)
+ end
+ end
+ done[d1]=t2
+ end
+ c[g1]=t2
+ end
+ done[c]=c
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before if before then recover(before) end
+ local after=rule.after if after then recover(after) end
+ local current=rule.current if current then recover(current) end
+ local replacements=rule.replacements
+ if replacements then
+ if not done[replacements] then
+ local r={}
+ for k,v in next,replacements do
+ r[indices[k]]=indices[v]
+ end
+ rule.replacements=r
+ done[replacements]=r
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ unifythem(resources.sequences)
+ unifythem(resources.sublookups)
+end
+local function copyduplicates(fontdata)
+ if check_duplicates then
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ local duplicates=resources.duplicates
+ if check_soft_hyphen then
+ local ds=descriptions[0xAD]
+ if not ds or ds.width==0 then
+ if ds then
+ descriptions[0xAD]=nil
+ if trace_unicodes then
+ report_unicodes("patching soft hyphen")
+ end
+ else
+ if trace_unicodes then
+ report_unicodes("adding soft hyphen")
+ end
+ end
+ if not duplicates then
+ duplicates={}
+ resources.duplicates=duplicates
+ end
+ local dh=duplicates[0x2D]
+ if dh then
+ dh[#dh+1]={ [0xAD]=true }
+ else
+ duplicates[0x2D]={ [0xAD]=true }
+ end
+ end
+ end
+ if duplicates then
+ for u,d in next,duplicates do
+ local du=descriptions[u]
+ if du then
+ local t={ f_character_y(u),"@",f_index(du.index),"->" }
+ local n=0
+ local m=25
+ for u in next,d do
+ if descriptions[u] then
+ if n<m then
+ t[n+4]=f_character_n(u)
+ end
+ else
+ local c=copy(du)
+ c.unicode=u
+ descriptions[u]=c
+ if n<m then
+ t[n+4]=f_character_y(u)
+ end
+ end
+ n=n+1
+ end
+ if trace_unicodes then
+ if n<=m then
+ report_unicodes("%i : % t",n,t)
+ else
+ report_unicodes("%i : % t ...",n,t)
+ end
+ end
+ else
+ end
+ end
+ end
+ end
+end
+local ignore={
+ ["notdef"]=true,
+ [".notdef"]=true,
+ ["null"]=true,
+ [".null"]=true,
+ ["nonmarkingreturn"]=true,
+}
+local function checklookups(fontdata,missing,nofmissing)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if missing and nofmissing and nofmissing<=0 then
+ return
+ end
+ local singles={}
+ local alternates={}
+ local ligatures={}
+ if not missing then
+ missing={}
+ nofmissing=0
+ for u,d in next,descriptions do
+ if not d.unicode then
+ nofmissing=nofmissing+1
+ missing[u]=true
+ end
+ end
+ end
+ local function collectthem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ singles[#singles+1]=c
+ end
+ elseif kind=="gsub_alternate" then
+ local c=step.coverage
+ if c then
+ alternates[#alternates+1]=c
+ end
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ ligatures[#ligatures+1]=c
+ end
+ end
+ end
+ end
+ end
+ end
+ collectthem(resources.sequences)
+ collectthem(resources.sublookups)
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#singles do
+ local c=singles[i]
+ for g1,g2 in next,c do
+ if missing[g1] then
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ end
+ for i=1,#alternates do
+ local c=alternates[i]
+ for g1,d1 in next,c do
+ if missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ if not missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ end
+ end
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ local t,n
+ local function recursed(c)
+ for g,d in next,c do
+ if g~="ligature" then
+ local u=descriptions[g].unicode
+ if u then
+ n=n+1
+ t[n]=u
+ recursed(d)
+ n=n-1
+ end
+ elseif missing[d] then
+ local l={}
+ local m=0
+ for i=1,n do
+ local u=t[i]
+ if type(u)=="table" then
+ for i=1,#u do
+ m=m+1
+ l[m]=u[i]
+ end
+ else
+ m=m+1
+ l[m]=u
+ end
+ end
+ missing[d]=false
+ descriptions[d].unicode=l
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ if nofmissing>0 then
+ t={}
+ n=0
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#ligatures do
+ recursed(ligatures[i])
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ t=nil
+ n=0
+ end
+ if trace_unicodes and nofmissing>0 then
+ local done={}
+ for i,r in next,missing do
+ if r then
+ local data=descriptions[i]
+ local name=data and data.name or f_index(i)
+ if not ignore[name] then
+ done[name]=true
+ end
+ end
+ end
+ if next(done) then
+ report_unicodes("not unicoded: % t",sortedkeys(done))
+ end
+ end
+end
+local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
+local puafirst=0xE000
+local pualast=0xF8FF
+local function unifymissing(fontdata)
+ if not fonts.mappings then
+ require("font-map")
+ require("font-agl")
+ end
+ local unicodes={}
+ local resources=fontdata.resources
+ resources.unicodes=unicodes
+ for unicode,d in next,fontdata.descriptions do
+ if unicode<privateoffset then
+ if unicode>=puafirst and unicode<=pualast then
+ else
+ local name=d.name
+ if name then
+ unicodes[name]=unicode
+ end
+ end
+ else
+ end
+ end
+ fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
+ resources.unicodes=nil
+end
+local function unifyglyphs(fontdata,usenames)
+ local private=fontdata.private or privateoffset
+ local glyphs=fontdata.glyphs
+ local indices={}
+ local descriptions={}
+ local names=usenames and {}
+ local resources=fontdata.resources
+ local zero=glyphs[0]
+ local zerocode=zero.unicode
+ if not zerocode then
+ zerocode=private
+ zero.unicode=zerocode
+ private=private+1
+ end
+ descriptions[zerocode]=zero
+ if names then
+ local name=glyphs[0].name or f_private(zerocode)
+ indices[0]=name
+ names[name]=zerocode
+ else
+ indices[0]=zerocode
+ end
+ if names then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ elseif descriptions[unicode] then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ else
+ local name=glyph.name or f_unicode(unicode)
+ indices[index]=name
+ names[name]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ elseif trace_unicodes then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ if name then
+ report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private)
+ else
+ report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
+ end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ if name then
+ report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index)
+ else
+ report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index)
+ end
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ if name then
+ report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index)
+ else
+ report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index)
+ end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ else
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ end
+ for index=1,#glyphs do
+ local math=glyphs[index].math
+ if math then
+ local list=math.vparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.hparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.vvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ local list=math.hvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ end
+ end
+ local colorpalettes=resources.colorpalettes
+ if colorpalettes then
+ for index=1,#glyphs do
+ local colors=glyphs[index].colors
+ if colors then
+ for i=1,#colors do
+ local c=colors[i]
+ c.slot=indices[c.slot]
+ end
+ end
+ end
+ end
+ fontdata.private=private
+ fontdata.glyphs=nil
+ fontdata.names=names
+ fontdata.descriptions=descriptions
+ fontdata.hashmethod=hashmethod
+ return indices,names
+end
+local p_crappyname do
+ local p_hex=R("af","AF","09")
+ local p_digit=R("09")
+ local p_done=S("._-")^0+P(-1)
+ local p_alpha=R("az","AZ")
+ local p_ALPHA=R("AZ")
+ p_crappyname=(
+ lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
++lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
++lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
++p_digit*p_hex^3+p_alpha*p_digit^1
++P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
+ )*p_done
+end
+local forcekeep=false
+directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep=v
+end)
+local function stripredundant(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ local n=0
+ local c=0
+ if (not context and fonts.privateoffsets.keepnames) or forcekeep then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ else
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name and lpegmatch(p_crappyname,name) then
+ d.name=nil
+ n=n+1
+ end
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n>0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c>0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
+ end
+end
+readers.stripredundant=stripredundant
+function readers.getcomponents(fontdata)
+ local resources=fontdata.resources
+ if resources then
+ local sequences=resources.sequences
+ if sequences then
+ local collected={}
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ if sequence.type=="gsub_ligature" then
+ local steps=sequence.steps
+ if steps then
+ local l={}
+ local function traverse(p,k,v)
+ if k=="ligature" then
+ collected[v]={ unpack(l) }
+ else
+ insert(l,k)
+ for k,vv in next,v do
+ traverse(p,k,vv)
+ end
+ remove(l)
+ end
+ end
+ for i=1,#steps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ traverse(k,k,v)
+ end
+ end
+ end
+ end
+ end
+ end
+ if next(collected) then
+ while true do
+ local done=false
+ for k,v in next,collected do
+ for i=1,#v do
+ local vi=v[i]
+ if vi==k then
+ collected[k]=nil
+ break
+ else
+ local c=collected[vi]
+ if c then
+ done=true
+ local t={}
+ local n=i-1
+ for j=1,n do
+ t[j]=v[j]
+ end
+ for j=1,#c do
+ n=n+1
+ t[n]=c[j]
+ end
+ for j=i+1,#v do
+ n=n+1
+ t[n]=v[j]
+ end
+ collected[k]=t
+ break
+ end
+ end
+ end
+ end
+ if not done then
+ break
+ end
+ end
+ return collected
+ end
+ end
+ end
+end
+readers.unifymissing=unifymissing
+function readers.rehash(fontdata,hashmethod)
+ if not (fontdata and fontdata.glyphs) then
+ return
+ end
+ if hashmethod=="indices" then
+ fontdata.hashmethod="indices"
+ elseif hashmethod=="names" then
+ fontdata.hashmethod="names"
+ local indices=unifyglyphs(fontdata,true)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ else
+ fontdata.hashmethod="unicodes"
+ local indices=unifyglyphs(fontdata)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ stripredundant(fontdata)
+ end
+end
+function readers.checkhash(fontdata)
+ local hashmethod=fontdata.hashmethod
+ if hashmethod=="unicodes" then
+ fontdata.names=nil
+ elseif hashmethod=="names" and fontdata.names then
+ unifyresources(fontdata,fontdata.names)
+ copyduplicates(fontdata)
+ fontdata.hashmethod="unicodes"
+ fontdata.names=nil
+ else
+ readers.rehash(fontdata,"unicodes")
+ end
+end
+function readers.addunicodetable(fontdata)
+ local resources=fontdata.resources
+ local unicodes=resources.unicodes
+ if not unicodes then
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ unicodes={}
+ resources.unicodes=unicodes
+ for u,d in next,descriptions do
+ local n=d.name
+ if n then
+ unicodes[n]=u
+ end
+ end
+ end
+ end
+end
+local concat,sort=table.concat,table.sort
+local next,type,tostring=next,type,tostring
+local criterium=1
+local threshold=0
+local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end)
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local function tabstr_normal(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k..">"..tabstr_normal(v)
+ elseif v==true then
+ s[n]=k.."+"
+ elseif v then
+ s[n]=k.."="..v
+ else
+ s[n]=k.."-"
+ end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+local function tabstr_flat(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ s[n]=k.."="..v
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+local function tabstr_mixed(t)
+ local s={}
+ local n=#t
+ if n==0 then
+ return ""
+ elseif n==1 then
+ local k=t[1]
+ if k==true then
+ return "++"
+ elseif k==false then
+ return "--"
+ else
+ return tostring(k)
+ end
+ else
+ for i=1,n do
+ local k=t[i]
+ if k==true then
+ s[i]="++"
+ elseif k==false then
+ s[i]="--"
+ else
+ s[i]=k
+ end
+ end
+ return concat(s,",")
+ end
+end
+local function tabstr_boolean(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if v then
+ s[n]=k.."+"
+ else
+ s[n]=k.."-"
+ end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+function readers.pack(data)
+ if data then
+ local h,t,c={},{},{}
+ local hh,tt,cc={},{},{}
+ local nt,ntt=0,0
+ local function pack_normal(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_normal_cc(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ v[1]=0
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_flat(v)
+ local tag=tabstr_flat(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_indexed(v)
+ local tag=concat(v," ")
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_mixed(v)
+ local tag=tabstr_mixed(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_boolean(v)
+ local tag=tabstr_boolean(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_final(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function pack_final_cc(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function success(stage,pass)
+ if nt==0 then
+ if trace_loading or trace_packing then
+ report_otf("pack quality: nothing to pack")
+ end
+ return false
+ elseif nt>=threshold then
+ local one=0
+ local two=0
+ local rest=0
+ if pass==1 then
+ for k,v in next,c do
+ if v==1 then
+ one=one+1
+ elseif v==2 then
+ two=two+1
+ else
+ rest=rest+1
+ end
+ end
+ else
+ for k,v in next,cc do
+ if v>20 then
+ rest=rest+1
+ elseif v>10 then
+ two=two+1
+ else
+ one=one+1
+ end
+ end
+ data.tables=tt
+ end
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
+ stage,pass,one+two+rest,one,two,rest,criterium)
+ end
+ return true
+ else
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
+ stage,pass,nt,threshold)
+ end
+ return false
+ end
+ end
+ local function packers(pass)
+ if pass==1 then
+ return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc
+ else
+ return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc
+ end
+ end
+ local resources=data.resources
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local chardata=characters and characters.data
+ local descriptions=data.descriptions or data.glyphs
+ if not descriptions then
+ return
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 1, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local boundingbox=description.boundingbox
+ if boundingbox then
+ description.boundingbox=pack_indexed(boundingbox)
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ for tag,kern in next,kerns do
+ kerns[tag]=pack_normal(kern)
+ end
+ end
+ end
+ end
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format~="pair" then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
+ end
+ elseif step.shared then
+ local shared={}
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ if not shared[d2] then
+ local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
+ local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
+ shared[d2]=true
+ end
+ end
+ end
+ if pass==2 then
+ step.shared=nil
+ end
+ else
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
+ local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ if d1 and d1~=true then
+ c[g1]=pack_indexed(d1)
+ end
+ end
+ else
+ step.coverage=pack_normal(c)
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local f=d1[2] if f then d1[2]=pack_indexed(f) end
+ local s=d1[3] if s then d1[3]=pack_indexed(s) end
+ end
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_indexed(d2)
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ for g3,d3 in next,d2 do
+ d2[g3]=pack_indexed(d3)
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
+ local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
+ local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
+ local r=rule.replacements if r then rule.replacements=pack_flat (r) end
+ end
+ end
+ end
+ end
+ if order then
+ sequence.order=pack_indexed(order)
+ end
+ if features then
+ for script,feature in next,features do
+ features[script]=pack_normal(feature)
+ end
+ end
+ if flags then
+ sequence.flags=pack_normal(flags)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ list[feature]=pack_normal(spec)
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ p[j]=pack_indexed(p[j])
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ v[j]=pack_normal(v[j])
+ end
+ end
+ end
+ local function packdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ for j=1,#d do
+ d[j]=pack_indexed(d[j])
+ end
+ di.regions=pack_indexed(di.regions)
+ end
+ end
+ local regions=main.regions
+ if regions then
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ r[j]=pack_normal(r[j])
+ end
+ end
+ end
+ end
+ end
+ packdeltas(variable.global)
+ packdeltas(variable.horizontal)
+ packdeltas(variable.vertical)
+ packdeltas(variable.metrics)
+ end
+ if not success(1,pass) then
+ return
+ end
+ end
+ if nt>0 then
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 2, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ math.kerns=pack_normal(kerns)
+ end
+ end
+ end
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local r=rule.before if r then rule.before=pack_normal(r) end
+ local r=rule.after if r then rule.after=pack_normal(r) end
+ local r=rule.current if r then rule.current=pack_normal(r) end
+ end
+ end
+ end
+ end
+ if features then
+ sequence.features=pack_normal(features)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if variable then
+ local function unpackdeltas(main)
+ if main then
+ local regions=main.regions
+ if regions then
+ main.regions=pack_normal(regions)
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 3, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal_cc(d1)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ end
+ end
+ end
+end
+local unpacked_mt={
+ __index=function(t,k)
+ t[k]=false
+ return k
+ end
+}
+function readers.unpack(data)
+ if data then
+ local tables=data.tables
+ if tables then
+ local resources=data.resources
+ local descriptions=data.descriptions or data.glyphs
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local unpacked={}
+ setmetatable(unpacked,unpacked_mt)
+ for unicode,description in next,descriptions do
+ local tv=tables[description.boundingbox]
+ if tv then
+ description.boundingbox=tv
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ local tm=tables[kerns]
+ if tm then
+ math.kerns=tm
+ kerns=unpacked[tm]
+ end
+ if kerns then
+ for k,kern in next,kerns do
+ local tv=tables[kern]
+ if tv then
+ kerns[k]=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ local function unpackthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ local markclass=sequence.markclass
+ if features then
+ local tv=tables[features]
+ if tv then
+ sequence.features=tv
+ features=tv
+ end
+ for script,feature in next,features do
+ local tv=tables[feature]
+ if tv then
+ features[script]=tv
+ end
+ end
+ end
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ d1=tv
+ end
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d1[g2]=tv
+ d2=tv
+ end
+ local f=tables[d2[1]] if f then d2[1]=f end
+ local s=tables[d2[2]] if s then d2[2]=s end
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
+ end
+ else
+ local tv=tables[c]
+ if tv then
+ step.coverage=tv
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ d1=tv
+ c[g1]=d1
+ end
+ local f=tables[d1[2]] if f then d1[2]=f end
+ local s=tables[d1[3]] if s then d1[3]=s end
+ end
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d1[g2]=tv
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
+ end
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d2=tv
+ d1[g2]=d2
+ end
+ for g3,d3 in next,d2 do
+ local tv=tables[d2[g3]]
+ if tv then
+ d2[g3]=tv
+ end
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
+ end
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before
+ if before then
+ local tv=tables[before]
+ if tv then
+ rule.before=tv
+ before=tv
+ end
+ for i=1,#before do
+ local tv=tables[before[i]]
+ if tv then
+ before[i]=tv
+ end
+ end
+ end
+ local after=rule.after
+ if after then
+ local tv=tables[after]
+ if tv then
+ rule.after=tv
+ after=tv
+ end
+ for i=1,#after do
+ local tv=tables[after[i]]
+ if tv then
+ after[i]=tv
+ end
+ end
+ end
+ local current=rule.current
+ if current then
+ local tv=tables[current]
+ if tv then
+ rule.current=tv
+ current=tv
+ end
+ for i=1,#current do
+ local tv=tables[current[i]]
+ if tv then
+ current[i]=tv
+ end
+ end
+ end
+ local replacements=rule.replacements
+ if replacements then
+ local tv=tables[replacements]
+ if tv then
+ rule.replacements=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ if order then
+ local tv=tables[order]
+ if tv then
+ sequence.order=tv
+ end
+ end
+ if flags then
+ local tv=tables[flags]
+ if tv then
+ sequence.flags=tv
+ end
+ end
+ end
+ end
+ if sequences then
+ unpackthem(sequences)
+ end
+ if sublookups then
+ unpackthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ local tv=tables[spec]
+ if tv then
+ list[feature]=tv
+ end
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ local tv=tables[p[j]]
+ if tv then
+ p[j]=tv
+ end
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ local tv=tables[v[j]]
+ if tv then
+ v[j]=tv
+ end
+ end
+ end
+ end
+ local function unpackdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ local r=di.regions
+ for j=1,#d do
+ local tv=tables[d[j]]
+ if tv then
+ d[j]=tv
+ end
+ end
+ local tv=di.regions
+ if tv then
+ di.regions=tv
+ end
+ end
+ end
+ local regions=main.regions
+ if regions then
+ local tv=tables[regions]
+ if tv then
+ main.regions=tv
+ regions=tv
+ end
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ local tv=tables[r[j]]
+ if tv then
+ r[j]=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ data.tables=nil
+ end
+ end
+end
+local mt={
+ __index=function(t,k)
+ if k=="height" then
+ local ht=t.boundingbox[4]
+ return ht<0 and 0 or ht
+ elseif k=="depth" then
+ local dp=-t.boundingbox[2]
+ return dp<0 and 0 or dp
+ elseif k=="width" then
+ return 0
+ elseif k=="name" then
+ return forcenotdef and ".notdef"
+ end
+ end
+}
+local function sameformat(sequence,steps,first,nofsteps,kind)
+ return true
+end
+local function mergesteps_1(lookup,strict)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
+ for i=2,nofsteps do
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ if not target[k] then
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_2(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
+ for i=2,nofsteps do
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ for kk,vv in next,v do
+ if tk[kk]==nil then
+ tk[kk]=vv
+ end
+ end
+ else
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_3(lookup,strict)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local coverage={}
+ for i=1,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=coverage[k]
+ if tk then
+ if trace_optimizations then
+ report_optimizations("quitting merge due to multiple checks")
+ end
+ return nofsteps
+ else
+ coverage[k]=v
+ end
+ end
+ end
+ end
+ local first=steps[1]
+ local baseclasses={}
+ for i=1,nofsteps do
+ local offset=i*10
+ local step=steps[i]
+ for k,v in sortedhash(step.baseclasses) do
+ baseclasses[offset+k]=v
+ end
+ for k,v in next,step.coverage do
+ v[1]=offset+v[1]
+ end
+ end
+ first.baseclasses=baseclasses
+ first.coverage=coverage
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function nested(old,new)
+ for k,v in next,old do
+ if k=="ligature" then
+ if not new.ligature then
+ new.ligature=v
+ end
+ else
+ local n=new[k]
+ if n then
+ nested(v,n)
+ else
+ new[k]=v
+ end
+ end
+ end
+end
+local function mergesteps_4(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ nested(v,tk)
+ else
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_5(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ local hash=nil
+ for k,v in next,target do
+ hash=v[1]
+ break
+ end
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ if not tk[2] then
+ tk[2]=v[2]
+ end
+ if not tk[3] then
+ tk[3]=v[3]
+ end
+ else
+ target[k]=v
+ v[1]=hash
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function checkkerns(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=step.coverage
+ local kerns=true
+ for g1,d1 in next,coverage do
+ if d1==true then
+ elseif not d1 then
+ elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then
+ kerns=false
+ break
+ end
+ end
+ if kerns then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ local c={}
+ for g1,d1 in next,coverage do
+ if d1 and d1~=true then
+ c[g1]=d1[3]
+ end
+ end
+ step.coverage=c
+ step.format="move"
+ kerned=kerned+1
+ end
+ end
+ end
+ return kerned
+end
+local function checkpairs(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ local function onlykerns(step)
+ local coverage=step.coverage
+ for g1,d1 in next,coverage do
+ for g2,d2 in next,d1 do
+ if d2[2] then
+ return false
+ else
+ local v=d2[1]
+ if v==true then
+ elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then
+ return false
+ end
+ end
+ end
+ end
+ return coverage
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=onlykerns(step)
+ if coverage then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ for g1,d1 in next,coverage do
+ local d={}
+ for g2,d2 in next,d1 do
+ local v=d2[1]
+ if v==true then
+ elseif v then
+ d[g2]=v[3]
+ end
+ end
+ coverage[g1]=d
+ end
+ step.format="move"
+ kerned=kerned+1
+ end
+ end
+ end
+ return kerned
+end
+local compact_pairs=true
+local compact_singles=true
+local merge_pairs=true
+local merge_singles=true
+local merge_substitutions=true
+local merge_alternates=true
+local merge_multiples=true
+local merge_ligatures=true
+local merge_cursives=true
+local merge_marks=true
+directives.register("otf.compact.pairs",function(v) compact_pairs=v end)
+directives.register("otf.compact.singles",function(v) compact_singles=v end)
+directives.register("otf.merge.pairs",function(v) merge_pairs=v end)
+directives.register("otf.merge.singles",function(v) merge_singles=v end)
+directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end)
+directives.register("otf.merge.alternates",function(v) merge_alternates=v end)
+directives.register("otf.merge.multiples",function(v) merge_multiples=v end)
+directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end)
+directives.register("otf.merge.cursives",function(v) merge_cursives=v end)
+directives.register("otf.merge.marks",function(v) merge_marks=v end)
+function readers.compact(data)
+ if not data or data.compacted then
+ return
+ else
+ data.compacted=true
+ end
+ local resources=data.resources
+ local merged=0
+ local kerned=0
+ local allsteps=0
+ local function compact(what)
+ local lookups=resources[what]
+ if lookups then
+ for i=1,#lookups do
+ local lookup=lookups[i]
+ local nofsteps=lookup.nofsteps
+ local kind=lookup.type
+ allsteps=allsteps+nofsteps
+ if nofsteps>1 then
+ local merg=merged
+ if kind=="gsub_single" then
+ if merge_substitutions then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_alternate" then
+ if merge_alternates then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_multiple" then
+ if merge_multiples then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_ligature" then
+ if merge_ligatures then
+ merged=merged+mergesteps_4(lookup)
+ end
+ elseif kind=="gpos_single" then
+ if merge_singles then
+ merged=merged+mergesteps_1(lookup,true)
+ end
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if merge_pairs then
+ merged=merged+mergesteps_2(lookup)
+ end
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ elseif kind=="gpos_cursive" then
+ if merge_cursives then
+ merged=merged+mergesteps_5(lookup)
+ end
+ elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then
+ if merge_marks then
+ merged=merged+mergesteps_3(lookup)
+ end
+ end
+ if merg~=merged then
+ lookup.merged=true
+ end
+ elseif nofsteps==1 then
+ local kern=kerned
+ if kind=="gpos_single" then
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ end
+ if kern~=kerned then
+ end
+ end
+ end
+ elseif trace_optimizations then
+ report_optimizations("no lookups in %a",what)
+ end
+ end
+ compact("sequences")
+ compact("sublookups")
+ if trace_optimizations then
+ if merged>0 then
+ report_optimizations("%i steps of %i removed due to merging",merged,allsteps)
+ end
+ if kerned>0 then
+ report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
+ end
+ end
+end
+local function mergesteps(t,k)
+ if k=="merged" then
+ local merged={}
+ for i=1,#t do
+ local step=t[i]
+ local coverage=step.coverage
+ for k in next,coverage do
+ local m=merged[k]
+ if m then
+ m[2]=i
+ else
+ merged[k]={ i,i }
+ end
+ end
+ end
+ t.merged=merged
+ return merged
+ end
+end
+local function checkmerge(sequence)
+ local steps=sequence.steps
+ if steps then
+ setmetatableindex(steps,mergesteps)
+ end
+end
+local function checkflags(sequence,resources)
+ if not sequence.skiphash then
+ local flags=sequence.flags
+ if flags then
+ local skipmark=flags[1]
+ local skipligature=flags[2]
+ local skipbase=flags[3]
+ local markclass=sequence.markclass
+ local skipsome=skipmark or skipligature or skipbase or markclass or false
+ if skipsome then
+ sequence.skiphash=setmetatableindex(function(t,k)
+ local c=resources.classes[k]
+ local v=c==skipmark
+ or (markclass and c=="mark" and not markclass[k])
+ or c==skipligature
+ or c==skipbase
+ or false
+ t[k]=v
+ return v
+ end)
+ else
+ sequence.skiphash=false
+ end
+ else
+ sequence.skiphash=false
+ end
+ end
+end
+local function checksteps(sequence)
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ steps[i].index=i
+ end
+ end
+end
+if fonts.helpers then
+ fonts.helpers.checkmerge=checkmerge
+ fonts.helpers.checkflags=checkflags
+ fonts.helpers.checksteps=checksteps
+end
+function readers.expand(data)
+ if not data or data.expanded then
+ return
+ else
+ data.expanded=true
+ end
+ local resources=data.resources
+ local sublookups=resources.sublookups
+ local sequences=resources.sequences
+ local markclasses=resources.markclasses
+ local descriptions=data.descriptions
+ if descriptions then
+ local defaultwidth=resources.defaultwidth or 0
+ local defaultheight=resources.defaultheight or 0
+ local defaultdepth=resources.defaultdepth or 0
+ local basename=trace_markwidth and file.basename(resources.filename)
+ for u,d in next,descriptions do
+ local bb=d.boundingbox
+ local wd=d.width
+ if not wd then
+ d.width=defaultwidth
+ elseif trace_markwidth and wd~=0 and d.class=="mark" then
+ report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
+ end
+ if bb then
+ local ht=bb[4]
+ local dp=-bb[2]
+ if ht==0 or ht<0 then
+ else
+ d.height=ht
+ end
+ if dp==0 or dp<0 then
+ else
+ d.depth=dp
+ end
+ end
+ end
+ end
+ local function expandlookups(sequences)
+ if sequences then
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps then
+ local nofsteps=sequence.nofsteps
+ local kind=sequence.type
+ local markclass=sequence.markclass
+ if markclass then
+ if not markclasses then
+ report_warning("missing markclasses")
+ sequence.markclass=false
+ else
+ sequence.markclass=markclasses[markclass]
+ end
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ local baseclasses=step.baseclasses
+ if baseclasses then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=baseclasses[v[1]]
+ end
+ elseif kind=="gpos_cursive" then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=coverage
+ end
+ end
+ local rules=step.rules
+ if rules then
+ local rulehash={ n=0 }
+ local rulesize=0
+ local coverage={}
+ local lookuptype=sequence.type
+ local nofrules=#rules
+ step.coverage=coverage
+ for currentrule=1,nofrules do
+ local rule=rules[currentrule]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
+ end
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
+ end
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups then
+ for i=1,#lookups do
+ local lookups=lookups[i]
+ if lookups then
+ for k,v in next,lookups do
+ local lookup=sublookups[v]
+ if lookup then
+ lookups[k]=lookup
+ if not subtype then
+ subtype=lookup.type
+ end
+ else
+ end
+ end
+ end
+ end
+ end
+ if sequence[1] then
+ sequence.n=#sequence
+ local ruledata={
+ currentrule,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ rulesize=rulesize+1
+ rulehash[rulesize]=ruledata
+ rulehash.n=rulesize
+ if true then
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ local n=#cu+1
+ cu[n]=ruledata
+ cu.n=n
+ else
+ coverage[unic]={ ruledata,n=1 }
+ end
+ end
+ else
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ else
+ coverage[unic]=rulehash
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ checkmerge(sequence)
+ checkflags(sequence,resources)
+ checksteps(sequence)
+ end
+ end
+ end
+ end
+ expandlookups(sequences)
+ expandlookups(sublookups)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
if not modules then modules={} end modules ['font-ota']={
version=1.001,
comment="companion to font-ini.mkiv",
@@ -26001,6 +26047,7 @@ if not modules then modules={} end modules ['font-ota']={
license="see context related readme files"
}
local type=type
+local setmetatableindex=table.setmetatableindex
if not trackers then trackers={ register=function() end } end
local fonts,nodes,node=fonts,nodes,node
local allocate=utilities.storage.allocate
@@ -26214,7 +26261,7 @@ if not classifiers then
local f_mandiac,l_mandiac=characters.blockrange("mandiac")
local f_nko,l_nko=characters.blockrange("nko")
local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda")
- classifiers=table.setmetatableindex(function(t,k)
+ classifiers=setmetatableindex(function(t,k)
if type(k)=="number" then
local c=chardata[k]
local v=false
@@ -26380,6 +26427,106 @@ end
methods.syrc=methods.arab
methods.mand=methods.arab
methods.nko=methods.arab
+do
+ local joining=setmetatableindex(function(t,k)
+ if type(k)=="number" then
+ local c=chardata[k]
+ local v=false
+ if c then
+ local mongolian=c.mongolian
+ v=mongolian
+ end
+ t[k]=v
+ return v
+ end
+ end)
+ function methods.mong(head,font,attr)
+ local first,last
+ local current=head
+ local done=false
+ local prevjoin=nil
+ local prestate=nil
+ current=tonut(current)
+ local function wrapup()
+ if last then
+ if last~=first then
+ local s=getstate(last)
+ if s==s_medi then
+ setstate(last,s_fina)
+ elseif s==s_init then
+ setstate(last,s_isol)
+ end
+ end
+ last=nil
+ first=nil
+ prevjoin=nil
+ prestate=nil
+ end
+ end
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getstate(current) then
+ local currjoin=joining[char]
+ done=true
+ if not last then
+ setstate(current,s_isol)
+ prevjoin=currjoin
+ first=current
+ last=current
+ prevstate=s_isol
+ elseif currjoin=="t" then
+ last=current
+ elseif prevjoin=="d" or prevjoin=="jc" or prevjoin=="l" then
+ if currjoin=="d" or prevjoin=="jc" or prevjoin=="r" then
+ local s=getstate(last)
+ if s==s_isol then
+ setstate(last,s_init)
+ elseif s==s_fina then
+ setstate(last,s_medi)
+ end
+ setstate(current,s_fina)
+ prevstate=s_fina
+ elseif prevjoin=="nj" or prevjoin=="l" then
+ local s=getstate(last)
+ if s==s_medi then
+ setstate(last,s_fina)
+ elseif s==s_init then
+ setstate(last,s_isol)
+ end
+ setstate(current,s_isol)
+ prevstate=s_isol
+ end
+ prevjoin=currjoin
+ last=current
+ elseif prevjoin=="nj" or prevjoin=="r" then
+ if s==s_medi then
+ setstate(last,s_fina)
+ elseif s==s_init then
+ setstate(last,s_isol)
+ end
+ setstate(current,s_isol)
+ prevjoin=currjoin
+ prevstate=s_isol
+ last=current
+ elseif last then
+ wrapup()
+ end
+ else
+ if last then
+ wrapup()
+ end
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if last then
+ wrapup()
+ end
+ return head,done
+ end
+end
directives.register("otf.analyze.useunicodemarks",function(v)
analyzers.useunicodemarks=v
end)
@@ -26390,6 +26537,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-ots']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -26492,6 +26640,8 @@ local disc_code=nodecodes.disc
local math_code=nodecodes.math
local dir_code=nodecodes.dir
local localpar_code=nodecodes.localpar
+local lefttoright_code=nodes.dirvalues.lefttoright
+local righttoleft_code=nodes.dirvalues.righttoleft
local discretionarydisc_code=disccodes.discretionary
local ligatureglyph_code=glyphcodes.ligature
local a_noligature=attributes.private("noligature")
@@ -27995,6 +28145,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local sweepnode=sweepnode
local sweeptype=sweeptype
local sweepoverflow=false
+ local checkdisc=getprev(head)
local keepdisc=not sweepnode
local lookaheaddisc=nil
local backtrackdisc=nil
@@ -28118,7 +28269,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local current=prev
local i=f
local t=sweeptype=="pre" or sweeptype=="replace"
- if not current and t and current==checkdisk then
+ if not current and t and current==checkdisc then
current=getprev(sweepnode)
end
while current and i>1 do
@@ -28146,7 +28297,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
end
end
current=getprev(current)
- if t and current==checkdisk then
+ if t and current==checkdisc then
current=getprev(sweepnode)
end
end
@@ -28331,6 +28482,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local l=ck[5]
local current=start
local last=start
+ if s==1 then
+ goto next
+ end
if l>f then
local discfound
local n=f+1
@@ -28396,6 +28550,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
break
end
end
+ if n<=l then
+ notmatchpre[last]=true
+ end
else
notmatchpre[last]=true
end
@@ -29341,8 +29498,6 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase
end
local txtdirstate,pardirstate do
local getdirection=nuts.getdirection
- local lefttoright=0
- local righttoleft=1
txtdirstate=function(start,stack,top,rlparmode)
local dir,pop=getdirection(start)
if pop then
@@ -29350,19 +29505,19 @@ local txtdirstate,pardirstate do
return 0,rlparmode
else
top=top-1
- if stack[top]==righttoleft then
+ if stack[top]==righttoleft_code then
return top,-1
else
return top,1
end
end
- elseif dir==lefttoright then
+ elseif dir==lefttoright_code then
top=top+1
- stack[top]=lefttoright
+ stack[top]=lefttoright_code
return top,1
- elseif dir==righttoleft then
+ elseif dir==righttoleft_code then
top=top+1
- stack[top]=righttoleft
+ stack[top]=righttoleft_code
return top,-1
else
return top,rlparmode
@@ -29370,13 +29525,9 @@ local txtdirstate,pardirstate do
end
pardirstate=function(start)
local dir=getdirection(start)
- if dir==lefttoright then
- return 1,1
- elseif dir==righttoleft then
- return -1,-1
- elseif dir=="TLT" then
+ if dir==lefttoright_code then
return 1,1
- elseif dir=="TRT" then
+ elseif dir==righttoleft_code then
return -1,-1
else
return 0,0
@@ -29431,7 +29582,7 @@ do
local initialrl=0
if getid(head)==localpar_code and start_of_par(head) then
initialrl=pardirstate(head)
- elseif direction==1 or direction=="TRT" then
+ elseif direction==righttoleft_code then
initialrl=-1
end
local datasets=otfdataset(tfmdata,font,attr)
@@ -29655,7 +29806,7 @@ do
local done=false
local dirstack={ nil }
local start=head
- local initialrl=(direction==1 or direction=="TRT") and -1 or 0
+ local initialrl=(direction==righttoleft_code) and -1 or 0
local rlmode=initialrl
local rlparmode=initialrl
local topstack=0
@@ -29980,6 +30131,765 @@ end -- closure
do -- begin closure to overcome local limits and interference
+if not modules then modules={} end modules ['font-otc']={
+ 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 insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash
+local type,next,tonumber=type,next,tonumber
+local lpegmatch=lpeg.match
+local utfbyte,utflen=utf.byte,utf.len
+local sortedhash=table.sortedhash
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local fonts=fonts
+local otf=fonts.handlers.otf
+local registerotffeature=otf.features.register
+local setmetatableindex=table.setmetatableindex
+local fonthelpers=fonts.helpers
+local checkmerge=fonthelpers.checkmerge
+local checkflags=fonthelpers.checkflags
+local checksteps=fonthelpers.checksteps
+local normalized={
+ substitution="substitution",
+ single="substitution",
+ ligature="ligature",
+ alternate="alternate",
+ multiple="multiple",
+ kern="kern",
+ pair="pair",
+ single="single",
+ chainsubstitution="chainsubstitution",
+ chainposition="chainposition",
+}
+local types={
+ substitution="gsub_single",
+ ligature="gsub_ligature",
+ alternate="gsub_alternate",
+ multiple="gsub_multiple",
+ kern="gpos_pair",
+ pair="gpos_pair",
+ single="gpos_single",
+ chainsubstitution="gsub_contextchain",
+ chainposition="gpos_contextchain",
+}
+local names={
+ gsub_single="gsub",
+ gsub_multiple="gsub",
+ gsub_alternate="gsub",
+ gsub_ligature="gsub",
+ gsub_context="gsub",
+ gsub_contextchain="gsub",
+ gsub_reversecontextchain="gsub",
+ gpos_single="gpos",
+ gpos_pair="gpos",
+ gpos_cursive="gpos",
+ gpos_mark2base="gpos",
+ gpos_mark2ligature="gpos",
+ gpos_mark2mark="gpos",
+ gpos_context="gpos",
+ gpos_contextchain="gpos",
+}
+setmetatableindex(types,function(t,k) t[k]=k return k end)
+local everywhere={ ["*"]={ ["*"]=true } }
+local noflags={ false,false,false,false }
+local function getrange(sequences,category)
+ local count=#sequences
+ local first=nil
+ local last=nil
+ for i=1,count do
+ local t=sequences[i].type
+ if t and names[t]==category then
+ if not first then
+ first=i
+ end
+ last=i
+ end
+ end
+ return first or 1,last or count
+end
+local function validspecification(specification,name)
+ local dataset=specification.dataset
+ if dataset then
+ elseif specification[1] then
+ dataset=specification
+ specification={ dataset=dataset }
+ else
+ dataset={ { data=specification.data } }
+ specification.data=nil
+ specification.dataset=dataset
+ end
+ local first=dataset[1]
+ if first then
+ first=first.data
+ end
+ if not first then
+ report_otf("invalid feature specification, no dataset")
+ return
+ end
+ if type(name)~="string" then
+ name=specification.name or first.name
+ end
+ if type(name)~="string" then
+ report_otf("invalid feature specification, no name")
+ return
+ end
+ local n=#dataset
+ if n>0 then
+ for i=1,n do
+ setmetatableindex(dataset[i],specification)
+ end
+ return specification,name
+ end
+end
+local function addfeature(data,feature,specifications)
+ if not specifications then
+ report_otf("missing specification")
+ return
+ end
+ local descriptions=data.descriptions
+ local resources=data.resources
+ local features=resources.features
+ local sequences=resources.sequences
+ if not features or not sequences then
+ report_otf("missing specification")
+ return
+ end
+ local alreadydone=resources.alreadydone
+ if not alreadydone then
+ alreadydone={}
+ resources.alreadydone=alreadydone
+ end
+ if alreadydone[specifications] then
+ return
+ else
+ alreadydone[specifications]=true
+ end
+ local fontfeatures=resources.features or everywhere
+ local unicodes=resources.unicodes
+ local splitter=lpeg.splitter(" ",unicodes)
+ local done=0
+ local skip=0
+ local aglunicodes=false
+ local privateslot=fonthelpers.privateslot
+ local specifications=validspecification(specifications,feature)
+ if not specifications then
+ return
+ end
+ local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1)
+ local function tounicode(code)
+ if not code then
+ return
+ end
+ if type(code)=="number" then
+ return code
+ end
+ local u=unicodes[code]
+ if u then
+ return u
+ end
+ if utflen(code)==1 then
+ u=utfbyte(code)
+ if u then
+ return u
+ end
+ end
+ if privateslot then
+ u=privateslot(code)
+ if u then
+ return u
+ end
+ end
+ local u=lpegmatch(p,code)
+ if u then
+ return u
+ end
+ if not aglunicodes then
+ aglunicodes=fonts.encodings.agl.unicodes
+ end
+ local u=aglunicodes[code]
+ if u then
+ return u
+ end
+ end
+ local coverup=otf.coverup
+ local coveractions=coverup.actions
+ local stepkey=coverup.stepkey
+ local register=coverup.register
+ local function prepare_substitution(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(replacement)=="table" then
+ replacement=replacement[1]
+ end
+ replacement=tounicode(replacement)
+ if replacement and (nocheck or descriptions[replacement]) then
+ cover(coverage,unicode,replacement)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_alternate(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r={}
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ r[i]=(nocheck or descriptions[u]) and u or unicode
+ end
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ local u=tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_multiple(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r={}
+ local n=0
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ if nocheck or descriptions[u] then
+ n=n+1
+ r[n]=u
+ end
+ end
+ if n>0 then
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ else
+ local u=tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_ligature(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,ligature in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(ligature)=="string" then
+ ligature={ lpegmatch(splitter,ligature) }
+ end
+ local present=true
+ for i=1,#ligature do
+ local l=ligature[i]
+ local u=tounicode(l)
+ if nocheck or descriptions[u] then
+ ligature[i]=u
+ else
+ present=false
+ break
+ end
+ end
+ if present then
+ cover(coverage,unicode,ligature)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function resetspacekerns()
+ data.properties.hasspacekerns=true
+ data.resources .spacekerns=nil
+ end
+ local function prepare_kern(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ local isspace=false
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
+ end
+ else
+ skip=skip+1
+ end
+ else
+ skip=skip+1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ return coverage
+ end
+ local function prepare_pair(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ if cover then
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
+ end
+ else
+ skip=skip+1
+ end
+ else
+ skip=skip+1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ else
+ report_otf("unknown cover type %a",featuretype)
+ end
+ return coverage
+ end
+ local prepare_single=prepare_pair
+ local function prepare_chain(list,featuretype,sublookups)
+ local rules=list.rules
+ local coverage={}
+ if rules then
+ local rulehash={}
+ local rulesize=0
+ local lookuptype=types[featuretype]
+ for nofrules=1,#rules do
+ local rule=rules[nofrules]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
+ end
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
+ end
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups and sublookups then
+ for k,v in sortedhash(lookups) do
+ local t=type(v)
+ if t=="table" then
+ for i=1,#v do
+ local vi=v[i]
+ if type(vi)~="table" then
+ v[i]={ vi }
+ end
+ end
+ elseif t=="number" then
+ local lookup=sublookups[v]
+ if lookup then
+ lookups[k]={ lookup }
+ if not subtype then
+ subtype=lookup.type
+ end
+ elseif v==0 then
+ lookups[k]={ { type="gsub_remove" } }
+ else
+ lookups[k]=false
+ end
+ else
+ lookups[k]=false
+ end
+ end
+ end
+ if nofsequences>0 then
+ local hashed={}
+ for i=1,nofsequences do
+ local t={}
+ local s=sequence[i]
+ for i=1,#s do
+ local u=tounicode(s[i])
+ if u then
+ t[u]=true
+ end
+ end
+ hashed[i]=t
+ end
+ sequence=hashed
+ rulesize=rulesize+1
+ rulehash[rulesize]={
+ nofrules,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ for unic in sortedhash(sequence[start]) do
+ local cu=coverage[unic]
+ if not cu then
+ coverage[unic]=rulehash
+ end
+ end
+ sequence.n=nofsequences
+ end
+ end
+ rulehash.n=rulesize
+ end
+ return coverage
+ end
+ local dataset=specifications.dataset
+ local function report(name,category,position,first,last,sequences)
+ report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
+ name,category,position,first,last,1,#sequences)
+ end
+ local function inject(specification,sequences,sequence,first,last,category,name)
+ local position=specification.position or false
+ if not position then
+ position=specification.prepend
+ if position==true then
+ if trace_loading then
+ report(name,category,first,first,last,sequences)
+ end
+ insert(sequences,first,sequence)
+ return
+ end
+ end
+ if not position then
+ position=specification.append
+ if position==true then
+ if trace_loading then
+ report(name,category,last+1,first,last,sequences)
+ end
+ insert(sequences,last+1,sequence)
+ return
+ end
+ end
+ local kind=type(position)
+ if kind=="string" then
+ local index=false
+ for i=first,last do
+ local s=sequences[i]
+ local f=s.features
+ if f then
+ for k in sortedhash(f) do
+ if k==position then
+ index=i
+ break
+ end
+ end
+ if index then
+ break
+ end
+ end
+ end
+ if index then
+ position=index
+ else
+ position=last+1
+ end
+ elseif kind=="number" then
+ if position<0 then
+ position=last-position+1
+ end
+ if position>last then
+ position=last+1
+ elseif position<first then
+ position=first
+ end
+ else
+ position=last+1
+ end
+ if trace_loading then
+ report(name,category,position,first,last,sequences)
+ end
+ insert(sequences,position,sequence)
+ end
+ for s=1,#dataset do
+ local specification=dataset[s]
+ local valid=specification.valid
+ local feature=specification.name or feature
+ if not feature or feature=="" then
+ report_otf("no valid name given for extra feature")
+ elseif not valid or valid(data,specification,feature) then
+ local initialize=specification.initialize
+ if initialize then
+ specification.initialize=initialize(specification,data) and initialize or nil
+ end
+ local askedfeatures=specification.features or everywhere
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nocheck=specification.nocheck
+ local featureorder=specification.order or { feature }
+ local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
+ local nofsteps=0
+ local steps={}
+ local sublookups=specification.lookups
+ local category=nil
+ checkflags(specification,resources)
+ if sublookups then
+ local s={}
+ for i=1,#sublookups do
+ local specification=sublookups[i]
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nofsteps=0
+ local steps={}
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ checkmerge(specification)
+ checksteps(specification)
+ s[i]={
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ flags=featureflags,
+ type=types[featuretype],
+ }
+ end
+ sublookups=s
+ end
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ category="gsub"
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ category="gsub"
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ category="gsub"
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ category="gsub"
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ category="gpos"
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ category="gpos"
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ category="gpos"
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ elseif featuretype=="chainsubstitution" then
+ category="gsub"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ elseif featuretype=="chainposition" then
+ category="gpos"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ else
+ report_otf("not registering feature %a, unknown category",feature)
+ return
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ if nofsteps>0 then
+ for k,v in next,askedfeatures do
+ if v[1] then
+ askedfeatures[k]=tohash(v)
+ end
+ end
+ if featureflags[1] then featureflags[1]="mark" end
+ if featureflags[2] then featureflags[2]="ligature" end
+ if featureflags[3] then featureflags[3]="base" end
+ local steptype=types[featuretype]
+ local sequence={
+ chain=featurechain,
+ features={ [feature]=askedfeatures },
+ flags=featureflags,
+ name=feature,
+ order=featureorder,
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ type=steptype,
+ }
+ checkflags(sequence,resources)
+ checkmerge(sequence)
+ checksteps(sequence)
+ local first,last=getrange(sequences,category)
+ inject(specification,sequences,sequence,first,last,category,feature)
+ local features=fontfeatures[category]
+ if not features then
+ features={}
+ fontfeatures[category]=features
+ end
+ local k=features[feature]
+ if not k then
+ k={}
+ features[feature]=k
+ end
+ for script,languages in next,askedfeatures do
+ local kk=k[script]
+ if not kk then
+ kk={}
+ k[script]=kk
+ end
+ for language,value in next,languages do
+ kk[language]=value
+ end
+ end
+ end
+ end
+ end
+ if trace_loading then
+ report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
+ end
+end
+otf.enhancers.addfeature=addfeature
+local extrafeatures={}
+local knownfeatures={}
+function otf.addfeature(name,specification)
+ if type(name)=="table" then
+ specification=name
+ end
+ if type(specification)~="table" then
+ report_otf("invalid feature specification, no valid table")
+ return
+ end
+ specification,name=validspecification(specification,name)
+ if name and specification then
+ local slot=knownfeatures[name]
+ if not slot then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ elseif specification.overload==false then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ else
+ end
+ specification.name=name
+ extrafeatures[slot]=specification
+ end
+end
+local function enhance(data,filename,raw)
+ for slot=1,#extrafeatures do
+ local specification=extrafeatures[slot]
+ addfeature(data,specification.name,specification)
+ end
+end
+otf.enhancers.enhance=enhance
+otf.enhancers.register("check extra features",enhance)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
if not modules then modules={} end modules ['font-osd']={
version=1.001,
comment="companion to font-ini.mkiv",
@@ -32417,9 +33327,6 @@ if not modules then modules={} end modules ['font-ocl']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then
- return
-end
local tostring,tonumber,next=tostring,tonumber,next
local round,max=math.round,math.round
local gsub,find=string.gsub,string.find
@@ -32487,7 +33394,7 @@ local function convert(t,k)
t[k]=v
return v
end
-local start={ "pdf","mode","font" }
+local mode={ "pdf","mode","font" }
local push={ "pdf","page","q" }
local pop={ "pdf","page","Q" }
local function initializeoverlay(tfmdata,kind,value)
@@ -32532,7 +33439,7 @@ local function initializeoverlay(tfmdata,kind,value)
local s=#colorlist
local goback=w~=0 and leftcommand[w] or nil
local t={
- start,
+ mode,
not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) },
push,
}
@@ -32656,20 +33563,15 @@ do
local loaddata=io.loaddata
local savedata=io.savedata
local remove=os.remove
- if context and xml.convert then
- local xmlconvert=xml.convert
- local xmlfirst=xml.first
- function otfsvg.filterglyph(entry,index)
- local svg=xmlconvert(entry.data)
- local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']")
- local data=root and tostring(root)
- return data
- end
- else
+if context then
+
+--removed
+
+else
function otfsvg.filterglyph(entry,index)
return entry.data
end
- end
+end
local runner=sandbox and sandbox.registerrunner {
name="otfsvg",
program="inkscape",
@@ -32682,6 +33584,14 @@ do
return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w")
end
end
+ local new=nil
+ local function inkscapeformat(suffix)
+ if new==nil then
+ new=os.resultof("inkscape --version") or ""
+ new=new=="" or not find(new,"Inkscape%s*0")
+ end
+ return new and "filename" or suffix
+ end
function otfsvg.topdf(svgshapes,tfmdata)
local pdfshapes={}
local inkscape=runner()
@@ -32690,7 +33600,7 @@ do
local nofshapes=#svgshapes
local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"]
local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"]
- local f_convert=formatters["%s --export-pdf=%s\n"]
+ local f_convert=formatters["%s --export-%s=%s\n"]
local filterglyph=otfsvg.filterglyph
local nofdone=0
local processed={}
@@ -32704,7 +33614,7 @@ do
local svgfile=f_svgfile(index)
local pdffile=f_pdffile(index)
savedata(svgfile,data)
- inkscape:write(f_convert(svgfile,pdffile))
+ inkscape:write(f_convert(svgfile,inkscapeformat("pdf"),pdffile))
processed[index]=true
nofdone=nofdone+1
if nofdone%25==0 then
@@ -32893,767 +33803,9 @@ end -- closure
do -- begin closure to overcome local limits and interference
-if not modules then modules={} end modules ['font-otc']={
- 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 insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash
-local type,next,tonumber=type,next,tonumber
-local lpegmatch=lpeg.match
-local utfbyte,utflen=utf.byte,utf.len
-local sortedhash=table.sortedhash
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
-local report_otf=logs.reporter("fonts","otf loading")
-local fonts=fonts
-local otf=fonts.handlers.otf
-local registerotffeature=otf.features.register
-local setmetatableindex=table.setmetatableindex
-local fonthelpers=fonts.helpers
-local checkmerge=fonthelpers.checkmerge
-local checkflags=fonthelpers.checkflags
-local checksteps=fonthelpers.checksteps
-local normalized={
- substitution="substitution",
- single="substitution",
- ligature="ligature",
- alternate="alternate",
- multiple="multiple",
- kern="kern",
- pair="pair",
- single="single",
- chainsubstitution="chainsubstitution",
- chainposition="chainposition",
-}
-local types={
- substitution="gsub_single",
- ligature="gsub_ligature",
- alternate="gsub_alternate",
- multiple="gsub_multiple",
- kern="gpos_pair",
- pair="gpos_pair",
- single="gpos_single",
- chainsubstitution="gsub_contextchain",
- chainposition="gpos_contextchain",
-}
-local names={
- gsub_single="gsub",
- gsub_multiple="gsub",
- gsub_alternate="gsub",
- gsub_ligature="gsub",
- gsub_context="gsub",
- gsub_contextchain="gsub",
- gsub_reversecontextchain="gsub",
- gpos_single="gpos",
- gpos_pair="gpos",
- gpos_cursive="gpos",
- gpos_mark2base="gpos",
- gpos_mark2ligature="gpos",
- gpos_mark2mark="gpos",
- gpos_context="gpos",
- gpos_contextchain="gpos",
-}
-setmetatableindex(types,function(t,k) t[k]=k return k end)
-local everywhere={ ["*"]={ ["*"]=true } }
-local noflags={ false,false,false,false }
-local function getrange(sequences,category)
- local count=#sequences
- local first=nil
- local last=nil
- for i=1,count do
- local t=sequences[i].type
- if t and names[t]==category then
- if not first then
- first=i
- end
- last=i
- end
- end
- return first or 1,last or count
-end
-local function validspecification(specification,name)
- local dataset=specification.dataset
- if dataset then
- elseif specification[1] then
- dataset=specification
- specification={ dataset=dataset }
- else
- dataset={ { data=specification.data } }
- specification.data=nil
- specification.dataset=dataset
- end
- local first=dataset[1]
- if first then
- first=first.data
- end
- if not first then
- report_otf("invalid feature specification, no dataset")
- return
- end
- if type(name)~="string" then
- name=specification.name or first.name
- end
- if type(name)~="string" then
- report_otf("invalid feature specification, no name")
- return
- end
- local n=#dataset
- if n>0 then
- for i=1,n do
- setmetatableindex(dataset[i],specification)
- end
- return specification,name
- end
-end
-local function addfeature(data,feature,specifications)
- if not specifications then
- report_otf("missing specification")
- return
- end
- local descriptions=data.descriptions
- local resources=data.resources
- local features=resources.features
- local sequences=resources.sequences
- if not features or not sequences then
- report_otf("missing specification")
- return
- end
- local alreadydone=resources.alreadydone
- if not alreadydone then
- alreadydone={}
- resources.alreadydone=alreadydone
- end
- if alreadydone[specifications] then
- return
- else
- alreadydone[specifications]=true
- end
- local fontfeatures=resources.features or everywhere
- local unicodes=resources.unicodes
- local splitter=lpeg.splitter(" ",unicodes)
- local done=0
- local skip=0
- local aglunicodes=false
- local privateslot=fonthelpers.privateslot
- local specifications=validspecification(specifications,feature)
- if not specifications then
- return
- end
- local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1)
- local function tounicode(code)
- if not code then
- return
- end
- if type(code)=="number" then
- return code
- end
- local u=unicodes[code]
- if u then
- return u
- end
- if utflen(code)==1 then
- u=utfbyte(code)
- if u then
- return u
- end
- end
- if privateslot then
- u=privateslot(code)
- if u then
- return u
- end
- end
- local u=lpegmatch(p,code)
- if u then
- return u
- end
- if not aglunicodes then
- aglunicodes=fonts.encodings.agl.unicodes
- end
- local u=aglunicodes[code]
- if u then
- return u
- end
- end
- local coverup=otf.coverup
- local coveractions=coverup.actions
- local stepkey=coverup.stepkey
- local register=coverup.register
- local function prepare_substitution(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- else
- if type(replacement)=="table" then
- replacement=replacement[1]
- end
- replacement=tounicode(replacement)
- if replacement and (nocheck or descriptions[replacement]) then
- cover(coverage,unicode,replacement)
- done=done+1
- else
- skip=skip+1
- end
- end
- end
- return coverage
- end
- local function prepare_alternate(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- elseif type(replacement)=="table" then
- local r={}
- for i=1,#replacement do
- local u=tounicode(replacement[i])
- r[i]=(nocheck or descriptions[u]) and u or unicode
- end
- cover(coverage,unicode,r)
- done=done+1
- else
- local u=tounicode(replacement)
- if u then
- cover(coverage,unicode,{ u })
- done=done+1
- else
- skip=skip+1
- end
- end
- end
- return coverage
- end
- local function prepare_multiple(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- elseif type(replacement)=="table" then
- local r={}
- local n=0
- for i=1,#replacement do
- local u=tounicode(replacement[i])
- if nocheck or descriptions[u] then
- n=n+1
- r[n]=u
- end
- end
- if n>0 then
- cover(coverage,unicode,r)
- done=done+1
- else
- skip=skip+1
- end
- else
- local u=tounicode(replacement)
- if u then
- cover(coverage,unicode,{ u })
- done=done+1
- else
- skip=skip+1
- end
- end
- end
- return coverage
- end
- local function prepare_ligature(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,ligature in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- else
- if type(ligature)=="string" then
- ligature={ lpegmatch(splitter,ligature) }
- end
- local present=true
- for i=1,#ligature do
- local l=ligature[i]
- local u=tounicode(l)
- if nocheck or descriptions[u] then
- ligature[i]=u
- else
- present=false
- break
- end
- end
- if present then
- cover(coverage,unicode,ligature)
- done=done+1
- else
- skip=skip+1
- end
- end
- end
- return coverage
- end
- local function resetspacekerns()
- data.properties.hasspacekerns=true
- data.resources .spacekerns=nil
- end
- local function prepare_kern(list,featuretype)
- local coverage={}
- local cover=coveractions[featuretype]
- local isspace=false
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if description and type(replacement)=="table" then
- local r={}
- for k,v in next,replacement do
- local u=tounicode(k)
- if u then
- r[u]=v
- if u==32 then
- isspace=true
- end
- end
- end
- if next(r) then
- cover(coverage,unicode,r)
- done=done+1
- if unicode==32 then
- isspace=true
- end
- else
- skip=skip+1
- end
- else
- skip=skip+1
- end
- end
- if isspace then
- resetspacekerns()
- end
- return coverage
- end
- local function prepare_pair(list,featuretype)
- local coverage={}
- local cover=coveractions[featuretype]
- if cover then
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if description and type(replacement)=="table" then
- local r={}
- for k,v in next,replacement do
- local u=tounicode(k)
- if u then
- r[u]=v
- if u==32 then
- isspace=true
- end
- end
- end
- if next(r) then
- cover(coverage,unicode,r)
- done=done+1
- if unicode==32 then
- isspace=true
- end
- else
- skip=skip+1
- end
- else
- skip=skip+1
- end
- end
- if isspace then
- resetspacekerns()
- end
- else
- report_otf("unknown cover type %a",featuretype)
- end
- return coverage
- end
- local prepare_single=prepare_pair
- local function prepare_chain(list,featuretype,sublookups)
- local rules=list.rules
- local coverage={}
- if rules then
- local rulehash={}
- local rulesize=0
- local lookuptype=types[featuretype]
- for nofrules=1,#rules do
- local rule=rules[nofrules]
- local current=rule.current
- local before=rule.before
- local after=rule.after
- local replacements=rule.replacements or false
- local sequence={}
- local nofsequences=0
- if before then
- for n=1,#before do
- nofsequences=nofsequences+1
- sequence[nofsequences]=before[n]
- end
- end
- local start=nofsequences+1
- for n=1,#current do
- nofsequences=nofsequences+1
- sequence[nofsequences]=current[n]
- end
- local stop=nofsequences
- if after then
- for n=1,#after do
- nofsequences=nofsequences+1
- sequence[nofsequences]=after[n]
- end
- end
- local lookups=rule.lookups or false
- local subtype=nil
- if lookups and sublookups then
- for k,v in sortedhash(lookups) do
- local t=type(v)
- if t=="table" then
- for i=1,#v do
- local vi=v[i]
- if type(vi)~="table" then
- v[i]={ vi }
- end
- end
- elseif t=="number" then
- local lookup=sublookups[v]
- if lookup then
- lookups[k]={ lookup }
- if not subtype then
- subtype=lookup.type
- end
- elseif v==0 then
- lookups[k]={ { type="gsub_remove" } }
- else
- lookups[k]=false
- end
- else
- lookups[k]=false
- end
- end
- end
- if nofsequences>0 then
- local hashed={}
- for i=1,nofsequences do
- local t={}
- local s=sequence[i]
- for i=1,#s do
- local u=tounicode(s[i])
- if u then
- t[u]=true
- end
- end
- hashed[i]=t
- end
- sequence=hashed
- rulesize=rulesize+1
- rulehash[rulesize]={
- nofrules,
- lookuptype,
- sequence,
- start,
- stop,
- lookups,
- replacements,
- subtype,
- }
- for unic in sortedhash(sequence[start]) do
- local cu=coverage[unic]
- if not cu then
- coverage[unic]=rulehash
- end
- end
- sequence.n=nofsequences
- end
- end
- rulehash.n=rulesize
- end
- return coverage
- end
- local dataset=specifications.dataset
- local function report(name,category,position,first,last,sequences)
- report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
- name,category,position,first,last,1,#sequences)
- end
- local function inject(specification,sequences,sequence,first,last,category,name)
- local position=specification.position or false
- if not position then
- position=specification.prepend
- if position==true then
- if trace_loading then
- report(name,category,first,first,last,sequences)
- end
- insert(sequences,first,sequence)
- return
- end
- end
- if not position then
- position=specification.append
- if position==true then
- if trace_loading then
- report(name,category,last+1,first,last,sequences)
- end
- insert(sequences,last+1,sequence)
- return
- end
- end
- local kind=type(position)
- if kind=="string" then
- local index=false
- for i=first,last do
- local s=sequences[i]
- local f=s.features
- if f then
- for k in sortedhash(f) do
- if k==position then
- index=i
- break
- end
- end
- if index then
- break
- end
- end
- end
- if index then
- position=index
- else
- position=last+1
- end
- elseif kind=="number" then
- if position<0 then
- position=last-position+1
- end
- if position>last then
- position=last+1
- elseif position<first then
- position=first
- end
- else
- position=last+1
- end
- if trace_loading then
- report(name,category,position,first,last,sequences)
- end
- insert(sequences,position,sequence)
- end
- for s=1,#dataset do
- local specification=dataset[s]
- local valid=specification.valid
- local feature=specification.name or feature
- if not feature or feature=="" then
- report_otf("no valid name given for extra feature")
- elseif not valid or valid(data,specification,feature) then
- local initialize=specification.initialize
- if initialize then
- specification.initialize=initialize(specification,data) and initialize or nil
- end
- local askedfeatures=specification.features or everywhere
- local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
- local featuretype=normalized[specification.type or "substitution"] or "substitution"
- local featureflags=specification.flags or noflags
- local nocheck=specification.nocheck
- local featureorder=specification.order or { feature }
- local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
- local nofsteps=0
- local steps={}
- local sublookups=specification.lookups
- local category=nil
- checkflags(specification,resources)
- if sublookups then
- local s={}
- for i=1,#sublookups do
- local specification=sublookups[i]
- local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
- local featuretype=normalized[specification.type or "substitution"] or "substitution"
- local featureflags=specification.flags or noflags
- local nofsteps=0
- local steps={}
- for i=1,#askedsteps do
- local list=askedsteps[i]
- local coverage=nil
- local format=nil
- if featuretype=="substitution" then
- coverage=prepare_substitution(list,featuretype,nocheck)
- elseif featuretype=="ligature" then
- coverage=prepare_ligature(list,featuretype,nocheck)
- elseif featuretype=="alternate" then
- coverage=prepare_alternate(list,featuretype,nocheck)
- elseif featuretype=="multiple" then
- coverage=prepare_multiple(list,featuretype,nocheck)
- elseif featuretype=="kern" or featuretype=="move" then
- format=featuretype
- coverage=prepare_kern(list,featuretype)
- elseif featuretype=="pair" then
- format="pair"
- coverage=prepare_pair(list,featuretype)
- elseif featuretype=="single" then
- format="single"
- coverage=prepare_single(list,featuretype)
- end
- if coverage and next(coverage) then
- nofsteps=nofsteps+1
- steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
- end
- end
- checkmerge(specification)
- checksteps(specification)
- s[i]={
- [stepkey]=steps,
- nofsteps=nofsteps,
- flags=featureflags,
- type=types[featuretype],
- }
- end
- sublookups=s
- end
- for i=1,#askedsteps do
- local list=askedsteps[i]
- local coverage=nil
- local format=nil
- if featuretype=="substitution" then
- category="gsub"
- coverage=prepare_substitution(list,featuretype,nocheck)
- elseif featuretype=="ligature" then
- category="gsub"
- coverage=prepare_ligature(list,featuretype,nocheck)
- elseif featuretype=="alternate" then
- category="gsub"
- coverage=prepare_alternate(list,featuretype,nocheck)
- elseif featuretype=="multiple" then
- category="gsub"
- coverage=prepare_multiple(list,featuretype,nocheck)
- elseif featuretype=="kern" or featuretype=="move" then
- category="gpos"
- format=featuretype
- coverage=prepare_kern(list,featuretype)
- elseif featuretype=="pair" then
- category="gpos"
- format="pair"
- coverage=prepare_pair(list,featuretype)
- elseif featuretype=="single" then
- category="gpos"
- format="single"
- coverage=prepare_single(list,featuretype)
- elseif featuretype=="chainsubstitution" then
- category="gsub"
- coverage=prepare_chain(list,featuretype,sublookups)
- elseif featuretype=="chainposition" then
- category="gpos"
- coverage=prepare_chain(list,featuretype,sublookups)
- else
- report_otf("not registering feature %a, unknown category",feature)
- return
- end
- if coverage and next(coverage) then
- nofsteps=nofsteps+1
- steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
- end
- end
- if nofsteps>0 then
- for k,v in next,askedfeatures do
- if v[1] then
- askedfeatures[k]=tohash(v)
- end
- end
- if featureflags[1] then featureflags[1]="mark" end
- if featureflags[2] then featureflags[2]="ligature" end
- if featureflags[3] then featureflags[3]="base" end
- local steptype=types[featuretype]
- local sequence={
- chain=featurechain,
- features={ [feature]=askedfeatures },
- flags=featureflags,
- name=feature,
- order=featureorder,
- [stepkey]=steps,
- nofsteps=nofsteps,
- type=steptype,
- }
- checkflags(sequence,resources)
- checkmerge(sequence)
- checksteps(sequence)
- local first,last=getrange(sequences,category)
- inject(specification,sequences,sequence,first,last,category,feature)
- local features=fontfeatures[category]
- if not features then
- features={}
- fontfeatures[category]=features
- end
- local k=features[feature]
- if not k then
- k={}
- features[feature]=k
- end
- for script,languages in next,askedfeatures do
- local kk=k[script]
- if not kk then
- kk={}
- k[script]=kk
- end
- for language,value in next,languages do
- kk[language]=value
- end
- end
- end
- end
- end
- if trace_loading then
- report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
- end
-end
-otf.enhancers.addfeature=addfeature
-local extrafeatures={}
-local knownfeatures={}
-function otf.addfeature(name,specification)
- if type(name)=="table" then
- specification=name
- end
- if type(specification)~="table" then
- report_otf("invalid feature specification, no valid table")
- return
- end
- specification,name=validspecification(specification,name)
- if name and specification then
- local slot=knownfeatures[name]
- if not slot then
- slot=#extrafeatures+1
- knownfeatures[name]=slot
- elseif specification.overload==false then
- slot=#extrafeatures+1
- knownfeatures[name]=slot
- else
- end
- specification.name=name
- extrafeatures[slot]=specification
- end
-end
-local function enhance(data,filename,raw)
- for slot=1,#extrafeatures do
- local specification=extrafeatures[slot]
- addfeature(data,specification.name,specification)
- end
-end
-otf.enhancers.enhance=enhance
-otf.enhancers.register("check extra features",enhance)
-
-end -- closure
-
-do -- begin closure to overcome local limits and interference
-
if not modules then modules={} end modules ['font-onr']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -34028,6 +34180,7 @@ do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-one']={
version=1.001,
+ optimize=true,
comment="companion to font-ini.mkiv",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright="PRAGMA ADE / ConTeXt Development Team",
@@ -35792,8 +35945,9 @@ function definers.read(specification,size,id)
report_defining("already hashed: %s",hash)
end
else
- tfmdata=definers.loadfont(specification)
+ tfmdata=definers.loadfont(specification)
if tfmdata then
+ tfmdata.original=specification.specification
if trace_defining then
report_defining("loaded and hashed: %s",hash)
end
@@ -35830,6 +35984,373 @@ end -- closure
do -- begin closure to overcome local limits and interference
+if not modules then modules={} end modules ['font-shp']={
+ 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 tonumber,next=tonumber,next
+local concat=table.concat
+local formatters=string.formatters
+local otf=fonts.handlers.otf
+local afm=fonts.handlers.afm
+local pfb=fonts.handlers.pfb
+local hashes=fonts.hashes
+local identifiers=hashes.identifiers
+local version=0.009
+local shapescache=containers.define("fonts","shapes",version,true)
+local streamscache=containers.define("fonts","streams",version,true)
+local compact_streams=false
+directives.register("fonts.streams.compact",function(v) compact_streams=v end)
+local function packoutlines(data,makesequence)
+ local subfonts=data.subfonts
+ if subfonts then
+ for i=1,#subfonts do
+ packoutlines(subfonts[i],makesequence)
+ end
+ return
+ end
+ local common=data.segments
+ if common then
+ return
+ end
+ local glyphs=data.glyphs
+ if not glyphs then
+ return
+ end
+ if makesequence then
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ local sequence={}
+ local nofsequence=0
+ for i=1,#segments do
+ local segment=segments[i]
+ local nofsegment=#segment
+ nofsequence=nofsequence+1
+ sequence[nofsequence]=segment[nofsegment]
+ for i=1,nofsegment-1 do
+ nofsequence=nofsequence+1
+ sequence[nofsequence]=segment[i]
+ end
+ end
+ glyph.sequence=sequence
+ glyph.segments=nil
+ end
+ end
+ end
+ else
+ local hash={}
+ local common={}
+ local reverse={}
+ local last=0
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ for i=1,#segments do
+ local h=concat(segments[i]," ")
+ hash[h]=(hash[h] or 0)+1
+ end
+ end
+ end
+ end
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ for i=1,#segments do
+ local segment=segments[i]
+ local h=concat(segment," ")
+ if hash[h]>1 then
+ local idx=reverse[h]
+ if not idx then
+ last=last+1
+ reverse[h]=last
+ common[last]=segment
+ idx=last
+ end
+ segments[i]=idx
+ end
+ end
+ end
+ end
+ end
+ if last>0 then
+ data.segments=common
+ end
+ end
+end
+local function unpackoutlines(data)
+ local subfonts=data.subfonts
+ if subfonts then
+ for i=1,#subfonts do
+ unpackoutlines(subfonts[i])
+ end
+ return
+ end
+ local common=data.segments
+ if not common then
+ return
+ end
+ local glyphs=data.glyphs
+ if not glyphs then
+ return
+ end
+ for index=0,#glyphs do
+ local glyph=glyphs[index]
+ if glyph then
+ local segments=glyph.segments
+ if segments then
+ for i=1,#segments do
+ local c=common[segments[i]]
+ if c then
+ segments[i]=c
+ end
+ end
+ end
+ end
+ end
+ data.segments=nil
+end
+local readers=otf.readers
+local cleanname=otf.readers.helpers.cleanname
+local function makehash(filename,sub,instance)
+ local name=cleanname(file.basename(filename))
+ if instance then
+ return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance))
+ else
+ return formatters["%s-%s"] (name,sub or 0)
+ end
+end
+local function loadoutlines(cache,filename,sub,instance)
+ local base=file.basename(filename)
+ local name=file.removesuffix(base)
+ local kind=file.suffix(filename)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ local sub=tonumber(sub)
+ if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then
+ local hash=makehash(filename,sub,instance)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ data=otf.readers.loadshapes(filename,sub,instance)
+ if data then
+ data.size=size
+ data.format=data.format or (kind=="otf" and "opentype") or "truetype"
+ data.time=time
+ packoutlines(data)
+ containers.write(cache,hash,data)
+ data=containers.read(cache,hash)
+ end
+ end
+ unpackoutlines(data)
+ elseif size>0 and (kind=="pfb") then
+ local hash=containers.cleanname(base)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ data=afm.readers.loadshapes(filename)
+ if data then
+ data.size=size
+ data.format="type1"
+ data.time=time
+ packoutlines(data)
+ containers.write(cache,hash,data)
+ data=containers.read(cache,hash)
+ end
+ end
+ unpackoutlines(data)
+ else
+ data={
+ filename=filename,
+ size=0,
+ time=time,
+ format="unknown",
+ units=1000,
+ glyphs={}
+ }
+ end
+ return data
+end
+local function cachethem(cache,hash,data)
+ containers.write(cache,hash,data,compact_streams)
+ return containers.read(cache,hash)
+end
+local function loadstreams(cache,filename,sub,instance)
+ local base=file.basename(filename)
+ local name=file.removesuffix(base)
+ local kind=file.suffix(filename)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ local sub=tonumber(sub)
+ if size>0 and (kind=="otf" or kind=="ttf" or kind=="ttc") then
+ local hash=makehash(filename,sub,instance)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ data=otf.readers.loadshapes(filename,sub,instance,true)
+ if data then
+ local glyphs=data.glyphs
+ local streams={}
+ if glyphs then
+ for i=0,#glyphs do
+ local glyph=glyphs[i]
+ if glyph then
+ streams[i]=glyph.stream or ""
+ else
+ streams[i]=""
+ end
+ end
+ end
+ data.streams=streams
+ data.glyphs=nil
+ data.size=size
+ data.format=data.format or (kind=="otf" and "opentype") or "truetype"
+ data.time=time
+ data=cachethem(cache,hash,data)
+ end
+ end
+ elseif size>0 and (kind=="pfb") then
+ local hash=makehash(filename,sub,instance)
+ data=containers.read(cache,hash)
+ if not data or data.time~=time or data.size~=size then
+ local names,encoding,streams,metadata=pfb.loadvector(filename,false,true)
+ if streams then
+ local fontbbox=metadata.fontbbox or { 0,0,0,0 }
+ for i=0,#streams do
+ streams[i]=streams[i].stream or "\14"
+ end
+ data={
+ filename=filename,
+ size=size,
+ time=time,
+ format="type1",
+ streams=streams,
+ fontheader={
+ fontversion=metadata.version,
+ units=1000,
+ xmin=fontbbox[1],
+ ymin=fontbbox[2],
+ xmax=fontbbox[3],
+ ymax=fontbbox[4],
+ },
+ horizontalheader={
+ ascender=0,
+ descender=0,
+ },
+ maximumprofile={
+ nofglyphs=#streams+1,
+ },
+ names={
+ copyright=metadata.copyright,
+ family=metadata.familyname,
+ fullname=metadata.fullname,
+ fontname=metadata.fontname,
+ subfamily=metadata.subfamilyname,
+ trademark=metadata.trademark,
+ notice=metadata.notice,
+ version=metadata.version,
+ },
+ cffinfo={
+ familyname=metadata.familyname,
+ fullname=metadata.fullname,
+ italicangle=metadata.italicangle,
+ monospaced=metadata.isfixedpitch and true or false,
+ underlineposition=metadata.underlineposition,
+ underlinethickness=metadata.underlinethickness,
+ weight=metadata.weight,
+ },
+ }
+ data=cachethem(cache,hash,data)
+ end
+ end
+ else
+ data={
+ filename=filename,
+ size=0,
+ time=time,
+ format="unknown",
+ streams={}
+ }
+ end
+ return data
+end
+local loadedshapes={}
+local loadedstreams={}
+local function loadoutlinedata(fontdata,streams)
+ local properties=fontdata.properties
+ local filename=properties.filename
+ local subindex=fontdata.subindex
+ local instance=properties.instance
+ local hash=makehash(filename,subindex,instance)
+ local loaded=loadedshapes[hash]
+ if not loaded then
+ loaded=loadoutlines(shapescache,filename,subindex,instance)
+ loadedshapes[hash]=loaded
+ end
+ return loaded
+end
+hashes.shapes=table.setmetatableindex(function(t,k)
+ local f=identifiers[k]
+ if f then
+ return loadoutlinedata(f)
+ end
+end)
+local function getstreamhash(fontid)
+ local fontdata=identifiers[fontid]
+ if fontdata then
+ local properties=fontdata.properties
+ return makehash(properties.filename,properties.subfont,properties.instance)
+ end
+end
+local function loadstreamdata(fontdata)
+ local properties=fontdata.properties
+ local shared=fontdata.shared
+ local rawdata=shared and shared.rawdata
+ local metadata=rawdata and rawdata.metadata
+ local filename=properties.filename
+ local subindex=metadata and metadata.subfontindex
+ local instance=properties.instance
+ local hash=makehash(filename,subindex,instance)
+ local loaded=loadedstreams[hash]
+ if not loaded then
+ loaded=loadstreams(streamscache,filename,subindex,instance)
+ loadedstreams[hash]=loaded
+ end
+ return loaded
+end
+hashes.streams=table.setmetatableindex(function(t,k)
+ local f=identifiers[k]
+ if f then
+ return loadstreamdata(f)
+ end
+end)
+otf.loadoutlinedata=loadoutlinedata
+otf.loadstreamdata=loadstreamdata
+otf.loadshapes=loadshapes
+otf.getstreamhash=getstreamhash
+local streams=fonts.hashes.streams
+callback.register("glyph_stream_provider",function(id,index,mode)
+ if id>0 then
+ local streams=streams[id].streams
+ if streams then
+ return streams[index] or ""
+ end
+ end
+ return ""
+end)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
if not modules then modules={} end modules ['luatex-fonts-def']={
version=1.001,
comment="companion to luatex-*.tex",
@@ -36376,41 +36897,6 @@ if context then
--removed
end
-if context then
- local letter=characters.is_letter
- local always=true
- local function collapseitalics(tfmdata,key,value)
- local threshold=value==true and 100 or tonumber(value)
- if threshold and threshold>0 then
- if threshold>100 then
- threshold=100
- end
- for unicode,data in next,tfmdata.characters do
- if always or letter[unicode] or letter[data.unicode] then
- local italic=data.italic
- if italic and italic~=0 then
- local width=data.width
- if width and width~=0 then
- local delta=threshold*italic/100
- data.width=width+delta
- data.italic=italic-delta
- end
- end
- end
- end
- end
- end
- local dimensions_specification={
- name="collapseitalics",
- description="collapse italics",
- manipulators={
- base=collapseitalics,
- node=collapseitalics,
- }
- }
- registerotffeature(dimensions_specification)
- registerafmfeature(dimensions_specification)
-end
end -- closure
@@ -36647,6 +37133,7 @@ local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze
end
end
end
+local shiftmode=CONTEXTLMTXMODE>0
local function manipulateeffect(tfmdata)
local effect=tfmdata.properties.effect
if effect then
@@ -36668,38 +37155,45 @@ local function manipulateeffect(tfmdata)
local factor=(1+effect.factor)*factor
local hfactor=(1+effect.hfactor)*hfactor
local vfactor=(1+effect.vfactor)*vfactor
- local vshift=vshift~=0 and upcommand[vshift] or false
+ if shiftmode then
+ parameters.hshift=hshift
+ parameters.vshift=vshift
+ else
+ vshift=vshift~=0 and upcommand[vshift] or false
+ hshift=rightcommand[hshift]
+ end
for unicode,character in next,characters do
local oldwidth=character.width
local oldheight=character.height
local olddepth=character.depth
if oldwidth and oldwidth>0 then
character.width=oldwidth+wdelta
- local commands=character.commands
- local hshift=rightcommand[hshift]
- if vshift then
- if commands then
- prependcommands (commands,
- hshift,
- vshift
- )
- else
- character.commands={
- hshift,
- vshift,
- charcommand[unicode]
- }
- end
- else
- if commands then
- prependcommands (commands,
- hshift
- )
+ if not shiftmode then
+ local commands=character.commands
+ if vshift then
+ if commands then
+ prependcommands (commands,
+ hshift,
+ vshift
+ )
+ else
+ character.commands={
+ hshift,
+ vshift,
+ charcommand[unicode]
+ }
+ end
else
- character.commands={
- hshift,
- charcommand[unicode]
- }
+ if commands then
+ prependcommands (commands,
+ hshift
+ )
+ else
+ character.commands={
+ hshift,
+ charcommand[unicode]
+ }
+ end
end
end
end
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-fil.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-fil.lua
index 79af277437b..183f7bea81f 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-fil.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-fil.lua
@@ -1,5 +1,6 @@
if not modules then modules = { } end modules ['util-fil'] = {
version = 1.001,
+ optimize = true,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua
index aba7859c31e..2d3f4d669f1 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua
@@ -1057,76 +1057,44 @@ local format_rest = function(s)
return format("%q",s) -- catches " and \n and such
end
--- local format_extension = function(extensions,f,name)
--- local extension = extensions[name] or "tostring(%s)"
--- local f = tonumber(f) or 1
--- local w = find(extension,"%.%.%.")
--- if f == 0 then
--- if w then
--- extension = gsub(extension,"%.%.%.","")
--- end
--- return extension
--- elseif f == 1 then
--- if w then
--- extension = gsub(extension,"%.%.%.","%%s")
--- end
--- n = n + 1
--- local a = "a" .. n
--- return format(extension,a,a) -- maybe more times?
--- elseif f < 0 then
--- local a = "a" .. (n + f + 1)
--- return format(extension,a,a)
--- else
--- if w then
--- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
--- end
--- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
--- -- cache we don't save much and there are hardly any extensions anyway
--- local t = { }
--- for i=1,f do
--- n = n + 1
--- -- t[#t+1] = "a" .. n
--- t[i] = "a" .. n
--- end
--- return format(extension,unpack(t))
--- end
--- end
-
local format_extension = function(extensions,f,name)
local extension = extensions[name] or "tostring(%s)"
local f = tonumber(f) or 1
local w = find(extension,"%.%.%.")
- if w then
- -- we have a wildcard
- if f == 0 then
+ if f == 0 then
+ if w then
extension = gsub(extension,"%.%.%.","")
- return extension
- elseif f == 1 then
+ end
+ return extension
+ elseif f == 1 then
+ if w then
extension = gsub(extension,"%.%.%.","%%s")
- n = n + 1
- local a = "a" .. n
- return format(extension,a,a) -- maybe more times?
- elseif f < 0 then
+ end
+ n = n + 1
+ local a = "a" .. n
+ return format(extension,a,a) -- maybe more times?
+ elseif f < 0 then
+ if w then
+ -- not supported
+ extension = gsub(extension,"%.%.%.","")
+ return extension
+ else
local a = "a" .. (n + f + 1)
return format(extension,a,a)
- else
- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
- -- cache we don't save much and there are hardly any extensions anyway
- local t = { }
- for i=1,f do
- n = n + 1
- -- t[#t+1] = "a" .. n
- t[i] = "a" .. n
- end
- return format(extension,unpack(t))
end
else
- extension = gsub(extension,"%%s",function()
+ if w then
+ extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ end
+ -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+ -- cache we don't save much and there are hardly any extensions anyway
+ local t = { }
+ for i=1,f do
n = n + 1
- return "a" .. n
- end)
- return extension
+ -- t[#t+1] = "a" .. n
+ t[i] = "a" .. n
+ end
+ return format(extension,unpack(t))
end
end
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua
index 62ef5d57a95..14a66da3591 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua
@@ -6,8 +6,8 @@
local ProvidesLuaModule = {
name = "luaotfload-auxiliary",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / auxiliary functions",
license = "GPL v2.0"
}
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua
index 070fe868c7f..e8a8e996a86 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-colors",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua
index 36bb31dda17..8f04190a434 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua
@@ -7,8 +7,8 @@
local ProvidesLuaModule = {
name = "luaotfload-configuration",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / config file reader",
license = "GPL v2.0"
}
@@ -103,30 +103,31 @@ local valid_resolvers = tabletohash {
"tex", "path", "name", "file", "my"
}
+local base_features = tabletohash {
+ -- Adopt the generic default from HarfBuzz.
+ -- The first line is generally enabled there,
+ -- the second only for horizontal text.
+ -- The third line is luaotfload specific
+ "abvm", "blwm", "ccmp", "locl", "mark", "mkmk", "rlig",
+ "calt", "clig", "curs", "dist", "kern", "liga", "rclt",
+ "itlc",
+}
local feature_presets = {
- arab = tabletohash {
- "ccmp", "locl", "isol", "fina", "fin2",
- "fin3", "medi", "med2", "init", "rlig",
- "calt", "liga", "cswh", "mset", "curs",
- "kern", "mark", "mkmk",
- },
- deva = tabletohash {
- "ccmp", "locl", "init", "nukt", "akhn",
- "rphf", "blwf", "half", "pstf", "vatu",
- "pres", "blws", "abvs", "psts", "haln",
- "calt", "blwm", "abvm", "dist", "kern",
- "mark", "mkmk",
- },
- khmr = tabletohash {
- "ccmp", "locl", "pref", "blwf", "abvf",
- "pstf", "pres", "blws", "abvs", "psts",
- "clig", "calt", "blwm", "abvm", "dist",
- "kern", "mark", "mkmk",
- },
- thai = tabletohash {
- "ccmp", "locl", "liga", "kern", "mark",
- "mkmk",
- },
+ arab = table.merged( tabletohash {
+ "isol", "fina", "fin2", "fin3", "medi", "med2", "init",
+ "cswh", "mset",
+ }, base_features),
+ deva = table.merged( tabletohash {
+ "init", "nukt", "akhn", "rphf", "blwf", "half", "pstf",
+ "vatu", "pres", "blws", "abvs", "psts", "haln",
+ }, base_features),
+ khmr = table.merged( tabletohash {
+ "pref", "blwf", "abvf", "pstf", "pres", "blws", "abvs",
+ "psts",
+ }, base_features),
+ hang = table.merged( tabletohash {
+ "ccmp", "ljmo", "vjmo", "tjmo",
+ }, base_features),
}
--[[doc--
@@ -234,10 +235,7 @@ local default_config = {
},
default_features = {
global = { mode = "node" },
- dflt = tabletohash {
- "ccmp", "locl", "rlig", "liga", "clig",
- "kern", "mark", "mkmk", 'itlc',
- },
+ dflt = base_features,
arab = feature_presets.arab,
syrc = feature_presets.arab,
@@ -260,7 +258,7 @@ local default_config = {
thai = feature_presets.thai,
lao = feature_presets.thai,
- hang = tabletohash { "ccmp", "ljmo", "vjmo", "tjmo", },
+ hang = feature_presets.hang,
},
}
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua
index af123a0296b..6d0bcff414e 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua
@@ -5,8 +5,8 @@
do -- block to avoid to many local variables error
local ProvidesLuaModule = {
name = "luaotfload-database",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -140,9 +140,11 @@ local tonumber = tonumber
local unpack = table.unpack
local fonts = fonts or { }
-local fontshandlers = fonts.handlers or { }
+do
+ local fontshandlers = fonts.handlers or { }
+ fonts.handlers = fontshandlers
+end
local otfhandler = fonts.handlers.otf or { }
-fonts.handlers = fontshandlers
local gzipload = gzip.load
local gzipsave = gzip.save
@@ -176,7 +178,6 @@ local utf8offset = utf8.offset
local context_environment = luaotfload.fontloader
local caches = context_environment.caches
local filebasename = file.basename
-local filecollapsepath = file.collapsepath or file.collapse_path
local filedirname = file.dirname
local fileextname = file.extname
local fileiswritable = file.iswritable
@@ -361,6 +362,7 @@ This is a sketch of the luaotfload db:
type dbobj = {
families : familytable;
+ fontnames : fontnametable;
files : filemap;
status : filestatus;
mappings : fontentry list;
@@ -381,6 +383,11 @@ This is a sketch of the luaotfload db:
default : int; // points into mappings or names
optical : (int, int) list; // design size -> index entry
}
+ and fontnametable = {
+ local : (format, index) hash;
+ texmf : (format, index) hash;
+ system : (format, index) hash;
+ }
and metadata = {
created : string // creation time
formats : string list; // { "otf", "ttf", "ttc" }
@@ -522,24 +529,13 @@ local function load_lua_file (path)
end
--- define locals in scope
-local access_font_index
-local find_closest
-local flush_lookup_cache
-local generate_filedata
local get_font_filter
-local group_modifiers
-local load_names
local lookup_font_name
-local getmetadata
-local order_design_sizes
-local ot_fullinfo
-local read_blacklist
local reload_db
local lookup_fullpath
local save_lookups
local save_names
local set_font_filter
-local t1_fullinfo
local update_names
--- state of the database
@@ -549,7 +545,7 @@ local fonts_reloaded = false
local fuzzy_limit = 1 --- display closest only
--- bool? -> -> bool? -> dbobj option
-load_names = function (dry_run, no_rebuild)
+local function load_names (dry_run, no_rebuild)
local starttime = osgettimeofday ()
local foundname, data = load_lua_file (config.luaotfload.paths.index_path_lua)
@@ -617,12 +613,12 @@ end
--doc]]--
-access_font_index = function ()
+local function access_font_index ()
if not name_index then name_index = load_names () end
return name_index
end
-getmetadata = function ()
+local function getmetadata ()
if not name_index then
name_index = load_names (false, true)
if name_index then return tablefastcopy (name_index.meta) end
@@ -728,9 +724,13 @@ do
local type1_metrics = { "tfm", "ofm", }
-- /MK
-lookup_font_file = function (filename)
+function lookup_font_file (filename)
local found = lookup_filename (filename)
+ if found and not lfsisfile(found) then
+ found = nil
+ end
+
if not found then
local type = file.suffix(filename)
if type ~= "" then
@@ -750,7 +750,7 @@ lookup_font_file = function (filename)
end
if not fonts_reloaded and config.luaotfload.db.update_live == true then
- return reload_db (stringformat ("File not found: %s.", filename),
+ return reload_db (stringformat ("File not found: %q.", filename),
lookup_font_file,
filename)
end
@@ -979,11 +979,8 @@ end
--- int * int * int * int list -> int -> int
local function choose_size (sizes, askedsize)
- local mappings = name_index.mappings
- local exact
local inrange = { } --- distance * index list
local norange = { } --- distance * index list
- local fontname, subfont
if askedsize ~= 0 then
--- firstly, look for an exactly matching design size or
--- matching range
@@ -1041,7 +1038,6 @@ end
--- spec -> string -> string -> int -> string * int * bool
local function lookup_familyname (specification, name, style, askedsize)
local families = name_index.families
- local mappings = name_index.mappings
local candidates = nil
local fallback = true
--- arrow code alert
@@ -1081,21 +1077,25 @@ local function lookup_familyname (specification, name, style, askedsize)
end
local function lookup_fontname (specification, name)
- local mappings = name_index.mappings
- local fallback = nil
- local lastresort = nil
- for i = 1, #mappings do
- local face = mappings [i]
- local typographicsubfamily = face.typographicsubfamily
- local subfamily = face.subfamily
- if face.fontname == name
- or face.fullname == name
- or face.psname == name
- then
- return face.fullpath, face.subfont
+ local fontnames = name_index.fontnames
+ --- arrow code alert
+ for i = 1, #location_precedence do
+ local location = location_precedence [i]
+ local locgroup = fontnames [location]
+ for j = 1, #format_precedence do
+ local format = format_precedence [j]
+ local fmtgroup = locgroup [format]
+ if fmtgroup then
+ local index = fmtgroup [name]
+ if index then
+ local success, resolved, subfont = get_font_file (index)
+ if success then
+ return resolved, subfont
+ end
+ end
+ end
end
end
- return nil, nil
end
local design_size_dimension --- scale asked size if not using bp
@@ -1204,7 +1204,7 @@ end
--doc]]--
--- table -> string * (int | bool)
-lookup_font_name = function (specification)
+function lookup_font_name (specification)
if not name_index then name_index = load_names () end
local name = sanitize_fontname (specification.name)
local style = sanitize_fontname (specification.style) or "r"
@@ -1238,7 +1238,7 @@ lookup_font_name = function (specification)
if not resolved then
if not fonts_reloaded and config.luaotfload.db.update_live == true then
- return reload_db (stringformat ("Font %s not found.",
+ return reload_db (stringformat ("Font %q not found.",
specification.name or "<?>"),
lookup_font_name,
specification)
@@ -1247,7 +1247,7 @@ lookup_font_name = function (specification)
return resolved, subfont
end
-lookup_fullpath = function (fontname, ext) --- getfilename()
+function lookup_fullpath (fontname, ext) --- getfilename()
if not name_index then name_index = load_names () end
local files = name_index.files
local basedata = files.base
@@ -1282,12 +1282,12 @@ end
--- and then re-run the caller with the arg list
--- string -> ('a -> 'a) -> 'a list -> 'a
-reload_db = function (why, caller, ...)
+function reload_db (why, caller, ...)
local namedata = name_index
local formats = tableconcat (namedata.meta.formats, ",")
logreport ("both", 0, "db",
- "Reload initiated (formats: %s); reason: %q.",
+ "Reload initiated (formats: %s); reason: %s",
formats, why)
set_font_filter (formats)
@@ -1350,7 +1350,7 @@ local function delete_dupes (lst)
end
--- string -> int -> bool
-find_closest = function (name, limit)
+local function find_closest (name, limit)
local name = sanitize_fontname (name)
limit = limit or fuzzy_limit
@@ -1671,7 +1671,7 @@ table as returned by the font file reader need to be relocated.
--- string -> int -> bool -> string -> fontentry
-ot_fullinfo = function (filename,
+local function ot_fullinfo (filename,
subfont,
location,
basename,
@@ -1717,7 +1717,7 @@ end
--- string -> int -> bool -> string -> fontentry
-t1_fullinfo = function (filename, _subfont, location, basename, format)
+local function t1_fullinfo (filename, _subfont, location, basename, format)
local sanitized
local metadata = load_font_file (filename)
local fontname = metadata.fontname
@@ -1954,8 +1954,7 @@ do
--- choose a normalization function in advance
--- instead of testing with every call
local os_type, os_name = os.type, os.name
- local filecollapsepath = filecollapsepath
- local lfsreadlink = lfs.readlink
+ local filecollapsepath = file.collapsepath or file.collapse_path
--- windows and dos
if os_type == "windows" or os_type == "msdos" then
@@ -1973,20 +1972,7 @@ do
--doc]]--
else -- posix
- function path_normalize (path)
- local dest = lfsreadlink(path)
- if dest then
- if kpsereadable_file(dest) then
- path = dest
- elseif kpsereadable_file(filejoin(filedirname(path), dest)) then
- path = filejoin(file.dirname(path), dest)
- else
- -- broken symlink?
- end
- end
- path = filecollapsepath(path)
- return path
- end
+ path_normalize = filecollapsepath
end
end
@@ -2056,7 +2042,7 @@ local function create_blacklist (blacklist, whitelist)
end
--- unit -> unit
-read_blacklist = function ()
+local function read_blacklist ()
local files = {
kpselookup ("luaotfload-blacklist.cnf",
{all=true, format="tex"})
@@ -2116,29 +2102,26 @@ do
local current_formats = { }
+ local splitcomma = luaotfload.parsers.splitcomma
function set_font_filter (formats)
if not formats or type (formats) ~= "string" then
return
end
- local splitcomma = luaotfload.parsers and luaotfload.parsers.splitcomma
-
if stringsub (formats, 1, 1) == "+" then -- add
formats = lpegmatch (splitcomma, stringsub (formats, 2))
if formats then
current_formats = tableappend (current_formats, formats)
end
- elseif stringsub (formats, 1, 1) == "-" then -- add
+ elseif stringsub (formats, 1, 1) == "-" then -- remove
formats = lpegmatch (splitcomma, stringsub (formats, 2))
if formats then
local newformats = { }
for i = 1, #current_formats do
local fmt = current_formats[i]
- local include = true
for j = 1, #formats do
if current_formats[i] == formats[j] then
- include = false
goto skip
end
end
@@ -2327,12 +2310,10 @@ local function collect_font_filenames_dir (dirname, location)
return files
end
+local stripslashes = luaotfload.parsers.stripslashes
--- string list -> string list
local function filter_out_pwd (dirs)
local result = { }
- if stripslashes == nil then
- stripslashes = luaotfload.parsers and luaotfload.parsers.stripslashes
- end
local pwd = path_normalize (lpegmatch (stripslashes,
lfscurrentdir ()))
for i = 1, #dirs do
@@ -2414,15 +2395,16 @@ local function get_os_dirs ()
elseif os.type == "windows" or os.type == "msdos" then
local windir = osgetenv("WINDIR")
local appdata = osgetenv("LOCALAPPDATA")
- return { filejoin(windir, 'Fonts'), filejoin(appdata, 'Microsoft/Windows/Fonts') }
+ if chgstrcp and kpse.var_value('command_line_encoding') ~= nil then
+ return { filejoin(windir, 'Fonts'), chgstrcp.syscptoutf8(filejoin(appdata, 'Microsoft/Windows/Fonts')) }
+ else
+ return { filejoin(windir, 'Fonts'), filejoin(appdata, 'Microsoft/Windows/Fonts') }
+ end
else
local fonts_conves = { --- plural, much?
"/usr/local/etc/fonts/fonts.conf",
"/etc/fonts/fonts.conf",
}
- if not luaotfload.parsers then
- logreport ("log", 0, "db", "Fatal: no fonts.conf parser.")
- end
local os_dirs = luaotfload.parsers.read_fonts_conf(fonts_conves, find_files)
return os_dirs
end
@@ -2529,7 +2511,7 @@ local function collect_font_filenames_system ()
end
--- unit -> bool
-flush_lookup_cache = function ()
+local function flush_lookup_cache ()
lookup_cache = { }
collectgarbage "collect"
return true
@@ -2565,7 +2547,7 @@ local function collect_font_filenames_local ()
end
--- fontentry list -> filemap
-generate_filedata = function (mappings)
+local function generate_filedata (mappings)
logreport ("both", 2, "db", "Creating filename map.")
@@ -2965,6 +2947,29 @@ local function collect_families (mappings)
return families
end
+local function collect_fontnames (mappings)
+
+ logreport ("info", 2, "db", "Collecting fontnames.")
+
+ local fontnames = {
+ ["local"] = { },
+ system = { },
+ texmf = { },
+ }
+
+ for i = 1, #mappings do
+ local entry = mappings [i]
+
+ local subtable = get_subtable (fontnames, entry)
+ if entry.fontname then subtable[entry.fontname] = i end
+ if entry.fullname then subtable[entry.fullname] = i end
+ if entry.psname then subtable[entry.psname] = i end
+ end
+
+ collectgarbage "collect"
+ return fontnames
+end
+
--[[doc--
group_modifiers -- For not-quite-bold faces, determine whether
@@ -2979,7 +2984,7 @@ end
local style_categories = { "r", "b", "i", "bi" }
local bold_categories = { "b", "bi" }
-group_modifiers = function (mappings, families)
+local function group_modifiers (mappings, families)
logreport ("info", 2, "db", "Analyzing shapes, weights, and styles.")
for location, location_data in next, families do
for format, format_data in next, location_data do
@@ -3082,7 +3087,7 @@ local function cmp_sizes (a, b)
return a [1] < b [1]
end
-order_design_sizes = function (families)
+local function order_design_sizes (families)
logreport ("info", 2, "db", "Ordering design sizes.")
@@ -3386,7 +3391,7 @@ end
--- dry_dun: don’t write to the db, just scan dirs
--- dbobj? -> bool? -> bool? -> dbobj
-update_names = function (currentnames, force, dry_run)
+function update_names (currentnames, force, dry_run)
local targetnames
local n_new = 0
local n_rem = 0
@@ -3472,15 +3477,17 @@ update_names = function (currentnames, force, dry_run)
targetnames.files = generate_filedata (targetnames.mappings)
--- pass 5: build family lookup table
- targetnames.families = collect_families (targetnames.mappings)
+ targetnames.families = collect_families (targetnames.mappings)
--- pass 6: arrange style and size info
targetnames.families = group_modifiers (targetnames.mappings,
targetnames.families)
-
--- pass 7: order design size tables
targetnames.families = order_design_sizes (targetnames.families)
+ --- pass 8: build family lookup table
+ targetnames.fontnames = collect_fontnames (targetnames.mappings)
+
logreport ("info", 3, "db",
"Rebuilt in %0.f ms.",
1000 * (osgettimeofday () - starttime))
@@ -3509,7 +3516,7 @@ update_names = function (currentnames, force, dry_run)
end
--- unit -> bool
-save_lookups = function ( )
+function save_lookups ( )
local paths = config.luaotfload.paths
local luaname, lucname = paths.lookup_path_lua, paths.lookup_path_luc
if fileiswritable (luaname) and fileiswritable (lucname) then
@@ -3536,7 +3543,7 @@ end
--- save_names() is usually called without the argument
--- dbobj? -> bool * string option
-save_names = function (currentnames)
+function save_names (currentnames)
if not currentnames then
currentnames = name_index
end
@@ -3825,7 +3832,7 @@ return function ()
names.blacklist = blacklist
-- MK Changed to rebuild with case insensitive fallback.
-- Negative version to indicate generation by modified code.
- names.version = -1 --- decrease monotonically
+ names.version = -2 --- decrease monotonically
-- /MK
names.data = nil --- contains the loaded database
names.lookups = nil --- contains the lookup cache
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua
index c90aa0f5bed..be3183cf65a 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua
@@ -7,8 +7,8 @@
local ProvidesLuaModule = {
name = "luaotfload-diagnostics",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload-tool submodule / diagnostics",
license = "GPL v2.0"
}
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua
new file mode 100644
index 00000000000..b57934fdb6d
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua
@@ -0,0 +1,131 @@
+-------------------------------------------------------------------------------
+-- FILE: luaotfload-dvi.lua
+-- DESCRIPTION: part of luaotfload / DVI
+-------------------------------------------------------------------------------
+
+
+local ProvidesLuaModule = {
+ name = "luaotfload-dvi",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / DVI",
+ license = "GPL v2.0",
+ author = "Marcel Krüger",
+ copyright = "Luaotfload Development Team",
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local getfont = font.getfont
+local setfont = node.direct.setfont
+local getdisc = node.direct.getdisc
+local traverse_glyph = node.direct.traverse_glyph
+local traverse_id = node.direct.traverse_id
+local uses_font = node.direct.uses_font
+local define_font = font.define
+local disc_t = node.id'disc'
+
+-- DVI output support
+--
+-- When writing DVI files, we can't assume that the DVI reader has access to our
+-- font dictionaries, so we need an independent representation for our glyphs. The
+-- approach we chose in coordination with the dvisvgm author is to create a DVI font
+-- name which indicates the font filename and some essential backend parameters
+-- (especially otential extend, shrink, embolden, etc. factors) and then use GIDs in
+-- the page stream.
+--
+-- Normally we could easily implement this using virtual fonts, but because we are
+-- dealing with DVI output, LuaTeX is not evaluating virtual fonts by itself.
+-- So instead, we process the shaped output and replace all glyph nodes with glyph
+-- nodes from special fonts which have the characteristics expected brom the DVI reader.
+
+-- mapped_fonts maps fontids from the user to fontids used in the DVI file
+local mapped_fonts = setmetatable({}, {__index = function(t, fid)
+ local font = getfont(fid)
+ local mapped = font.backend_font or false
+ t[fid] = mapped
+ return mapped
+end})
+
+local function process(head, font)
+ local mapping = mapped_fonts[font]
+ if not mapping then return head end
+ local mapped_font = mapping.font
+ for n, c, f in traverse_glyph(head) do if f == font then
+ local mapped = mapping[c]
+ if mapped then setfont(n, mapped_font, mapped) end
+ end end
+ for n in traverse_id(disc_t, head) do if uses_font(n, font) then
+ local pre, post, rep = getdisc(n)
+ for n, c, f in traverse_glyph(pre) do if f == font then
+ local mapped = mapping[c]
+ if mapped then setfont(n, mapped_font, mapped) end
+ end end
+ for n, c, f in traverse_glyph(post) do if f == font then
+ local mapped = mapping[c]
+ if mapped then setfont(n, mapped_font, mapped) end
+ end end
+ for n, c, f in traverse_glyph(rep) do if f == font then
+ local mapped = mapping[c]
+ if mapped then setfont(n, mapped_font, mapped) end
+ end end
+ end end
+end
+local function manipulate(tfmdata, _, dvi_kind)
+ if dvi_kind ~= 'dvisvgm' then
+ texio.write_nl(string.format('WARNING (luaotfload): Unsupported DVI backend %q, falling back to dvisvgm.', dvi_kind))
+ end
+ -- Legacy fonts can be written to the DVI file directly
+ if 2 ~= (tfmdata.encodingbytes or ((tfmdata.format == 'truetype' or tfmdata.format == 'opentype') and 2 or 1)) then
+ return
+ end
+ local newfont = {}
+ for k,v in pairs(tfmdata) do
+ newfont[k] = v
+ end
+ local newchars = {}
+ newfont.characters = newchars
+ local lookup = {}
+ for k,v in pairs(tfmdata.characters) do
+ local newchar = {
+ width = v.width, -- Only width should really be necessary
+ height = v.height,
+ depth = v.depth,
+ }
+ newchars[v.index or k] = newchar
+ lookup[k] = v.index or k
+ end
+ newfont.checksum = string.unpack('>I4', 'LuaF') -- Use a magic checksum such that the reader
+ -- can uniquely identify these fonts.
+ local name = '[' .. newfont.name .. ']:' -- TODO: Why .name? I would have expected .filename
+ if newfont.subfont and newfont.subfont ~= 1 then
+ name = name .. 'index=' .. tostring(math.tointeger(newfont.subfont-1)) .. ';'
+ end
+ if newfont.extend and newfont.extend ~= 1000 then
+ name = name .. 'extend=' .. tostring(math.tointeger(math.round(newfont.extend*65.536))) .. ';'
+ end
+ if newfont.slant and newfont.slant ~= 0 then
+ name = name .. 'slant=' .. tostring(math.tointeger(math.round(newfont.slant*65.536))) .. ';'
+ end
+ if newfont.mode == 2 and newfont.width and newfont.width ~= 0 then
+ name = name .. 'embolden=' .. tostring(math.tointeger(math.round(newfont.width*65.78176))) .. ';'
+ end
+ newfont.name = name:sub(1,-2) -- Stri th trailing : or ;
+ tfmdata.backend_font = lookup
+ lookup.font = define_font(newfont)
+end
+
+fonts.constructors.features.otf.register {
+ name = "dvifont",
+ default = "dvisvgm",
+ manipulators = {
+ node = manipulate,
+ base = manipulate,
+ },
+ processors = {
+ node = process,
+ base = process,
+ },
+}
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua
index 479c485d62c..d1d4e478c82 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua
@@ -5,9 +5,9 @@
local ProvidesLuaModule = {
name = "luaotfload-embolden",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
- description = "luaotfload submodule / color",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / embolden",
license = "GPL v2.0",
author = "Marcel Krüger"
}
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua
index 6218d9caeb0..eee107c7095 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-fallback",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / fallback",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua
index 59fe42da32d..2d83df10ffc 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-features",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / features",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -429,6 +429,13 @@ local function handle_request (specification)
--- investigated it any further (luatex-fonts-ext), so it will
--- just stay here.
features.normal = normalize (request.features)
+ if features.normal.instance then
+ if features.normal.axis then
+ report("term and log", 0, "features", "instance and axis provided, instance will be ignored")
+ else
+ specification.instance = features.normal.instance
+ end
+ end
specification.sub = request.sub or specification.sub or false
local forced_mode = request.features and request.features.mode
@@ -451,6 +458,58 @@ if as_script == true then --- skip the remainder of the file
return
end
+do
+ local helpers = fonts.handlers.otf.readers.helpers
+ local axistofactors = helpers.axistofactors
+ local cleanname = helpers.cleanname
+ local getaxisscale = helpers.getaxisscale
+ local function search(table, term, key_field, value_field)
+ if not table then return end
+ for i=1, #table do
+ local entry = table[i]
+ if cleanname(entry[key_field]) == term then
+ return entry[value_field]
+ end
+ end
+ end
+ function helpers.getfactors(tfmdata, instance) -- `instance` might refer to an `axis` value here
+ assert(instance == true or type(instance) == "string", "Fontloader changed interface of helpers.getfactors. This is a bug, please notify the luaotfload maintainers.")
+ local variabledata = tfmdata.variabledata
+ if not variabledata or instance == "" then return end
+ local instances = variabledata.instances
+ local axis = variabledata.axis
+ local designaxis = variabledata.designaxis
+ local segments = variabledata.segments
+ if not axis then return end
+ local factors = {}
+ if instance == true then
+ for i=1, #axis do
+ local cur = axis[i]
+ local default = cur.default
+ factors[i] = getaxisscale(segments, cur.minimum, default, cur.maximum, default)
+ end
+ return factors
+ end
+ local values = search(instances, instance, "subfamily", "values")
+ if values then
+ for i=1, #axis do
+ local cur = axis[i]
+ factors[i] = getaxisscale(segments, cur.minimum, cur.default, cur.maximum, values[i].value)
+ end
+ return factors
+ end
+ values = axistofactors(instance)
+ for i=1, #axis do
+ local cur = axis[i]
+ local default = cur.default
+ local value = cur.name and values[cur.name] or values[cur.tag]
+ value = tonumber(value) or (value and search(search(designaxis, cur.tag, "tag", "variants"), cleanname(value), "name", "value")) or default
+ factors[i] = getaxisscale(segments, cur.minimum, default, cur.maximum, value)
+ end
+ return factors
+ end
+end
+
-- MK: Added
function fonts.definers.analyze (spec_string, size)
return handle_request {
@@ -602,6 +661,110 @@ do
}
end
+do
+ local function mathfontdimen(tfmdata, _, value)
+ if not next(tfmdata.mathparameters) then return end
+ local parameters = tfmdata.parameters
+ local mathparameters = tfmdata.mathparameters
+ if value == 'xetex' then
+ parameters[10] = mathparameters.ScriptPercentScaleDown
+ parameters[11] = mathparameters.ScriptScriptPercentScaleDown
+ parameters[12] = mathparameters.DelimitedSubFormulaMinHeight
+ parameters[13] = mathparameters.DisplayOperatorMinHeight
+ parameters[14] = mathparameters.MathLeading
+ parameters[15] = mathparameters.AxisHeight
+ parameters[16] = mathparameters.AccentBaseHeight
+ parameters[17] = mathparameters.FlattenedAccentBaseHeight
+ parameters[18] = mathparameters.SubscriptShiftDown
+ parameters[19] = mathparameters.SubscriptTopMax
+ parameters[20] = mathparameters.SubscriptBaselineDropMin
+ parameters[21] = mathparameters.SuperscriptShiftUp
+ parameters[22] = mathparameters.SuperscriptShiftUpCramped
+ parameters[23] = mathparameters.SuperscriptBottomMin
+ parameters[24] = mathparameters.SuperscriptBaselineDropMax
+ parameters[25] = mathparameters.SubSuperscriptGapMin
+ parameters[26] = mathparameters.SuperscriptBottomMaxWithSubscript
+ parameters[27] = mathparameters.SpaceAfterScript
+ parameters[28] = mathparameters.UpperLimitGapMin
+ parameters[29] = mathparameters.UpperLimitBaselineRiseMin
+ parameters[30] = mathparameters.LowerLimitGapMin
+ parameters[31] = mathparameters.LowerLimitBaselineDropMin
+ parameters[32] = mathparameters.StackTopShiftUp
+ parameters[33] = mathparameters.StackTopDisplayStyleShiftUp
+ parameters[34] = mathparameters.StackBottomShiftDown
+ parameters[35] = mathparameters.StackBottomDisplayStyleShiftDown
+ parameters[36] = mathparameters.StackGapMin
+ parameters[37] = mathparameters.StackDisplayStyleGapMin
+ parameters[38] = mathparameters.StretchStackTopShiftUp
+ parameters[39] = mathparameters.StretchStackBottomShiftDown
+ parameters[40] = mathparameters.StretchStackGapAboveMin
+ parameters[41] = mathparameters.StretchStackGapBelowMin
+ parameters[42] = mathparameters.FractionNumeratorShiftUp
+ parameters[43] = mathparameters.FractionNumeratorDisplayStyleShiftUp
+ parameters[44] = mathparameters.FractionDenominatorShiftDown
+ parameters[45] = mathparameters.FractionDenominatorDisplayStyleShiftDown
+ parameters[46] = mathparameters.FractionNumeratorGapMin
+ parameters[47] = mathparameters.FractionNumeratorDisplayStyleGapMin
+ parameters[48] = mathparameters.FractionRuleThickness
+ parameters[49] = mathparameters.FractionDenominatorGapMin
+ parameters[50] = mathparameters.FractionDenominatorDisplayStyleGapMin
+ parameters[51] = mathparameters.SkewedFractionHorizontalGap
+ parameters[52] = mathparameters.SkewedFractionVerticalGap
+ parameters[53] = mathparameters.OverbarVerticalGap
+ parameters[54] = mathparameters.OverbarRuleThickness
+ parameters[55] = mathparameters.OverbarExtraAscender
+ parameters[56] = mathparameters.UnderbarVerticalGap
+ parameters[57] = mathparameters.UnderbarRuleThickness
+ parameters[58] = mathparameters.UnderbarExtraDescender
+ parameters[59] = mathparameters.RadicalVerticalGap
+ parameters[60] = mathparameters.RadicalDisplayStyleVerticalGap
+ parameters[61] = mathparameters.RadicalRuleThickness
+ parameters[62] = mathparameters.RadicalExtraAscender
+ parameters[63] = mathparameters.RadicalKernBeforeDegree
+ parameters[64] = mathparameters.RadicalKernAfterDegree
+ parameters[65] = mathparameters.RadicalDegreeBottomRaisePercent
+ -- parameters[66] = mathparameters.MinConnectorOverlap
+ -- parameters[67] = mathparameters.SubscriptShiftDownWithSuperscript
+ -- parameters[68] = mathparameters.FractionDelimiterSize
+ -- parameters[69] = mathparameters.FractionDelimiterDisplayStyleSize
+ -- parameters[70] = mathparameters.NoLimitSubFactor
+ -- parameters[71] = mathparameters.NoLimitSupFactor
+ elseif value == 'tex2' then
+ parameters[8] = mathparameters.FractionNumeratorDisplayStyleShiftUp
+ parameters[9] = mathparameters.FractionNumeratorShiftUp
+ parameters[10] = mathparameters.StackTopShiftUp
+ parameters[11] = mathparameters.FractionDenominatorDisplayStyleShiftDown
+ parameters[12] = mathparameters.FractionDenominatorShiftDown
+ parameters[13] = mathparameters.SuperscriptShiftUp
+ parameters[14] = mathparameters.SuperscriptShiftUp
+ parameters[15] = mathparameters.SuperscriptShiftUpCramped
+ parameters[16] = mathparameters.SubscriptShiftDown
+ parameters[17] = mathparameters.SubscriptShiftDown
+ parameters[18] = mathparameters.SuperscriptBaselineDropMax
+ parameters[19] = mathparameters.SubscriptBaselineDropMin
+ parameters[20] = mathparameters.FractionDelimiterDisplayStyleSize
+ parameters[21] = mathparameters.FractionDelimiterSize
+ parameters[22] = mathparameters.AxisHeight
+ elseif value == 'tex3' then
+ parameters[8] = mathparameters.Defa
+ parameters[9] = mathparameters.UpperLimitGapMin
+ parameters[10] = mathparameters.LowerLimitGapMin
+ parameters[11] = mathparameters.UpperLimitBaselineRiseMin
+ parameters[12] = mathparameters.LowerLimitBaselineDropMin
+ parameters[13] = 0
+ end
+ end
+ fonts.constructors.features.otf.register {
+ name = 'mathfontdimen',
+ description = 'Set fontdimen values for compatibility with other engines',
+ manipulators = {
+ base = mathfontdimen,
+ -- node = mathfontdimen,
+ -- plug = mathfontdimen,
+ },
+ }
+end
+
return function ()
if not fonts and fonts.handlers then
report ("log", 0, "features",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua
index 1e3a4fff386..b8ab343402d 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua
@@ -6,8 +6,8 @@
local ProvidesLuaModule = {
name = "luaotfload-filelist",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / filelist",
license = "GPL v2.0"
}
@@ -188,26 +188,27 @@ luaotfload.filelist.data =
{ name = "fonts-syn" , ours = nil , ext = ".lua", kind = kind_ignored , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
{ name = "font-vfc" , ours = "font-vfc" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-otr" , ours = "font-otr" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
- { name = "font-oti" , ours = "font-oti" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
- { name = "font-ott" , ours = "font-ott" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-cff" , ours = "font-cff" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-ttf" , ours = "font-ttf" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-dsp" , ours = "font-dsp" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
- { name = "font-oup" , ours = "font-oup" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-oti" , ours = "font-oti" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-ott" , ours = "font-ott" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-otl" , ours = "font-otl" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-oto" , ours = "font-oto" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-otj" , ours = "font-otj" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-oup" , ours = "font-oup" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-ota" , ours = "font-ota" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-ots" , ours = "font-ots" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-otc" , ours = "font-otc" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-osd" , ours = "font-osd" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-ocl" , ours = "font-ocl" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
- { name = "font-otc" , ours = "font-otc" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-onr" , ours = "font-onr" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-one" , ours = "font-one" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-afk" , ours = "font-afk" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "fonts-tfm" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxgene" , ctxpref = "luatex-" },
{ name = "font-lua" , ours = "font-lua" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "font-def" , ours = "font-def" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-shp" , ours = "font-shp" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
{ name = "fonts-def" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
{ name = "fonts-ext" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
{ name = "font-imp-tex" , ours = "font-imp-tex" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
@@ -259,6 +260,7 @@ luaotfload.filelist.data =
{ name = "resolvers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "unicode" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "tounicode" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "dvi" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "characters" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkcharacter" },
{ name = "glyphlist" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkglyphlist" },
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua
index 6c19570ab76..19f5c2082b2 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua
@@ -1,7 +1,7 @@
local ProvidesLuaModule = {
name = "luaotfload-glyphlist",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / autogenerated glyphlist",
copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt",
original = "Adobe Glyph List, version 2.0, September 20, 2002",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua
index 31a92e4aa0c..37ada59d00f 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua
@@ -5,9 +5,9 @@
do -- block to avoid to many local variables error
local ProvidesLuaModule = {
name = "luaotfload-harf-define",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
- description = "luaotfload submodule / database",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / HarfBuzz font loading",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
copyright = "Luaotfload Development Team",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua
index 8e1883e23f8..6759747fbf3 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua
@@ -5,9 +5,9 @@
do -- block to avoid to many local variables error
local ProvidesLuaModule = {
name = "luaotfload-harf-plug",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
- description = "luaotfload submodule / database",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / HarfBuzz shaping",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
copyright = "Luaotfload Development Team",
@@ -18,7 +18,8 @@ do -- block to avoid to many local variables error
end
end
-local hb = luaotfload.harfbuzz
+local hb = luaotfload.harfbuzz
+local logreport = luaotfload.log.report
local assert = assert
local next = next
@@ -50,8 +51,7 @@ local getattrs = direct.getattributelist
local setattrs = direct.setattributelist
local getchar = direct.getchar
local setchar = direct.setchar
-local getdir = direct.getdir
-local setdir = direct.setdir
+local getdirection = direct.getdirection
local getdisc = direct.getdisc
local setdisc = direct.setdisc
local getfont = direct.getfont
@@ -59,6 +59,8 @@ local getdata = direct.getdata
local setdata = direct.setdata
local getfont = direct.getfont
local setfont = direct.setfont
+local getwhatsitfield = direct.getwhatsitfield or direct.getfield
+local setwhatsitfield = direct.setwhatsitfield or direct.setfield
local getfield = direct.getfield
local setfield = direct.setfield
local getid = direct.getid
@@ -174,7 +176,7 @@ local function itemize(head, fontid, direction)
local runs, codes = {}, {}
local dirstack = {}
- local currdir = direction or "TLT"
+ local currdir = direction or 0
local lastskip, lastdir = true
local lastrun = {}
@@ -203,18 +205,19 @@ local function itemize(head, fontid, direction)
skip = true
end
elseif id == dir_t then
- local dir = getdir(n)
- if dir:sub(1, 1) == "+" then
- -- Push the current direction to the stack.
- tableinsert(dirstack, currdir)
- currdir = dir:sub(2)
- else
- assert(currdir == dir:sub(2))
+ local dir, cancel = getdirection(n)
+ local direction, kind = getdirection(n)
+ if cancel then
+ assert(currdir == dir)
-- Pop the last direction from the stack.
currdir = tableremove(dirstack)
+ else
+ -- Push the current direction to the stack.
+ tableinsert(dirstack, currdir)
+ currdir = dir
end
elseif id == localpar_t then
- currdir = getdir(n)
+ currdir = getdirection(n)
end
codes[#codes + 1] = code
@@ -225,7 +228,7 @@ local function itemize(head, fontid, direction)
start = #codes,
len = 1,
font = fontid,
- dir = currdir == "TRT" and dir_rtl or dir_ltr,
+ dir = currdir == 1 and dir_rtl or dir_ltr,
skip = skip,
codes = codes,
}
@@ -265,6 +268,7 @@ local function makesub(run, codes, nodelist)
nodelist = nil
end
nodelist, nodelist, glyphs = shape(nodelist, nodelist, subrun)
+ assert(glyphs, [[Shaping discretionary list failed. This shouldn't happen.]])
return { glyphs = glyphs, run = subrun, head = nodelist }
end
@@ -428,7 +432,8 @@ function shape(head, firstnode, run)
while startglyph > 1
and codes[glyphs[startglyph - 1].cluster + 1] ~= 0x20
and codes[glyphs[startglyph - 1].cluster + 1] ~= 0xFFFC
- and unsafetobreak(glyphs[startglyph]) do
+ and (unsafetobreak(glyphs[startglyph])
+ or glyphs[startglyph].cluster == glyphs[startglyph-1].cluster) do
startglyph = startglyph - 1
end
-- Get the corresponding character index.
@@ -550,9 +555,23 @@ function shape(head, firstnode, run)
end
end
return head, firstnode, glyphs, run.len - len
+ else
+ if not fontdata.shaper_warning then
+ local shaper = shapers[1]
+ if shaper then
+ tex.error("luaotfload | harf : Shaper failed", {
+ string.format("You asked me to use shaper %q to shape", shaper),
+ string.format("the font %q", fontdata.name),
+ "but the shaper failed. This probably means that either the shaper is not",
+ "available or the font is not compatible.",
+ "Maybe you should try the default shaper instead?"
+ })
+ else
+ tex.error(string.format("luaotfload | harf : All shapers failed for font %q.", fontdata.name))
+ end
+ fontdata.shaper_warning = true -- Only warn once for every font
+ end
end
-
- return head, firstnode, {}, 0
end
local function color_to_rgba(color)
@@ -687,6 +706,7 @@ local function tonodes(head, node, run, glyphs)
if layers then
local cmds = {} -- Every layer will add 5 cmds
local prev_color = nil
+ local k = 1 -- k == j except that k does only get increased if the layer isn't dropped
for j = 1, #layers do
local layer = layers[j]
local layerchar = characters[gid_offset + layer.glyph]
@@ -700,13 +720,16 @@ local function tonodes(head, node, run, glyphs)
-- color, we don’t check for it here explicitly since we will
-- get nil anyway.
local color = palette[layer.color_index]
- cmds[5*j - 4] = (color and not prev_color) and save_cmd or nop_cmd
- cmds[5*j - 3] = prev_color == color and nop_cmd or (color and {"pdf", "page", color_to_rgba(color)} or restore_cmd)
- cmds[5*j - 2] = push_cmd
- cmds[5*j - 1] = {"char", layer.glyph + gid_offset}
- cmds[5*j] = pop_cmd
- fontglyphs[layer.glyph].used = true
- prev_color = color
+ if not color or color.alpha ~= 0 then
+ cmds[5*k - 4] = (color and not prev_color) and save_cmd or nop_cmd
+ cmds[5*k - 3] = prev_color == color and nop_cmd or (color and {"pdf", "page", color_to_rgba(color)} or restore_cmd)
+ cmds[5*k - 2] = push_cmd
+ cmds[5*k - 1] = {"char", layer.glyph + gid_offset}
+ cmds[5*k] = pop_cmd
+ fontglyphs[layer.glyph].used = true
+ prev_color = color
+ k = k+1
+ end
end
cmds[#cmds + 1] = prev_color and restore_cmd
if not character.colored then
@@ -888,10 +911,11 @@ local function shape_run(head, current, run)
-- shaping.
local glyphs, offset
head, current, glyphs, offset = shape(head, current, run)
- return offset, tonodes(head, current, run, glyphs)
- else
- return 0, head, run.after
+ if glyphs then
+ return offset, tonodes(head, current, run, glyphs)
+ end
end
+ return 0, head, run.after
end
function process(head, font, _attr, direction)
@@ -912,8 +936,8 @@ end
local function pageliteral(data)
local n = newnode(whatsit_t, pdfliteral_t)
- setfield(n, "mode", 1) -- page
- setdata(n, data)
+ setwhatsitfield(n, "mode", 1) -- page
+ setwhatsitfield(n, "data", data) -- page
return n
end
@@ -994,7 +1018,16 @@ local utfchar = utf8.char
local function get_glyph_info(n)
n = todirect(n)
local props = properties[n]
- return props and props.glyph_info or utfchar(getchar(n)):gsub('\0', '^^@')
+ local info = props and props.glyph_info
+ if info then return info end
+ local c = getchar(n)
+ if c == 0 then
+ return '^^@'
+ elseif c < 0x110000 then
+ return utfchar(c)
+ else
+ return string.format("^^^^^^%06X", c)
+ end
end
fonts.handlers.otf.registerplugin('harf', process)
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua
index e86945b033a..cfbcb68eab7 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua
@@ -5,17 +5,17 @@
-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>, Marcel Krüger
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+local ProvidesLuaModule = {
name = "luaotfload-init",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / initialization",
license = "GPL v2.0"
}
if luatexbase and luatexbase.provides_module then
luatexbase.provides_module (ProvidesLuaModule)
-end
+end
-----------------------------------------------------------------------
@@ -79,68 +79,73 @@ local logreport --- filled in after loading the log module
--doc]]--
--- below paths are relative to the texmf-context
-local ltx = "tex/generic/context/luatex"
-local ctx = { "tex/context/base/mkiv", "tex/context/base" }
+
+local ignore, ltx, ctx = 0, 1, 2
+
+local context_module_paths = { -- [ltx] =
+ "tex/generic/context/luatex", -- [ctx] =
+ {"tex/context/base/mkiv", "tex/context/base" },
+}
local context_modules = {
--- Since 2.6 those are directly provided by the Lualibs package.
- { false, "l-lua" },
- { false, "l-lpeg" },
- { false, "l-function" },
- { false, "l-string" },
- { false, "l-table" },
- { false, "l-io" },
- { false, "l-file" },
- { false, "l-boolean" },
- { false, "l-math" },
- { false, "l-unicode" }, -- NEW UF 19.09.2018
- { false, "util-str" },
- { false, "util-fil" },
+ { ignore, "l-lua" },
+ { ignore, "l-lpeg" },
+ { ignore, "l-function" },
+ { ignore, "l-string" },
+ { ignore, "l-table" },
+ { ignore, "l-io" },
+ { ignore, "l-file" },
+ { ignore, "l-boolean" },
+ { ignore, "l-math" },
+ { ignore, "l-unicode" }, -- NEW UF 19.09.2018
+ { ignore, "util-str" },
+ { ignore, "util-fil" },
--- These constitute the fontloader proper.
- { ltx, "luatex-basics-gen" },
+ { ltx, "basics-gen" },
{ ctx, "data-con" },
- { ltx, "luatex-basics-nod" },
- { ltx, "luatex-basics-chr" }, -- NEW UF 14.12.2018
+ { ltx, "basics-nod" },
+ { ltx, "basics-chr" }, -- NEW UF 14.12.2018
{ ctx, "font-ini" },
- { ltx, "luatex-fonts-mis" }, -- NEW UF 19.09.2018
+ { ltx, "fonts-mis" }, -- NEW UF 19.09.2018
{ ctx, "font-con" },
- { ltx, "luatex-fonts-enc" },
+ { ltx, "fonts-enc" },
{ ctx, "font-cid" },
{ ctx, "font-map" },
--- { ltx, "luatex-fonts-syn" }, -- ignore??
+-- { ltx, "fonts-syn" }, -- ignore??
{ ctx, "font-vfc" }, -- NEW UF 19.09.2018
- { ctx, "font-oti" },
{ ctx, "font-otr" },
- { ctx, "font-ott" },
{ ctx, "font-cff" },
{ ctx, "font-ttf" },
{ ctx, "font-dsp" },
- { ctx, "font-oup" },
+ { ctx, "font-oti" },
+ { ctx, "font-ott" },
{ ctx, "font-otl" },
{ ctx, "font-oto" },
{ ctx, "font-otj" },
+ { ctx, "font-oup" },
{ ctx, "font-ota" },
{ ctx, "font-ots" },
+ { ctx, "font-otc" },
{ ctx, "font-osd" },
{ ctx, "font-ocl" },
- { ctx, "font-otc" },
{ ctx, "font-onr" },
{ ctx, "font-one" },
{ ctx, "font-afk" },
- { ctx, "luatex-fonts-tfm" },
+ { ltx, "fonts-tfm" },
{ ctx, "font-lua" },
{ ctx, "font-def" },
- { ltx, "luatex-fonts-def" },
- { ltx, "luatex-fonts-ext" },
+ { ctx, "font-shp" },
+ { ltx, "fonts-def" },
+ { ltx, "fonts-ext" },
{ ctx, "font-imp-tex" },
{ ctx, "font-imp-ligatures"},
{ ctx, "font-imp-italics" },
{ ctx, "font-imp-effects" },
- { ltx, "luatex-fonts-lig" },
- { ltx, "luatex-fonts-gbn" },
-
+ { ltx, "fonts-lig" },
+ { ltx, "fonts-gbn" },
} --[[context_modules]]
@@ -151,12 +156,15 @@ local function load_context_modules (pth)
logreport ("both", 2, "init",
"Loading fontloader components from context.")
- local n = #context_modules
- for i = 1, n do
- local sub, spec = unpack (context_modules [i])
- if sub == false then
+ for i = 1, #context_modules do
+ local kind, spec = unpack (context_modules [i])
+ if kind == ignore then
ignore_module (spec)
else
+ if kind == ltx then
+ spec = 'luatex-' .. spec
+ end
+ local sub = context_module_paths[kind]
local tsub = type (sub)
if not pth then
load_module (spec)
@@ -193,10 +201,10 @@ local function load_context_modules (pth)
end
local function verify_context_dir (pth)
- if lfsisdir(file.join(pth, ltx)) then
+ if lfsisdir(file.join(pth, context_module_paths[ltx])) then
return true
end
- for _, d in ipairs(ctx) do
+ for _, d in ipairs(context_module_paths[ctx]) do
if lfsisdir(file.join(pth, d)) then
return true
end
@@ -265,6 +273,7 @@ local function init_main(early_hook)
local the_attributes = luatexbase.attributes
local context_environment = luaotfload.fontloader
+ context_environment.CONTEXTLMTXMODE = 0
context_environment.attributes = {
private = function (name)
local attr = "luaotfload@" .. name --- used to be: “otfl@”
@@ -285,7 +294,21 @@ local function init_main(early_hook)
local load_fontloader_module = luaotfload.loaders.fontloader
local ignore_module = luaotfload.loaders.ignore
- load_fontloader_module "basics-gen"
+ do
+ local saved_reporter = texio.reporter
+ local saved_exit = os.exit
+ local errmsg
+ function texio.reporter(msg, ...)
+ print(...)
+ errmsg = msg
+ end
+ function os.exit()
+ error(errmsg)
+ end
+ load_fontloader_module "basics-gen"
+ texio.reporter = saved_reporter
+ os.exit = saved_exit
+ end
if early_hook then early_hook() end
@@ -324,66 +347,13 @@ local function init_main(early_hook)
load_fontloader_module (luaotfload.fontloader_package)
elseif fontloader == "unpackaged" then
+
logreport ("log", 0, "init",
"Loading fontloader components individually.")
- --- The loading sequence is known to change, so this might have to be
- --- updated with future updates. Do not modify it though unless there is
- --- a change to the upstream package!
-
- --- Since 2.6 those are directly provided by the Lualibs package.
- ignore_module "l-lua"
- ignore_module "l-lpeg"
- ignore_module "l-function"
- ignore_module "l-string"
- ignore_module "l-table"
- ignore_module "l-io"
- ignore_module "l-file"
- ignore_module "l-boolean"
- ignore_module "l-math"
- ignore_module "util-str"
- ignore_module "util-fil"
- ignore_module "luatex-basics-gen"
-
- load_fontloader_module "data-con"
- load_fontloader_module "basics-nod"
- load_fontloader_module "basics-chr"
- load_fontloader_module "font-ini"
- load_fontloader_module "fonts-mis"
- load_fontloader_module "font-con"
- load_fontloader_module "fonts-enc"
- load_fontloader_module "font-cid"
- load_fontloader_module "font-map"
--- load_fontloader_module "fonts-syn" -- ignore?
- load_fontloader_module "font-vfc"
- load_fontloader_module "font-otr"
- load_fontloader_module "font-oti"
- load_fontloader_module "font-ott"
- load_fontloader_module "font-cff"
- load_fontloader_module "font-ttf"
- load_fontloader_module "font-dsp"
- load_fontloader_module "font-oup"
- load_fontloader_module "font-otl"
- load_fontloader_module "font-oto"
- load_fontloader_module "font-otj"
- load_fontloader_module "font-ota"
- load_fontloader_module "font-ots"
- load_fontloader_module "font-osd"
- load_fontloader_module "font-ocl"
- load_fontloader_module "font-otc"
- load_fontloader_module "font-onr"
- load_fontloader_module "font-one"
- load_fontloader_module "font-afk"
- load_fontloader_module "fonts-tfm"
- load_fontloader_module "font-lua"
- load_fontloader_module "font-def"
- load_fontloader_module "fonts-def"
- load_fontloader_module "fonts-ext"
- load_fontloader_module "font-imp-tex"
- load_fontloader_module "font-imp-ligatures"
- load_fontloader_module "font-imp-italics"
- load_fontloader_module "font-imp-effects"
- load_fontloader_module "fonts-lig"
- load_fontloader_module "fonts-gbn"
+ for i = 1, #context_modules do
+ local mod = context_modules[i];
+ (mod[1] == ignore and ignore_module or load_fontloader_module)(mod[2])
+ end
elseif fontloader == "context" then
logreport ("log", 0, "init",
@@ -457,7 +427,9 @@ local init_post_install_callbacks = function ()
local handler = luaotfload.fontloader.nodes.simple_font_handler
local callback = function(head, groupcode, _, _, direction)
if not direction then
- direction = tex.get'textdir'
+ direction = tex.get'textdirection'
+ else
+ direction = direction == "TRT" and 1 or 0
end
multiscript(head, nil, nil, nil, direction)
fallback(head, nil, nil, nil, direction)
@@ -472,6 +444,14 @@ local init_post_install_callbacks = function ()
"luaotfload.node_processor",
1)
-- /MK
+
+ local streams = fonts.hashes.streams
+ luatexbase.add_to_callback("glyph_stream_provider",function(id,index,mode)
+ if id <= 0 then return "" end
+ local stream = streams[id].streams
+ if not stream then return "" end
+ return stream[index] or ""
+ end, "luaotfload.glyph_stream")
end
local function init_post_load_agl ()
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua
index 927fa68771a..f9c24a13354 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua
@@ -5,9 +5,9 @@
local ProvidesLuaModule = {
name = "luaotfload-letterspace",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
- description = "luaotfload submodule / color",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / letterspacing",
license = "GPL v2.0",
copyright = "PRAGMA ADE / ConTeXt Development Team",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL; adapted by Philipp Gesang, Ulrike Fischer, Marcel Krüger"
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua
index 02dd8359e68..a63506237a5 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua
@@ -8,8 +8,8 @@
local ProvidesLuaModule = {
name = "luaotfload-loaders",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / callback handling",
license = "GPL v2.0"
}
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua
index 801310981d3..b102da65bf0 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua
@@ -6,8 +6,8 @@
local ProvidesLuaModule = {
name = "luaotfload-log",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / logging",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua
index 0c8a909c1be..5fa8c54ad39 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua
@@ -20,8 +20,8 @@ local authors = "\z
-- version number is used below!
local ProvidesLuaModule = {
name = "luaotfload-main",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload entry point",
author = authors,
copyright = authors,
@@ -40,7 +40,6 @@ luaotfload.log = luaotfload.log or { }
local logreport
luaotfload.version = ProvidesLuaModule.version
luaotfload.loaders = { }
-luaotfload.min_luatex_version = { 0, 95, 0 }
luaotfload.fontloader_package = "reference" --- default: from current Context
if not tex or not tex.luatexversion then
@@ -48,21 +47,14 @@ if not tex or not tex.luatexversion then
end
--- version check
-local major = tex.luatexversion / 100
-local minor = tex.luatexversion % 100
-local revision = tex.luatexrevision --[[ : string ]]
-local revno = tonumber (revision)
-local minimum = luaotfload.min_luatex_version
-local actual = { major, minor, revno or 0 }
-if actual [1] < minimum [1]
- or actual == minimum and actual [2] < minimum [2]
- or actual == minimum and actual [2] == minimum [2] and actual [3] < minimum [3]
-then
+local revno = tonumber(tex.luatexrevision)
+local minimum = { 110, 0 }
+if tex.luatexversion < minimum[1] or tex.luatexversion == minimum[1] and revno < minimum[2] then
texio.write_nl ("term and log",
string.format ("\tFATAL ERROR\n\z
\tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z
\tPlease update your TeX distribution!\n\n",
- (unpack or table.unpack) (minimum)))
+ math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2]))
error "version check failed"
end
@@ -234,13 +226,13 @@ local function context_loader (name, path)
local t_end = osgettimeofday ()
timing_info.t_load [name] = t_end - t_0
- if ret ~= true then
+ if ret ~= nil then
--- require () returns “true” upon success unless the loaded file
--- yields a non-zero exit code. This isn’t per se indicating that
--- something isn’t right, but against HH’s coding practices. We’ll
--- silently ignore this ever happening on lower log levels.
luaotfload.log.report ("log", 4, "load",
- "Module %q returned %q.", ret)
+ "Module %q returned %q.", modname, ret)
end
return ret
end
@@ -334,6 +326,9 @@ luaotfload.main = function ()
loadmodule "szss" --- missing glyph handling
initialize "auxiliary" --- additional high-level functionality
loadmodule "tounicode"
+ if tex.outputmode == 0 then
+ loadmodule "dvi" --- allow writing fonts to DVI files
+ end
luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua
index fe6cf17985f..aae924c9de8 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-multiscript",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / multiscript",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
index e027d206669..f2043a7ad7f 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua
@@ -5,9 +5,9 @@
local ProvidesLuaModule = {
name = "luaotfload-notdef",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
- description = "luaotfload submodule / color",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / notdef",
license = "GPL v2.0",
author = "Marcel Krüger"
}
@@ -34,6 +34,8 @@ local setfont = node.direct.setfont
local traverse_char = node.direct.traverse_char
local traverse_id = node.direct.traverse_id
local setchar = node.direct.setchar
+local setdisc = node.direct.setdisc
+local getdisc = node.direct.getdisc
local getwidth = node.direct.getwidth
local setkern = node.direct.setkern
local setattributelist = node.direct.setattributelist
@@ -197,7 +199,7 @@ local push, pop do
head = node.direct.remove(head, n)
l[#l+1] = n
elseif id == disc_id then
- local pre, post, replace = node.direct.getdisc(n)
+ local pre, post, replace = getdisc(n)
for nn in node.direct.traverse(pre) do
if checkprop(nn) then
local after
@@ -217,7 +219,7 @@ local push, pop do
l[#l+1] = {nn, n, 'replace'}
end
end
- node.direct.setdisc(n, pre, post, replace)
+ setdisc(n, pre, post, replace)
end
end
return head
@@ -302,8 +304,6 @@ otfregister {
},
}
-ignorable_replacement = {}
-
local delayed_remove do
local delayed
function delayed_remove(n)
@@ -335,7 +335,7 @@ local function ignorablehandler(head, fid, ...) -- FIXME: The arguments are prob
end
end end
delayed_remove()
- for n in traverse_id(head, disc_id) do
+ for n in traverse_id(disc_id, head) do
local a, b, c = getdisc(n)
setdisc(ignorablehandler(a, fid), ignorablehandler(b, fid), ignorablehandler(c, fid))
end
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua
index c69cb86f567..f321e9733fd 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua
@@ -7,9 +7,9 @@
local ProvidesLuaModule = {
name = "luaotfload-parsers",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
- description = "luaotfload submodule / filelist",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / parsers",
license = "GPL v2.0"
}
@@ -779,19 +779,20 @@ local parse_config = Ct (ini_sections)
--doc]=]--
+luaotfload.parsers = {
+ --- parameters
+ traversal_maxdepth = traversal_maxdepth,
+ --- main parsers
+ read_fonts_conf = read_fonts_conf,
+ font_request = font_request,
+ config = parse_config,
+ --- common patterns
+ stripslashes = stripslashes,
+ splitcomma = splitcomma,
+}
+
return function ()
logreport = luaotfload.log.report
- luaotfload.parsers = {
- --- parameters
- traversal_maxdepth = traversal_maxdepth,
- --- main parsers
- read_fonts_conf = read_fonts_conf,
- font_request = font_request,
- config = parse_config,
- --- common patterns
- stripslashes = stripslashes,
- splitcomma = splitcomma,
- }
return true
end
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua
index 14a503bb148..b7ca21ec876 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua
@@ -11,8 +11,8 @@
local ProvidesLuaModule = {
name = "luaotfload-resolvers",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / resolvers",
license = "GPL v2.0"
}
@@ -233,7 +233,7 @@ local function resolve_kpse (specification)
local name = specification.name
local suffix = stringlower (filesuffix (name))
if suffix and fonts.formats[suffix] then
- local resolved = resolvers.findfile(name, suffix)
+ local resolved = resolvers_findfile(name, suffix)
if resolved then return resolved end
end
for t, format in next, fonts.formats do --- brute force
@@ -292,7 +292,7 @@ return function()
end
logreport ("log", 5, "resolvers", "installing font resolvers", name)
local request_resolvers = fonts.definers.resolvers
- for k, _ in pairs(resolvers) do
+ for k, _ in pairs(request_resolvers) do
request_resolvers[k] = nil
end
setmetatable(request_resolvers, {__index = function(t, n)
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua
index fb842c5532a..6ac19f14d57 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-script",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / Script helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua
index 69fa2f6ab55..dd38631cc8d 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua
@@ -1,97 +1,97 @@
return {
["hashes"]={
- { "fontloader-2020-05-06.lua", "cb465e20137d75429cb876688189ff36" },
- { "fontloader-util-fil.lua", "4bb3e4dc72e308d8ed67cd7a80027fa7" },
- { "fontloader-util-str.lua", "2c1a12d8248d3719c0b5fc93184242bf" },
- { "fontloader-l-unicode.lua", "9bc311ce08ce498f9caacb6164ea1d9f" },
- { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" },
- { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" },
- { "fontloader-l-file.lua", "60ddd3948d9de7bde8b4a0f5c51ff9f5" },
- { "fontloader-l-io.lua", "a4042e9d6bce71c61fdd94e6e17f2bf4" },
- { "fontloader-l-table.lua", "20c03ae1b81e902217f3f76995b9d294" },
- { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" },
- { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" },
- { "fontloader-l-lpeg.lua", "efe630e3a9a1d269120e59cfd8fba4ba" },
- { "fontloader-l-lua.lua", "4185c43dd58d217094ef91c0310d8772" },
- { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" },
- { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" },
- { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" },
- { "fontloader-fonts-def.lua", "5ad79120ebc5e60f4d322fb3ee13bffe" },
- { "fontloader-fonts-tfm.lua", "3bbba3214fd0b8c6f35ad85592fc2917" },
- { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" },
- { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" },
- { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" },
- { "fontloader-basics-nod.lua", "68226d7dadd241bca55171af9ce1f243" },
- { "fontloader-font-imp-effects.lua", "73a660359a0ec71e44cc2b7225a715ac" },
- { "fontloader-font-imp-italics.lua", "fe1ca80fb5ea4a2f8d2d5c484e7ba913" },
- { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" },
- { "fontloader-font-imp-tex.lua", "77c374b0ef00c2fb12188ec42beb4257" },
- { "fontloader-font-def.lua", "c525b9f55da1c736a1f6939c0a6f8f00" },
- { "fontloader-font-lua.lua", "55b281fb98f7bd848fc19928f376f647" },
- { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" },
- { "fontloader-font-one.lua", "987c5c5ed3754ad2feab80985067d59e" },
- { "fontloader-font-onr.lua", "22572ec0f86f53631e14b6d1ed43ee51" },
- { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" },
- { "fontloader-font-ocl.lua", "ee310c8d0ac411d5ba6b50d338548013" },
- { "fontloader-font-osd.lua", "61f05fcf91add1aa5dac9bc8b235adc9" },
- { "fontloader-font-ots.lua", "113b7ad0c40d4786bb026706e479c3f3" },
- { "fontloader-font-ota.lua", "dd5f1c8ba28abaf4505fd960d04a3a98" },
- { "fontloader-font-otj.lua", "c9ded1d935bfa43020657e1f408fb820" },
- { "fontloader-font-oto.lua", "24238a7c600d090a8ee88312321dd9b3" },
- { "fontloader-font-otl.lua", "f111f9ac18d24049fadeb8883e4e8da5" },
- { "fontloader-font-oup.lua", "1700a2dac4f8b105c187d4e5b84cecdf" },
- { "fontloader-font-dsp.lua", "618e5e760ec5dceb0c898a83816dbe61" },
- { "fontloader-font-ttf.lua", "44e61cef50dab9b1aaf48130f9367c34" },
- { "fontloader-font-cff.lua", "155821e11e84021437869ff973e75d93" },
- { "fontloader-font-ott.lua", "aba6d8335a5f38a5a62d3631492f3392" },
- { "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" },
- { "fontloader-font-otr.lua", "d96724dcb40c673ac294df7044a39925" },
- { "fontloader-font-vfc.lua", "94937140f2c909e9c831ba021f1ab303" },
- { "fontloader-font-map.lua", "51d0362c19d2d0f621e5cb750410a809" },
- { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" },
- { "fontloader-font-con.lua", "40e3a857b2f31be1959dc6d445aaa9c4" },
- { "fontloader-font-ini.lua", "4dee96e1e1474d324dd126bd5d375df8" },
- { "fontloader-data-con.lua", "de6ae0997b0e70a23bcc9afff5d8b072" },
- { "fontloader-reference.lua", "2479b532aa53f60c4a83041c4f0e6632" },
- { "fontloader-basics-gen.lua", "b88f9848c3247e4222b7bb63b0ee3f35" },
- { "mktests", "c7cff7025962922944376acc1ffa9c47" },
- { "mkstatus", "8f230b751f58ec989604884a58cb5cfa" },
- { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" },
- { "mkglyphlist", "95bbf91338214d40b2102114285ccd3f" },
- { "mkimport", "60e0b11a1a68719033e86a3e0f4d5e86" },
- { "luaotfload-glyphlist.lua", "f14bb296a5a4eb9a6cb130f6a703d160" },
- { "luaotfload-characters.lua", "6a46f4749368e4f56a863da9c61b7bd6" },
- { "luaotfload-tounicode.lua", "610d27c11ea928a7a299ada038db3a6d" },
- { "luaotfload-unicode.lua", "737a96fb0cd50197bb2ceb6e28fec021" },
- { "luaotfload-resolvers.lua", "8349bdce20fa37470f985f1aabc7946f" },
- { "luaotfload-parsers.lua", "f61808c1b01a3a40385b3e74f8171c3e" },
- { "luaotfload-fallback.lua", "5d613223f8153767305bd8d3d4387de7" },
- { "luaotfload-szss.lua", "58a838170ea2d61affee0a83cbf602c2" },
- { "luaotfload-scripts.lua", "702a128883d033ab9f3726ba2e21fc8d" },
- { "luaotfload-multiscript.lua", "7089c788fa75d8074e73919532fefa92" },
- { "luaotfload-loaders.lua", "53d26bba499abf18cf823675c77e36de" },
- { "luaotfload-harf-plug.lua", "840abb8a4965dd32532cc73e670f5906" },
- { "luaotfload-harf-define.lua", "ba5861271933078de634b9e00172f69a" },
- { "luaotfload-notdef.lua", "af12a1afe613f42b0d8d1033776eefaf" },
- { "luaotfload-embolden.lua", "9f2cda5502e5a0ceb6402f6dd075732f" },
- { "luaotfload-letterspace.lua", "06639c9e935da07c4694da6579a36781" },
- { "luaotfload-features.lua", "0bd3943f65c0688738407ff1a186900f" },
- { "luaotfload-database.lua", "8e9e26a9acd048ec1217fad9fa80cd0d" },
- { "luaotfload-configuration.lua", "827b91b6f6881a69ea48885093f10c71" },
- { "luaotfload-colors.lua", "23cfde48b9609e33e9b809a3ebd1a670" },
- { "luaotfload-auxiliary.lua", "50a56ccd209e59b66514c483fd8af85d" },
- { "luaotfload-filelist.lua", "e3139b052bc5789b9135c1eb20753d3e" },
- { "luaotfload-tool.lua", "89fc62620ef6f534ea1f6a3f6253886b" },
- { "luaotfload-diagnostics.lua", "a4635cd5da922b6cb3ef27e74a3cf6d8" },
- { "luaotfload-log.lua", "b37a69c07eecaecc17d2d069e088b133" },
- { "luaotfload-init.lua", "8c9b852cdf019fa43c938618773ecd5e" },
- { "luaotfload-main.lua", "5ccffdfbe87102c13d6d1910873935d3" },
+ { "fontloader-2020-08-31.lua", "70a72561e3869bcaa8554921083b3872" },
+ { "fontloader-util-fil.lua", "aae2a2add764144bb58dd8216fd59260" },
+ { "fontloader-util-str.lua", "c975ff7bbd178163cf47d9e9296c8b4b" },
+ { "fontloader-l-unicode.lua", "f368874f11f3c525de5864fd413e4b24" },
+ { "fontloader-l-math.lua", "082add08e0bb79f39191ae9534a79849" },
+ { "fontloader-l-boolean.lua", "abe28515dd33e8f6c416c09bca351cf8" },
+ { "fontloader-l-file.lua", "352b42b8360ada02ceb26a41f0bd2a76" },
+ { "fontloader-l-io.lua", "bbcc4824d0ded30b415d7d2d5763028a" },
+ { "fontloader-l-table.lua", "0330da8b3a08d39876def70df8d9c0e5" },
+ { "fontloader-l-string.lua", "9457f2af85723e0e6c46d0b5122e9000" },
+ { "fontloader-l-function.lua", "a7e68a9703c35238729da41a474e951b" },
+ { "fontloader-l-lpeg.lua", "10bdaef44175902917691835010ae5f5" },
+ { "fontloader-l-lua.lua", "420bc442e6d81f4624728a6c56fcd175" },
+ { "fontloader-fonts-gbn.lua", "10ecdf01e7c926e5128ad8a9dff4d677" },
+ { "fontloader-fonts-lig.lua", "fbd251eea3810a43a8d5542319361d68" },
+ { "fontloader-fonts-ext.lua", "32013cbc5d5d336be8b1d1e5879d86c4" },
+ { "fontloader-fonts-def.lua", "f435e0875f203f343157baeff876ec9c" },
+ { "fontloader-fonts-tfm.lua", "f0eb5e2a8068b17ad401bb7efdba1630" },
+ { "fontloader-fonts-enc.lua", "5ff4ca50493d7c4ecea0e15c203099f0" },
+ { "fontloader-fonts-mis.lua", "17e967c9ec4d001deefd43ddf25e98f7" },
+ { "fontloader-basics-chr.lua", "64fafe4eaf55d64aead6513c1e74a024" },
+ { "fontloader-basics-nod.lua", "335e61ffb6dec00f88f737854a2d9ab4" },
+ { "fontloader-font-imp-effects.lua", "d9b935e9b73f250a175ddd71a226b8e9" },
+ { "fontloader-font-imp-italics.lua", "ae563638fa29a4ff3e8e4d1e81fd35ae" },
+ { "fontloader-font-imp-ligatures.lua", "26ffcf089391445f7af59536c8814364" },
+ { "fontloader-font-imp-tex.lua", "ceb087ef6fa2f89aed7179f60ddf8f35" },
+ { "fontloader-font-def.lua", "b9d908c2338b7dc443ce9d1e9fcb7139" },
+ { "fontloader-font-lua.lua", "1fbfdf7b689b2bdfd0e3bb9bf74ce136" },
+ { "fontloader-font-afk.lua", "9da14e0fb22129c053acc599d1312544" },
+ { "fontloader-font-one.lua", "5a2f244c88c8178e997c16a9b628bb6f" },
+ { "fontloader-font-onr.lua", "6d161533f3437435e12a0ad64866df44" },
+ { "fontloader-font-otc.lua", "0f12230ea07b5151f75d52726977e91f" },
+ { "fontloader-font-ocl.lua", "797b5c71bf819c5f4fb314a4d646e9a7" },
+ { "fontloader-font-osd.lua", "73c9531c79df5ada320cb20777f7ed49" },
+ { "fontloader-font-ots.lua", "f018ae1f355a8ef5c8d403cc5489e3d3" },
+ { "fontloader-font-ota.lua", "ad1d5de06400f88829509e1f3ff2b473" },
+ { "fontloader-font-otj.lua", "8de59cb9b043e5f73c6b9f7cc8f6978e" },
+ { "fontloader-font-oto.lua", "2b1d6bc63b2ebf8f2655a15e1cda6541" },
+ { "fontloader-font-otl.lua", "b168cf69300873d6668203bc7afe1f56" },
+ { "fontloader-font-oup.lua", "6f46aa00ae1c20c43f8ffaf329dc8695" },
+ { "fontloader-font-dsp.lua", "5d6528c0673b7651600ca6b763b51df5" },
+ { "fontloader-font-ttf.lua", "786a535ba0385446b7015260388bc415" },
+ { "fontloader-font-cff.lua", "802a10ad12ac32329f540881f940e3f2" },
+ { "fontloader-font-ott.lua", "673ed11e1d159997f535bfec5fa73808" },
+ { "fontloader-font-oti.lua", "309a75f9c14b77d87e94eba827dc4e71" },
+ { "fontloader-font-otr.lua", "64dcbbc7107538723990e1119a80a9f8" },
+ { "fontloader-font-vfc.lua", "a81c29eda98cd62cbebdb6c93544b50d" },
+ { "fontloader-font-map.lua", "c4a39db5ad822b348aa61bca5f4a599a" },
+ { "fontloader-font-cid.lua", "22b0367742fb253deef84ef7ccf5e8de" },
+ { "fontloader-font-con.lua", "a3eb543fa5946fa1faf0e1e50d5b3b91" },
+ { "fontloader-font-ini.lua", "5343de60613adb24cdd7a8d2ee1d153c" },
+ { "fontloader-data-con.lua", "23a0f5386d46a1c157ae82a373e35fa0" },
+ { "fontloader-reference.lua", "c10086745bc0b8b2303572fdea86d61c" },
+ { "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" },
+ { "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" },
+ { "mkstatus", "49692433db8a578cf3a03fbedfb2ea9c" },
+ { "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" },
+ { "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" },
+ { "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" },
+ { "luaotfload-glyphlist.lua", "af60521c7ea3f5828c83ed1d1fa23b45" },
+ { "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" },
+ { "luaotfload-tounicode.lua", "24601f0255c35508eddbb427a6e18873" },
+ { "luaotfload-unicode.lua", "c7d3f282db7a0f9588cc57d8f079a3cb" },
+ { "luaotfload-resolvers.lua", "ac9e134e0614ab7ab69122ec0fd99e54" },
+ { "luaotfload-parsers.lua", "10afafb81544840cb0fd0ecaac3c3344" },
+ { "luaotfload-fallback.lua", "9d70a346c2584834f40d83be25d53a6a" },
+ { "luaotfload-szss.lua", "0e29a05f35bbd05388e5af674059c242" },
+ { "luaotfload-scripts.lua", "9a1e50e55ddef481ca3863004f33703e" },
+ { "luaotfload-multiscript.lua", "8a828bf429dc73742ea78ad73332d219" },
+ { "luaotfload-loaders.lua", "f13bafee1dca48db5073fe4390dc8ec4" },
+ { "luaotfload-harf-plug.lua", "f43e0d894cf9ca3f31ff405d1684a5ff" },
+ { "luaotfload-harf-define.lua", "0aecef4ea82a6edc305be2eed7b8e9c9" },
+ { "luaotfload-notdef.lua", "73762a6d7662aa090f8f950a34d55835" },
+ { "luaotfload-embolden.lua", "3444350537a12803b8e255f56b33b50d" },
+ { "luaotfload-letterspace.lua", "6ac6c8d6f54107984ad338a94f0acd86" },
+ { "luaotfload-features.lua", "b42fbc57c4fb1306dc23bf4e3bf6cd98" },
+ { "luaotfload-database.lua", "8e11e69cf6a83bc1723c95e4788cdc70" },
+ { "luaotfload-configuration.lua", "d1f4d64caa58bfc5feb524ea7cd365f6" },
+ { "luaotfload-colors.lua", "5d1e7e10b5a8dda7ccf3742ae90f002e" },
+ { "luaotfload-auxiliary.lua", "6d4e31212b8852e5f1425dc0ea49e016" },
+ { "luaotfload-filelist.lua", "5e4c15ea6e5aafc19a533289b6ac2709" },
+ { "luaotfload-tool.lua", "9caf618c38bf58cf9a29f2b2d4449346" },
+ { "luaotfload-diagnostics.lua", "797176921da30591e6112831ed7459a7" },
+ { "luaotfload-log.lua", "932117045a6abfe303314a295c24d338" },
+ { "luaotfload-init.lua", "eb1bfca3833688aba31521032ed38883" },
+ { "luaotfload-main.lua", "133ee97a73e07f3116d0417c9373398b" },
},
["notes"]={
["committer"]="Marcel Fabian Krüger <tex@2krueger.de>",
- ["description"]="v3.14/2020-05-06",
- ["loader"]="fontloader-2020-05-06.lua",
- ["revision"]="79077b0311ec65e8eb3c60bfc306500d72fd270e",
- ["timestamp"]="2020-05-06 20:58:39 +0200",
+ ["description"]="v3.15/2020-09-02",
+ ["loader"]="fontloader-2020-08-31.lua",
+ ["revision"]="77eede02640bef0cb596d24aa79661328a68b448",
+ ["timestamp"]="2020-09-02 21:02:40 +0200",
},
} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua
index 50a0037c437..768cf814024 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-suppress",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / suppress",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua
index de3b47230c3..751964cdd10 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua
@@ -5,9 +5,9 @@
local ProvidesLuaModule = {
name = "luaotfload-szss",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
- description = "luaotfload submodule / color",
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
+ description = "luaotfload submodule / Special feature handling",
license = "GPL v2.0",
author = "Marcel Krüger"
}
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua
index 73bab117097..028aef9d125 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-tounicode",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / tounicode",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua
index 0fd71ec27a5..2e9b28cf790 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-unicode",
- version = "3.14", --TAGVERSION
- date = "2020-05-06", --TAGDATE
+ version = "3.15", --TAGVERSION
+ date = "2020-09-02", --TAGDATE
description = "luaotfload submodule / Unicode helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty
index 590a0b27ab8..33e15ba7c3f 100644
--- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty
@@ -1,4 +1,4 @@
-%% Copyright (C) 2009-2018
+%% Copyright (C) 2009-2020
%%
%% by Elie Roux <elie.roux@telecom-bretagne.eu>
%% and Khaled Hosny <khaledhosny@eglug.org>
@@ -8,9 +8,8 @@
%%
%% This file is part of Luaotfload.
%%
-%% Home: https://github.com/lualatex/luaotfload
-%%Current home: https://github.com/u-fischer/luaotfload
-%% Support: <lualatex-dev@tug.org>.
+%% Home: https://github.com/latex3/luaotfload
+%% Support: https://github.com/latex3/luaotfload/issues, <lualatex-dev@tug.org>.
%%
%% Luaotfload is under the GPL v2.0 (exactly) license.
%%
@@ -40,7 +39,7 @@
\fi
\ifdefined\ProvidesPackage
\ProvidesPackage{luaotfload}%
- [2020/05/06 v3.14 OpenType layout system]
+ [2020/09/02 v3.15 OpenType layout system]
\fi
\directlua{
if xpcall(function ()%