summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--doc/luaotfload-main.tex13
-rw-r--r--doc/luaotfload.conf.rst5
-rw-r--r--src/fontloader/misc/fontloader-font-con.lua31
-rw-r--r--src/fontloader/misc/fontloader-font-oti.lua4
-rw-r--r--src/fontloader/misc/fontloader-font-otl.lua2
-rw-r--r--src/fontloader/misc/fontloader-font-otr.lua130
-rw-r--r--src/fontloader/misc/fontloader-font-ots.lua108
-rw-r--r--src/fontloader/misc/fontloader-util-fil.lua68
-rw-r--r--src/fontloader/runtime/fontloader-reference.lua284
-rw-r--r--src/luaotfload-configuration.lua19
-rw-r--r--src/luaotfload-database.lua20
-rw-r--r--src/luaotfload-features.lua2
-rw-r--r--src/luaotfload-main.lua12
-rwxr-xr-xsrc/luaotfload-tool.lua38
15 files changed, 577 insertions, 177 deletions
diff --git a/Makefile b/Makefile
index a131f3a..e59b43e 100644
--- a/Makefile
+++ b/Makefile
@@ -198,16 +198,18 @@ $(TDS_ZIP): $(DOCS) $(ALL_STATUS) check
sign: $(CTAN_ZIPSIG)
-.PHONY: package install manifest clean mrproper show showtargets check import news
+.PHONY: package install manifest clean mrproper show showtargets
+.PHONY: check import news tds ctan sign package loader
+ifndef DESTDIR
install:
- @echo " ××××××××××××××××××××××××××××××××"
- @echo " There is no “install” target."
- @echo " ××××××××××××××××××××××××××××××××"
- @echo " Compile a TDS zipball (make tds)"
- @echo " and extract that into your local"
- @echo " TEXMF instead."
- @echo " ××××××××××××××××××××××××××××××××"
+ $(error "in order to install you need to provide $$DESTDIR")
+else
+install: $(TDS_ZIP)
+ $(info installing to destination “$(DESTDIR)”)
+ install -dm755 "$(DESTDIR)"
+ unzip "$(TDS_ZIP)" -d "$(DESTDIR)"
+endif
manifest:
@echo "Source files:"
diff --git a/doc/luaotfload-main.tex b/doc/luaotfload-main.tex
index f6c7301..406595a 100644
--- a/doc/luaotfload-main.tex
+++ b/doc/luaotfload-main.tex
@@ -424,6 +424,19 @@ non-standard directory:
\font \gfsporson = "[/tmp/GFSPorson.otf]" at 12pt
\endlisting
+\identifier{TrueType} collection files (the extension is usually
+\inlinecode{.ttc}) contain more than a single font. In order to refer to these
+subfonts, the respective index may be added in parentheses after the file
+name.\footnote{%
+ Incidentally, this syntactical detail also prevents one from loading files
+ that end in balanced parentheses.
+}
+
+\beginlisting
+ \font \cambriamain = "file:cambria.ttc(0)" at 10pt
+ \font \cambriamath = "file:cambria.ttc(1)" at 10pt
+\endlisting
+
\endsubsubsection
\beginsubsubsection{Loading by Font Name}
diff --git a/doc/luaotfload.conf.rst b/doc/luaotfload.conf.rst
index 051ec7f..2af9cec 100644
--- a/doc/luaotfload.conf.rst
+++ b/doc/luaotfload.conf.rst
@@ -142,8 +142,6 @@ Section ``db``
+-----------------+--------+---------------------------+
| update-live | b | ``true`` |
+-----------------+--------+---------------------------+
-| use-fontforge | b | ``false`` |
-+-----------------+--------+---------------------------+
The flag ``compress`` determines whether the font index (usually
``luaotfload-names.lua[.gz]`` will be stored in compressed forms.
@@ -189,9 +187,6 @@ cannot find a requested font. Those who prefer to update manually using
**luaotfload-tool** should unset this flag. This option does not affect
rebuilds due to version mismatch.
-The option ``use-fontforge`` had a meaning during the transition to the
-Lua-only Opentype reader. At present it is ignored.
-
Section ``default-features``
-----------------------------------------------------------------------
diff --git a/src/fontloader/misc/fontloader-font-con.lua b/src/fontloader/misc/fontloader-font-con.lua
index b3e506b..18f2217 100644
--- a/src/fontloader/misc/fontloader-font-con.lua
+++ b/src/fontloader/misc/fontloader-font-con.lua
@@ -447,12 +447,16 @@ function constructors.scale(tfmdata,specification)
local haskerns = properties.haskerns or properties.mode == "base" -- we can have afm in node mode
local hasligatures = properties.hasligatures or properties.mode == "base" -- we can have afm in node mode
local realdimensions = properties.realdimensions
+ local writingmode = properties.writingmode or "horizontal"
+ local identity = properties.identity or "horizontal"
--
if changed and not next(changed) then
changed = false
end
--
- target.type = isvirtual and "virtual" or "real"
+ target.type = isvirtual and "virtual" or "real"
+ target.writingmode = writingmode == "vertical" and "vertical" or "horizontal"
+ target.identity = identity == "vertical" and "vertical" or "horizontal"
--
target.postprocessors = tfmdata.postprocessors
--
@@ -894,6 +898,8 @@ function constructors.finalize(tfmdata)
cidinfo = tfmdata.cidinfo or nil,
format = tfmdata.format or "type1",
direction = tfmdata.direction or 0,
+ writingmode = tfmdata.writingmode or "horizontal",
+ identity = tfmdata.identity or "horizontal",
}
end
if not tfmdata.resources then
@@ -1091,7 +1097,11 @@ end)
do
- local function setindeed(mode,target,group,name,action,position)
+ local function setindeed(mode,source,target,group,name,position)
+ local action = source[mode]
+ if not action then
+ return
+ end
local t = target[mode]
if not t then
report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
@@ -1122,15 +1132,10 @@ do
report_defining("fatal source error in setting feature %a, group %a",name,group)
os.exit()
end
- local node = source.node
- local base = source.base
local position = source.position
- if node then
- setindeed("node",target,group,name,node,position)
- end
- if base then
- setindeed("base",target,group,name,base,position)
- end
+ setindeed("node",source,target,group,name,position)
+ setindeed("base",source,target,group,name,position)
+ setindeed("plug",source,target,group,name,position)
end
local function register(where,specification)
@@ -1197,9 +1202,9 @@ do
defaults = { },
descriptions = tables and tables.features or { },
used = statistics and statistics.usedfeatures or { },
- initializers = { base = { }, node = { } },
- processors = { base = { }, node = { } },
- manipulators = { base = { }, node = { } },
+ initializers = { base = { }, node = { }, plug = { } },
+ processors = { base = { }, node = { }, plug = { } },
+ manipulators = { base = { }, node = { }, plug = { } },
}
features.register = function(specification) return register(features,specification) end
handler.features = features -- will also become hidden
diff --git a/src/fontloader/misc/fontloader-font-oti.lua b/src/fontloader/misc/fontloader-font-oti.lua
index 5e812bb..e10a261 100644
--- a/src/fontloader/misc/fontloader-font-oti.lua
+++ b/src/fontloader/misc/fontloader-font-oti.lua
@@ -72,6 +72,7 @@ registerotffeature {
initializers = {
base = setmode,
node = setmode,
+ plug = setmode,
}
}
@@ -81,6 +82,7 @@ registerotffeature {
initializers = {
base = setlanguage,
node = setlanguage,
+ plug = setlanguage,
}
}
@@ -90,6 +92,7 @@ registerotffeature {
initializers = {
base = setscript,
node = setscript,
+ plug = setscript,
}
}
@@ -157,4 +160,3 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
end
end
end
-
diff --git a/src/fontloader/misc/fontloader-font-otl.lua b/src/fontloader/misc/fontloader-font-otl.lua
index cf6603f..d4eaed7 100644
--- a/src/fontloader/misc/fontloader-font-otl.lua
+++ b/src/fontloader/misc/fontloader-font-otl.lua
@@ -675,7 +675,7 @@ local function getgsub(tfmdata,k,kind,value)
local properties = tfmdata.properties
local validlookups, lookuplist = otf.collectlookups(rawdata,kind,properties.script,properties.language)
if validlookups then
- local choice = tonumber(value) or 1 -- no random here (yet)
+ -- local choice = tonumber(value) or 1 -- no random here (yet)
for i=1,#lookuplist do
local lookup = lookuplist[i]
local steps = lookup.steps
diff --git a/src/fontloader/misc/fontloader-font-otr.lua b/src/fontloader/misc/fontloader-font-otr.lua
index 9cdbc3d..2b18c1e 100644
--- a/src/fontloader/misc/fontloader-font-otr.lua
+++ b/src/fontloader/misc/fontloader-font-otr.lua
@@ -975,7 +975,7 @@ readers.head = function(f,fontdata)
end
-- This table is a rather simple one. No treatment of values is needed here. Most
--- variables are not used but nofhmetrics is quite important.
+-- variables are not used but nofmetrics is quite important.
readers.hhea = function(f,fontdata,specification)
if specification.details then
@@ -983,7 +983,7 @@ readers.hhea = function(f,fontdata,specification)
if datatable then
setposition(f,datatable.offset)
fontdata.horizontalheader = {
- version = readfixed(f),
+ version = readfixed(f), -- two ushorts: major minor
ascender = readfword(f),
descender = readfword(f),
linegap = readfword(f),
@@ -999,11 +999,45 @@ readers.hhea = function(f,fontdata,specification)
reserved_3 = readshort(f),
reserved_4 = readshort(f),
metricdataformat = readshort(f),
- nofhmetrics = readushort(f),
+ nofmetrics = readushort(f),
}
else
fontdata.horizontalheader = {
- nofhmetrics = 0,
+ nofmetrics = 0,
+ }
+ end
+ end
+end
+
+readers.vhea = function(f,fontdata,specification)
+ if specification.details then
+ local datatable = fontdata.tables.vhea
+ if datatable then
+ setposition(f,datatable.offset)
+ local version = readfixed(f)
+ fontdata.verticalheader = {
+ version = version,
+ ascender = readfword(f),
+ descender = readfword(f),
+ linegap = readfword(f),
+ maxadvanceheight = readufword(f),
+ mintopsidebearing = readfword(f),
+ minbottomsidebearing = readfword(f),
+ maxextent = readfword(f),
+ caretsloperise = readshort(f),
+ caretsloperun = readshort(f),
+ caretoffset = readshort(f),
+ reserved_1 = readshort(f),
+ reserved_2 = readshort(f),
+ reserved_3 = readshort(f),
+ reserved_4 = readshort(f),
+ metricdataformat = readshort(f),
+ nofmetrics = readushort(f),
+ }
+-- inspect(fontdata.verticalheader)
+ else
+ fontdata.verticalheader = {
+ nofmetrics = 0,
}
end
end
@@ -1064,11 +1098,12 @@ readers.hmtx = function(f,fontdata,specification)
local datatable = fontdata.tables.hmtx
if datatable then
setposition(f,datatable.offset)
- local nofmetrics = fontdata.horizontalheader.nofhmetrics
- local glyphs = fontdata.glyphs
- local nofglyphs = fontdata.nofglyphs
- local width = 0 -- advance
- local leftsidebearing = 0
+ local horizontalheader = fontdata.horizontalheader
+ local nofmetrics = horizontalheader.nofmetrics
+ local glyphs = fontdata.glyphs
+ local nofglyphs = fontdata.nofglyphs
+ local width = 0 -- advance
+ local leftsidebearing = 0
for i=0,nofmetrics-1 do
local glyph = glyphs[i]
width = readshort(f)
@@ -1095,6 +1130,53 @@ readers.hmtx = function(f,fontdata,specification)
end
end
+readers.vmtx = function(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable = fontdata.tables.vmtx
+ if datatable then
+ setposition(f,datatable.offset)
+ local verticalheader = fontdata.verticalheader
+ local nofmetrics = verticalheader.nofmetrics
+ local glyphs = fontdata.glyphs
+ local nofglyphs = fontdata.nofglyphs
+ local vheight = 0
+ local vdefault = verticalheader.ascender + verticalheader.descender
+ local topsidebearing = 0
+ for i=0,nofmetrics-1 do
+ local glyph = glyphs[i]
+ vheight = readshort(f)
+ topsidebearing = readshort(f)
+ if vheight ~= 0 and vheight ~= vdefault then
+ glyph.vheight = vheight
+ end
+ -- if topsidebearing ~= 0 then
+ -- glyph.tsb = topsidebearing
+ -- end
+ end
+ -- The next can happen in for instance a monospace font or in a cjk font
+ -- with fixed heights.
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph = glyphs[i]
+ if vheight ~= 0 and vheight ~= vdefault then
+ glyph.vheight = vheight
+ end
+ -- if topsidebearing ~= 0 then
+ -- glyph.tsb = topsidebearing
+ -- end
+ end
+ end
+ end
+end
+
+readers.vorg = function(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable = fontdata.tables.vorg
+ if datatable then
+ report("todo: %s","vorg")
+ end
+ end
+end
+
-- The post table relates to postscript (printing) but has some relevant properties for other
-- usage as well. We just use the names from the microsoft specification. The version 2.0
-- description is somewhat fuzzy but it is a hybrid with overloads.
@@ -1751,7 +1833,7 @@ end
-- some properties in order to read following tables. When details is true we also
-- initialize the glyphs data.
-local function getinfo(maindata,sub,platformnames,rawfamilynames)
+local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo)
local fontdata = sub and maindata.subfonts and maindata.subfonts[sub] or maindata
local names = fontdata.names
local info = nil
@@ -1808,6 +1890,29 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames)
descender = metrics.typodescender,
platformnames = platformnames and fontdata.platformnames or nil,
}
+ if metricstoo then
+ local keys = {
+ "version",
+ "ascender", "descender", "linegap",
+ -- "caretoffset", "caretsloperise", "caretsloperun",
+ "maxadvancewidth", "maxadvanceheight", "maxextent",
+ -- "metricdataformat",
+ "minbottomsidebearing", "mintopsidebearing",
+ }
+ local h = fontdata.horizontalheader or { }
+ local v = fontdata.verticalheader or { }
+ if h then
+ local th = { }
+ local tv = { }
+ for i=1,#keys do
+ local key = keys[i]
+ th[key] = h[key] or 0
+ tv[key] = v[key] or 0
+ end
+ info.horizontalmetrics = th
+ info.verticalmetrics = tv
+ end
+ end
elseif n then
info = {
filename = fontdata.filename,
@@ -1900,7 +2005,10 @@ local function readdata(f,offset,specification)
readers["head"](f,fontdata,specification)
readers["maxp"](f,fontdata,specification)
readers["hhea"](f,fontdata,specification)
+ readers["vhea"](f,fontdata,specification)
readers["hmtx"](f,fontdata,specification)
+ readers["vmtx"](f,fontdata,specification)
+ readers["vorg"](f,fontdata,specification)
readers["post"](f,fontdata,specification)
readers["cff" ](f,fontdata,specification)
readers["cmap"](f,fontdata,specification)
@@ -2084,7 +2192,7 @@ function readers.loadfont(filename,n)
descriptions = fontdata.descriptions,
format = fontdata.format,
goodies = { },
- metadata = getinfo(fontdata,n), -- no platformnames here !
+ metadata = getinfo(fontdata,n,false,false,true), -- no platformnames here !
properties = {
hasitalics = fontdata.hasitalics or false,
maxcolorclass = fontdata.maxcolorclass,
diff --git a/src/fontloader/misc/fontloader-font-ots.lua b/src/fontloader/misc/fontloader-font-ots.lua
index 1c64720..17e1a3c 100644
--- a/src/fontloader/misc/fontloader-font-ots.lua
+++ b/src/fontloader/misc/fontloader-font-ots.lua
@@ -128,6 +128,7 @@ local trace_details = false registertracker("otf.details", function(v
local trace_steps = false registertracker("otf.steps", function(v) trace_steps = v end)
local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end)
local trace_directions = false registertracker("otf.directions", function(v) trace_directions = v end)
+local trace_plugins = false registertracker("otf.plugins", function(v) trace_plugins = v end)
local trace_kernruns = false registertracker("otf.kernruns", function(v) trace_kernruns = v end)
local trace_discruns = false registertracker("otf.discruns", function(v) trace_discruns = v end)
@@ -136,6 +137,7 @@ local trace_testruns = false registertracker("otf.testruns", function(v
----- zwnjruns = true registerdirective("otf.zwnjruns", function(v) zwnjruns = v end)
local optimizekerns = true
+local alwaysdisc = true registerdirective("otf.alwaysdisc", function(v) alwaysdisc = v end)
local report_direct = logs.reporter("fonts","otf direct")
local report_subchain = logs.reporter("fonts","otf subchain")
@@ -599,7 +601,7 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou
setlink(discfound,next)
setboth(base)
setfield(base,"components",copied)
- setdisc(discfound,pre,post,base,discretionary_code)
+ setdisc(discfound,pre,post,base) -- was discretionary_code
base = prev -- restart
end
end
@@ -3047,7 +3049,11 @@ end
-- -- local a = getattr(start,0)
-- -- if not a or (a == attr) then
--
--- and even that one is probably not needed.
+-- and even that one is probably not needed. However, we can handle interesting
+-- cases now:
+--
+-- 1{2{\oldstyle\discretionary{3}{4}{5}}6}7\par
+-- 1{2\discretionary{3{\oldstyle3}}{{\oldstyle4}4}{5{\oldstyle5}5}6}7\par
local nesting = 0
@@ -3077,6 +3083,7 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
start = getnext(start)
end
else
+ -- go on can be a mixed one
start = getnext(start)
end
elseif char == false then
@@ -3122,6 +3129,8 @@ local function t_run_single(start,stop,font,attr,lookupcache)
return true, d > 1
end
end
+ else
+ -- go on can be a mixed one
end
start = getnext(start)
else
@@ -3207,6 +3216,7 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
start = getnext(start)
end
else
+ -- go on can be a mixed one
start = getnext(start)
end
elseif char == false then
@@ -3261,6 +3271,8 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
report_missing_coverage(dataset,sequence)
end
end
+ else
+ -- go on can be a mixed one
end
start = getnext(start)
else
@@ -3324,7 +3336,7 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase
end
end
--- to be checkedL nowadays we probably can assume properly matched directions
+-- to be checked, nowadays we probably can assume properly matched directions
-- so maybe we no longer need a stack
local function txtdirstate(start,stack,top,rlparmode)
@@ -3365,6 +3377,10 @@ local function pardirstate(start)
return getnext(start), new, new
end
+otf.helpers = otf.helpers or { }
+otf.helpers.txtdirstate = txtdirstate
+otf.helpers.pardirstate = pardirstate
+
local function featuresprocessor(head,font,attr)
local sequences = sequencelists[font] -- temp hack
@@ -3413,6 +3429,8 @@ local function featuresprocessor(head,font,attr)
local done = false
local datasets = otf.dataset(tfmdata,font,attr)
+ local forcedisc = alwaysdisc or not attr
+
local dirstack = { } -- could move outside function but we can have local runs
sweephead = { }
@@ -3425,7 +3443,7 @@ local function featuresprocessor(head,font,attr)
-- Keeping track of the headnode is needed for devanagari (I generalized it a bit
-- so that multiple cases are also covered.)
- -- We don't goto the next node of a disc node is created so that we can then treat
+ -- We don't goto the next node when a disc node is created so that we can then treat
-- the pre, post and replace. It's a bit of a hack but works out ok for most cases.
for s=1,#datasets do
@@ -3527,16 +3545,26 @@ local function featuresprocessor(head,font,attr)
-- whatever glyph
start = getnext(start)
elseif id == disc_code then
- local ok
- if gpossing then
- start, ok = kernrun(start,k_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
- elseif typ == "gsub_ligature" then
- start, ok = testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ -- ctx: we could assume the same attr as the surrounding glyphs but then we loose
+ -- the option to have interesting disc nodes (we gain upto 10% on extreme tests);
+ -- if a disc would have a font field we could even be more strict (see oldstyle test
+ -- case)
+ local a = forcedisc or getsubtype(start) == discretionary_code or getattr(start,0) == attr
+ if a then
+ -- local attr = false
+ local ok
+ if gpossing then
+ start, ok = kernrun(start,k_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ elseif typ == "gsub_ligature" then
+ start, ok = testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ else
+ start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ end
+ if ok then
+ success = true
+ end
else
- start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
- end
- if ok then
- success = true
+ start = getnext(start)
end
elseif id == math_code then
start = getnext(end_of_math(start))
@@ -3596,16 +3624,22 @@ local function featuresprocessor(head,font,attr)
elseif char == false then
start = getnext(start)
elseif id == disc_code then
- local ok
- if gpossing then
- start, ok = kernrun(start,k_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
- elseif typ == "gsub_ligature" then
- start, ok = testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ -- see comment above
+ local a = forcedisc or getsubtype(start) == discretionary_code or getattr(start,0) == attr
+ if a then
+ local ok
+ if gpossing then
+ start, ok = kernrun(start,k_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ elseif typ == "gsub_ligature" then
+ start, ok = testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ else
+ start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ end
+ if ok then
+ success = true
+ end
else
- start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
- end
- if ok then
- success = true
+ start = getnext(start)
end
elseif id == math_code then
start = getnext(end_of_math(start))
@@ -3637,6 +3671,34 @@ end
-- so far
+local plugins = { }
+otf.plugins = plugins
+
+function otf.registerplugin(name,f)
+ if type(name) == "string" and type(f) == "function" then
+ plugins[name] = { name, f }
+ end
+end
+
+local function plugininitializer(tfmdata,value)
+ if type(value) == "string" then
+ tfmdata.shared.plugin = plugins[value]
+ end
+end
+
+local function pluginprocessor(head,font)
+ local s = fontdata[font].shared
+ local p = s and s.plugin
+ if p then
+ if trace_plugins then
+ report_process("applying plugin %a",p[1])
+ end
+ return p[2](head,font)
+ else
+ return head, false
+ end
+end
+
local function featuresinitializer(tfmdata,value)
-- nothing done here any more
end
@@ -3648,9 +3710,11 @@ registerotffeature {
initializers = {
position = 1,
node = featuresinitializer,
+ plug = plugininitializer,
},
processors = {
node = featuresprocessor,
+ plug = pluginprocessor,
}
}
diff --git a/src/fontloader/misc/fontloader-util-fil.lua b/src/fontloader/misc/fontloader-util-fil.lua
index eeb6856..0f9731a 100644
--- a/src/fontloader/misc/fontloader-util-fil.lua
+++ b/src/fontloader/misc/fontloader-util-fil.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['util-fil'] = {
local byte = string.byte
local char = string.char
-local extract = bit32.extract
+local extract = bit32 and bit32.extract
local floor = math.floor
-- Here are a few helpers (the starting point were old ones I used for parsing
@@ -109,6 +109,10 @@ function files.readcardinal2(f)
local a, b = byte(f:read(2),1,2)
return 0x100 * a + b
end
+function files.readcardinal2le(f)
+ local b, a = byte(f:read(2),1,2)
+ return 0x100 * a + b
+end
function files.readinteger2(f)
local a, b = byte(f:read(2),1,2)
@@ -120,11 +124,25 @@ function files.readinteger2(f)
return n
end
end
+function files.readinteger2le(f)
+ local b, a = byte(f:read(2),1,2)
+ local n = 0x100 * a + b
+ if n >= 0x8000 then
+ -- return n - 0xFFFF - 1
+ return n - 0x10000
+ else
+ return n
+ end
+end
function files.readcardinal3(f)
local a, b, c = byte(f:read(3),1,3)
return 0x10000 * a + 0x100 * b + c
end
+function files.readcardinal3le(f)
+ local c, b, a = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+end
function files.readinteger3(f)
local a, b, c = byte(f:read(3),1,3)
@@ -136,11 +154,25 @@ function files.readinteger3(f)
return n
end
end
+function files.readinteger3le(f)
+ local c, b, a = byte(f:read(3),1,3)
+ local n = 0x10000 * a + 0x100 * b + c
+ if n >= 0x80000 then
+ -- return n - 0xFFFFFF - 1
+ return n - 0x1000000
+ else
+ return n
+ end
+end
function files.readcardinal4(f)
local a, b, c, d = byte(f:read(4),1,4)
return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
end
+function files.readcardinal4le(f)
+ local d, c, b, a = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+end
function files.readinteger4(f)
local a, b, c, d = byte(f:read(4),1,4)
@@ -152,6 +184,16 @@ function files.readinteger4(f)
return n
end
end
+function files.readinteger4le(f)
+ local d, c, b, a = byte(f:read(4),1,4)
+ local n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+ if n >= 0x8000000 then
+ -- return n - 0xFFFFFFFF - 1
+ return n - 0x100000000
+ else
+ return n
+ end
+end
function files.readfixed4(f)
local a, b, c, d = byte(f:read(4),1,4)
@@ -164,17 +206,21 @@ function files.readfixed4(f)
end
end
-function files.read2dot14(f)
- local a, b = byte(f:read(2),1,2)
- local n = 0x100 * a + b
- local m = extract(n,0,30)
- if n > 0x7FFF then
- n = extract(n,30,2)
- return m/0x4000 - 4
- else
- n = extract(n,30,2)
- return n + m/0x4000
+if extract then
+
+ function files.read2dot14(f)
+ local a, b = byte(f:read(2),1,2)
+ local n = 0x100 * a + b
+ local m = extract(n,0,30)
+ if n > 0x7FFF then
+ n = extract(n,30,2)
+ return m/0x4000 - 4
+ else
+ n = extract(n,30,2)
+ return n + m/0x4000
+ end
end
+
end
function files.skipshort(f,n)
diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua
index c93d2b1..a0b906d 100644
--- a/src/fontloader/runtime/fontloader-reference.lua
+++ b/src/fontloader/runtime/fontloader-reference.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 09/24/16 12:40:11
+-- merge date : 10/19/16 22:51:32
do -- begin closure to overcome local limits and interference
@@ -4166,7 +4166,7 @@ if not modules then modules={} end modules ['util-fil']={
}
local byte=string.byte
local char=string.char
-local extract=bit32.extract
+local extract=bit32 and bit32.extract
local floor=math.floor
utilities=utilities or {}
local files={}
@@ -4245,6 +4245,10 @@ function files.readcardinal2(f)
local a,b=byte(f:read(2),1,2)
return 0x100*a+b
end
+function files.readcardinal2le(f)
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+end
function files.readinteger2(f)
local a,b=byte(f:read(2),1,2)
local n=0x100*a+b
@@ -4254,10 +4258,23 @@ function files.readinteger2(f)
return n
end
end
+function files.readinteger2le(f)
+ local b,a=byte(f:read(2),1,2)
+ local n=0x100*a+b
+ if n>=0x8000 then
+ return n-0x10000
+ else
+ return n
+ end
+end
function files.readcardinal3(f)
local a,b,c=byte(f:read(3),1,3)
return 0x10000*a+0x100*b+c
end
+function files.readcardinal3le(f)
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+end
function files.readinteger3(f)
local a,b,c=byte(f:read(3),1,3)
local n=0x10000*a+0x100*b+c
@@ -4267,10 +4284,23 @@ function files.readinteger3(f)
return n
end
end
+function files.readinteger3le(f)
+ local c,b,a=byte(f:read(3),1,3)
+ local n=0x10000*a+0x100*b+c
+ if n>=0x80000 then
+ return n-0x1000000
+ else
+ return n
+ end
+end
function files.readcardinal4(f)
local a,b,c,d=byte(f:read(4),1,4)
return 0x1000000*a+0x10000*b+0x100*c+d
end
+function files.readcardinal4le(f)
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+end
function files.readinteger4(f)
local a,b,c,d=byte(f:read(4),1,4)
local n=0x1000000*a+0x10000*b+0x100*c+d
@@ -4280,6 +4310,15 @@ function files.readinteger4(f)
return n
end
end
+function files.readinteger4le(f)
+ local d,c,b,a=byte(f:read(4),1,4)
+ local n=0x1000000*a+0x10000*b+0x100*c+d
+ if n>=0x8000000 then
+ return n-0x100000000
+ else
+ return n
+ end
+end
function files.readfixed4(f)
local a,b,c,d=byte(f:read(4),1,4)
local n=0x100*a+b
@@ -4289,16 +4328,18 @@ function files.readfixed4(f)
return n+(0x100*c+d)/0xFFFF
end
end
-function files.read2dot14(f)
- local a,b=byte(f:read(2),1,2)
- local n=0x100*a+b
- local m=extract(n,0,30)
- if n>0x7FFF then
- n=extract(n,30,2)
- return m/0x4000-4
- else
- n=extract(n,30,2)
- return n+m/0x4000
+if extract then
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ local n=0x100*a+b
+ local m=extract(n,0,30)
+ if n>0x7FFF then
+ n=extract(n,30,2)
+ return m/0x4000-4
+ else
+ n=extract(n,30,2)
+ return n+m/0x4000
+ end
end
end
function files.skipshort(f,n)
@@ -6084,10 +6125,14 @@ function constructors.scale(tfmdata,specification)
local haskerns=properties.haskerns or properties.mode=="base"
local hasligatures=properties.hasligatures or properties.mode=="base"
local realdimensions=properties.realdimensions
+ local writingmode=properties.writingmode or "horizontal"
+ local identity=properties.identity or "horizontal"
if changed and not next(changed) then
changed=false
end
target.type=isvirtual and "virtual" or "real"
+ target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
+ target.identity=identity=="vertical" and "vertical" or "horizontal"
target.postprocessors=tfmdata.postprocessors
local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt
local targetspace=(parameters.space or parameters[2] or 0)*hdelta
@@ -6473,6 +6518,8 @@ function constructors.finalize(tfmdata)
cidinfo=tfmdata.cidinfo or nil,
format=tfmdata.format or "type1",
direction=tfmdata.direction or 0,
+ writingmode=tfmdata.writingmode or "horizontal",
+ identity=tfmdata.identity or "horizontal",
}
end
if not tfmdata.resources then
@@ -6611,7 +6658,11 @@ setmetatableindex(formats,function(t,k)
return rawget(t,file.suffix(l))
end)
do
- local function setindeed(mode,target,group,name,action,position)
+ local function setindeed(mode,source,target,group,name,position)
+ local action=source[mode]
+ if not action then
+ return
+ end
local t=target[mode]
if not t then
report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
@@ -6640,15 +6691,10 @@ do
report_defining("fatal source error in setting feature %a, group %a",name,group)
os.exit()
end
- local node=source.node
- local base=source.base
local position=source.position
- if node then
- setindeed("node",target,group,name,node,position)
- end
- if base then
- setindeed("base",target,group,name,base,position)
- end
+ setindeed("node",source,target,group,name,position)
+ setindeed("base",source,target,group,name,position)
+ setindeed("plug",source,target,group,name,position)
end
local function register(where,specification)
local name=specification.name
@@ -6710,9 +6756,9 @@ do
defaults={},
descriptions=tables and tables.features or {},
used=statistics and statistics.usedfeatures or {},
- initializers={ base={},node={} },
- processors={ base={},node={} },
- manipulators={ base={},node={} },
+ initializers={ base={},node={},plug={} },
+ processors={ base={},node={},plug={} },
+ manipulators={ base={},node={},plug={} },
}
features.register=function(specification) return register(features,specification) end
handler.features=features
@@ -7706,6 +7752,7 @@ registerotffeature {
initializers={
base=setmode,
node=setmode,
+ plug=setmode,
}
}
registerotffeature {
@@ -7714,6 +7761,7 @@ registerotffeature {
initializers={
base=setlanguage,
node=setlanguage,
+ plug=setlanguage,
}
}
registerotffeature {
@@ -7722,6 +7770,7 @@ registerotffeature {
initializers={
base=setscript,
node=setscript,
+ plug=setscript,
}
}
otftables.featuretypes=allocate {
@@ -8291,11 +8340,43 @@ readers.hhea=function(f,fontdata,specification)
reserved_3=readshort(f),
reserved_4=readshort(f),
metricdataformat=readshort(f),
- nofhmetrics=readushort(f),
+ nofmetrics=readushort(f),
}
else
fontdata.horizontalheader={
- nofhmetrics=0,
+ nofmetrics=0,
+ }
+ end
+ end
+end
+readers.vhea=function(f,fontdata,specification)
+ if specification.details then
+ local datatable=fontdata.tables.vhea
+ if datatable then
+ setposition(f,datatable.offset)
+ local version=readfixed(f)
+ fontdata.verticalheader={
+ version=version,
+ ascender=readfword(f),
+ descender=readfword(f),
+ linegap=readfword(f),
+ maxadvanceheight=readufword(f),
+ mintopsidebearing=readfword(f),
+ minbottomsidebearing=readfword(f),
+ maxextent=readfword(f),
+ caretsloperise=readshort(f),
+ caretsloperun=readshort(f),
+ caretoffset=readshort(f),
+ reserved_1=readshort(f),
+ reserved_2=readshort(f),
+ reserved_3=readshort(f),
+ reserved_4=readshort(f),
+ metricdataformat=readshort(f),
+ nofmetrics=readushort(f),
+ }
+ else
+ fontdata.verticalheader={
+ nofmetrics=0,
}
end
end
@@ -8346,7 +8427,8 @@ readers.hmtx=function(f,fontdata,specification)
local datatable=fontdata.tables.hmtx
if datatable then
setposition(f,datatable.offset)
- local nofmetrics=fontdata.horizontalheader.nofhmetrics
+ local horizontalheader=fontdata.horizontalheader
+ local nofmetrics=horizontalheader.nofmetrics
local glyphs=fontdata.glyphs
local nofglyphs=fontdata.nofglyphs
local width=0
@@ -8368,6 +8450,43 @@ readers.hmtx=function(f,fontdata,specification)
end
end
end
+readers.vmtx=function(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable=fontdata.tables.vmtx
+ if datatable then
+ setposition(f,datatable.offset)
+ local verticalheader=fontdata.verticalheader
+ local nofmetrics=verticalheader.nofmetrics
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local vheight=0
+ local vdefault=verticalheader.ascender+verticalheader.descender
+ local topsidebearing=0
+ for i=0,nofmetrics-1 do
+ local glyph=glyphs[i]
+ vheight=readshort(f)
+ topsidebearing=readshort(f)
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ end
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph=glyphs[i]
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ end
+ end
+ end
+end
+readers.vorg=function(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable=fontdata.tables.vorg
+ if datatable then
+ report("todo: %s","vorg")
+ end
+ end
+end
readers.post=function(f,fontdata,specification)
local datatable=fontdata.tables.post
if datatable then
@@ -8925,7 +9044,7 @@ function readers.math(f,fontdata,specification)
reportskippedtable("math")
end
end
-local function getinfo(maindata,sub,platformnames,rawfamilynames)
+local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo)
local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
local names=fontdata.names
local info=nil
@@ -8978,6 +9097,27 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames)
descender=metrics.typodescender,
platformnames=platformnames and fontdata.platformnames or nil,
}
+ if metricstoo then
+ local keys={
+ "version",
+ "ascender","descender","linegap",
+ "maxadvancewidth","maxadvanceheight","maxextent",
+ "minbottomsidebearing","mintopsidebearing",
+ }
+ local h=fontdata.horizontalheader or {}
+ local v=fontdata.verticalheader or {}
+ if h then
+ local th={}
+ local tv={}
+ for i=1,#keys do
+ local key=keys[i]
+ th[key]=h[key] or 0
+ tv[key]=v[key] or 0
+ end
+ info.horizontalmetrics=th
+ info.verticalmetrics=tv
+ end
+ end
elseif n then
info={
filename=fontdata.filename,
@@ -9061,7 +9201,10 @@ local function readdata(f,offset,specification)
readers["head"](f,fontdata,specification)
readers["maxp"](f,fontdata,specification)
readers["hhea"](f,fontdata,specification)
+ readers["vhea"](f,fontdata,specification)
readers["hmtx"](f,fontdata,specification)
+ readers["vmtx"](f,fontdata,specification)
+ readers["vorg"](f,fontdata,specification)
readers["post"](f,fontdata,specification)
readers["cff" ](f,fontdata,specification)
readers["cmap"](f,fontdata,specification)
@@ -9229,7 +9372,7 @@ function readers.loadfont(filename,n)
descriptions=fontdata.descriptions,
format=fontdata.format,
goodies={},
- metadata=getinfo(fontdata,n),
+ metadata=getinfo(fontdata,n,false,false,true),
properties={
hasitalics=fontdata.hasitalics or false,
maxcolorclass=fontdata.maxcolorclass,
@@ -15877,7 +16020,6 @@ local function getgsub(tfmdata,k,kind,value)
local properties=tfmdata.properties
local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language)
if validlookups then
- local choice=tonumber(value) or 1
for i=1,#lookuplist do
local lookup=lookuplist[i]
local steps=lookup.steps
@@ -18147,11 +18289,13 @@ local trace_details=false registertracker("otf.details",function(v) trace_detail
local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end)
local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end)
local trace_directions=false registertracker("otf.directions",function(v) trace_directions=v end)
+local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end)
local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end)
local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end)
local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end)
local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end)
local optimizekerns=true
+local alwaysdisc=true registerdirective("otf.alwaysdisc",function(v) alwaysdisc=v end)
local report_direct=logs.reporter("fonts","otf direct")
local report_subchain=logs.reporter("fonts","otf subchain")
local report_chain=logs.reporter("fonts","otf chain")
@@ -18533,7 +18677,7 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou
setlink(discfound,next)
setboth(base)
setfield(base,"components",copied)
- setdisc(discfound,pre,post,base,discretionary_code)
+ setdisc(discfound,pre,post,base)
base=prev
end
end
@@ -20702,6 +20846,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
return true,d>1
end
end
+ else
end
start=getnext(start)
else
@@ -20815,6 +20960,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
report_missing_coverage(dataset,sequence)
end
end
+ else
end
start=getnext(start)
else
@@ -20886,6 +21032,9 @@ local function pardirstate(start)
end
return getnext(start),new,new
end
+otf.helpers=otf.helpers or {}
+otf.helpers.txtdirstate=txtdirstate
+otf.helpers.pardirstate=pardirstate
local function featuresprocessor(head,font,attr)
local sequences=sequencelists[font]
if not sequencelists then
@@ -20913,6 +21062,7 @@ local function featuresprocessor(head,font,attr)
local rlmode=0
local done=false
local datasets=otf.dataset(tfmdata,font,attr)
+ local forcedisc=alwaysdisc or not attr
local dirstack={}
sweephead={}
for s=1,#datasets do
@@ -21005,16 +21155,21 @@ local function featuresprocessor(head,font,attr)
elseif char==false then
start=getnext(start)
elseif id==disc_code then
- local ok
- if gpossing then
- start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
- elseif typ=="gsub_ligature" then
- start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ local a=forcedisc or getsubtype(start)==discretionary_code or getattr(start,0)==attr
+ if a then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ elseif typ=="gsub_ligature" then
+ start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ else
+ start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
+ end
+ if ok then
+ success=true
+ end
else
- start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
- end
- if ok then
- success=true
+ start=getnext(start)
end
elseif id==math_code then
start=getnext(end_of_math(start))
@@ -21066,16 +21221,21 @@ local function featuresprocessor(head,font,attr)
elseif char==false then
start=getnext(start)
elseif id==disc_code then
- local ok
- if gpossing then
- start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
- elseif typ=="gsub_ligature" then
- start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ local a=forcedisc or getsubtype(start)==discretionary_code or getattr(start,0)==attr
+ if a then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ elseif typ=="gsub_ligature" then
+ start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ else
+ start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
+ end
+ if ok then
+ success=true
+ end
else
- start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
- end
- if ok then
- success=true
+ start=getnext(start)
end
elseif id==math_code then
start=getnext(end_of_math(start))
@@ -21100,6 +21260,30 @@ local function featuresprocessor(head,font,attr)
head=tonode(head)
return head,done
end
+local plugins={}
+otf.plugins=plugins
+function otf.registerplugin(name,f)
+ if type(name)=="string" and type(f)=="function" then
+ plugins[name]={ name,f }
+ end
+end
+local function plugininitializer(tfmdata,value)
+ if type(value)=="string" then
+ tfmdata.shared.plugin=plugins[value]
+ end
+end
+local function pluginprocessor(head,font)
+ local s=fontdata[font].shared
+ local p=s and s.plugin
+ if p then
+ if trace_plugins then
+ report_process("applying plugin %a",p[1])
+ end
+ return p[2](head,font)
+ else
+ return head,false
+ end
+end
local function featuresinitializer(tfmdata,value)
end
registerotffeature {
@@ -21109,9 +21293,11 @@ registerotffeature {
initializers={
position=1,
node=featuresinitializer,
+ plug=plugininitializer,
},
processors={
node=featuresprocessor,
+ plug=pluginprocessor,
}
}
otf.nodemodeinitializer=featuresinitializer
diff --git a/src/luaotfload-configuration.lua b/src/luaotfload-configuration.lua
index c707b63..8484c62 100644
--- a/src/luaotfload-configuration.lua
+++ b/src/luaotfload-configuration.lua
@@ -203,7 +203,6 @@ local default_config = {
update_live = true,
compress = true,
max_fonts = 2^51,
- use_fontforge = false,
},
run = {
anon_sequence = default_anon_sequence,
@@ -378,21 +377,6 @@ local set_default_features = function ()
return true
end
-local set_fontforge = function ()
- local names = fonts.names
- if not names or not names.use_fontforge then
- --- happens normally on the first run
- logreport ("log", 4, "db", "Database not present.")
- return true
- end
- local use_ff = config.luaotfload.db.use_fontforge
- if use_ff == true then
- logreport ("both", 0, "db",
- "Fontforge loader was requested but not supported anymore.")
- end
- return true
-end
-
reconf_tasks = {
{ "Set the log level" , set_loglevel },
{ "Build cache paths" , build_cache_paths },
@@ -400,7 +384,6 @@ reconf_tasks = {
{ "Set the font filter" , set_font_filter },
{ "Install font name resolver", set_name_resolver },
{ "Set default features" , set_default_features },
- { "Set fontforge" , set_fontforge },
}
-------------------------------------------------------------------------------
@@ -499,7 +482,6 @@ local option_spec = {
out_t = number_t, --- TODO int_t from 5.3.x on
transform = tointeger,
},
- use_fontforge = { in_t = boolean_t, },
},
run = {
anon_sequence = {
@@ -723,7 +705,6 @@ local formatters = {
skip_read = { false, format_boolean },
strip = { false, format_boolean },
update_live = { false, format_boolean },
- use_fontforge = { false, format_boolean },
},
default_features = {
__default = { true, format_keyval },
diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua
index 41080cf..c6ccaa6 100644
--- a/src/luaotfload-database.lua
+++ b/src/luaotfload-database.lua
@@ -1511,7 +1511,6 @@ end
local organize_styledata = function (metadata, rawinfo, info)
local pfminfo = metadata.pfminfo
local names = rawinfo.names
-
return {
--- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size
size = get_size_info (rawinfo),
@@ -2553,6 +2552,7 @@ generate_filedata = function (mappings)
end
local bold_spectrum_low = 501 --- 500 is medium, 900 heavy/black
+local normal_weight = 400
local bold_weight = 700
local normal_width = 5
@@ -2606,12 +2606,18 @@ do
treating weights > 500 as bold or allowing synonyms like
“heavy”, “black”.
--]]--
- if width == normal_width and pfmweight == bold_weight then
- --- bold spectrum matches
- if italicangle == 0 then
- return "b"
+ if width == normal_width then
+ if pfmweight == bold_weight then
+ --- bold spectrum matches
+ if italicangle == 0 then
+ return "b"
+ end
+ return "bi"
+ elseif pfmweight == normal_weight then
+ if italicangle ~= 0 then
+ return "i"
+ end
end
- return "bi"
end
return false
end
@@ -3578,8 +3584,6 @@ local export = {
erase_cache = erase_cache,
show_cache = show_cache,
find_closest = find_closest,
- --- transitionary
- use_fontforge = false,
}
return {
diff --git a/src/luaotfload-features.lua b/src/luaotfload-features.lua
index 285482f..a57aac3 100644
--- a/src/luaotfload-features.lua
+++ b/src/luaotfload-features.lua
@@ -1243,7 +1243,7 @@ local handle_request = function (specification)
specification.features = features
end
features.normal = normalize (request.features)
- local subfont = tonumber (specification.sub)
+ local subfont = tonumber (request.sub)
if subfont and subfont >= 0 then
specification.sub = subfont + 1
else
diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua
index 271e4cc..83ce5e7 100644
--- a/src/luaotfload-main.lua
+++ b/src/luaotfload-main.lua
@@ -1,7 +1,7 @@
-----------------------------------------------------------------------
-- FILE: luaotfload-main.lua
-- DESCRIPTION: Luaotfload entry point
--- REQUIREMENTS: luatex v.0.95 or later; packages lualibs
+-- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs
-- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang
-----------------------------------------------------------------------
--
@@ -11,9 +11,9 @@ config = config or { }
luaotfload = luaotfload or { }
local luaotfload = luaotfload
luaotfload.log = luaotfload.log or { }
-luaotfload.version = "2.7"
+luaotfload.version = "2.8"
luaotfload.loaders = { }
-luaotfload.min_luatex_version = { 0, 95, 0 } --- i. e. 0.95.0
+luaotfload.min_luatex_version = { 0, 95, 0 }
luaotfload.fontloader_package = "reference" --- default: from current Context
if not tex or not tex.luatexversion then
@@ -25,8 +25,10 @@ else
local revision = tex.luatexrevision --[[ : string ]]
local revno = tonumber (revision)
local minimum = luaotfload.min_luatex_version
- if major < minimum [1] or minor < minimum [2]
- or revno and revno < minimum [3]
+ 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
texio.write_nl ("term and log",
string.format ("\tFATAL ERROR\n\z
diff --git a/src/luaotfload-tool.lua b/src/luaotfload-tool.lua
index fee5980..e7df3ce 100755
--- a/src/luaotfload-tool.lua
+++ b/src/luaotfload-tool.lua
@@ -2,7 +2,7 @@
-----------------------------------------------------------------------
-- FILE: luaotfload-tool.lua
-- DESCRIPTION: database functionality
--- REQUIREMENTS: luaotfload 2.7
+-- REQUIREMENTS: luaotfload 2.8
-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
-- LICENSE: GPL v2.0
-----------------------------------------------------------------------
@@ -10,7 +10,7 @@
luaotfload = luaotfload or { }
local version = "2.8"
luaotfload.version = version
-luaotfload.min_luatex_version = { 0, 95, 0 } --- i. e. 0.95.0
+luaotfload.min_luatex_version = { 0, 95, 0 }
luaotfload.self = "luaotfload-tool"
--[[doc--
@@ -64,8 +64,9 @@ do
actual = { major, minor, revno or 0 }
end
- if actual [1] < minimum [1] or actual [2] < minimum [2]
- or actual [3] < minimum [3]
+ 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
texio.write_nl ("term and log",
string.format ("\tFATAL ERROR\n\z
@@ -152,20 +153,8 @@ require "fontloader-font-cff"
require "fontloader-font-ttf"
require "fontloader-font-dsp"
require "fontloader-font-oup"
-require "fontloader-font-otl"
-require "fontloader-font-oto"
-------- "fontloader-font-otj"
-------- "fontloader-font-ota"
-------- "fontloader-font-ots"
-------- "fontloader-font-osd"
require "fontloader-font-onr"
-require "fontloader-font-one"
-require "fontloader-font-afk"
-require "fontloader-font-tfm"
-require "fontloader-font-lua"
require "fontloader-font-def"
-require "fontloader-fonts-ext"
-------- "fontloader-font-gbn"
fonts = fonts or { }
local fontsnames = fonts.names or { }
@@ -192,7 +181,7 @@ end
require "alt_getopt"
-loadmodule "log.lua" --- this populates the luaotfload.log.* namespace
+loadmodule "log" --- this populates the luaotfload.log.* namespace
loadmodule "parsers" --- fonts.conf, configuration, and request syntax
loadmodule "configuration" --- configuration file handling
loadmodule "database"
@@ -666,7 +655,7 @@ subfont_by_name = function (lst, askedname, n)
if fonts.names.sanitize_fontname (font.fullname) == askedname then
return font
end
- return subfont_by_name (lst, askedname, n)
+ return subfont_by_name (lst, askedname, n + 1)
end
return false
end
@@ -679,7 +668,7 @@ The font info knows two levels of detail:
returned by readers.loadfont().
--doc]]--
-local show_font_info = function (basename, askedname, detail)
+local show_font_info = function (basename, askedname, detail, subfont)
local filenames = fonts.names.data().files
local index = filenames.base[basename]
local fullname = filenames.full[index]
@@ -689,7 +678,7 @@ local show_font_info = function (basename, askedname, detail)
end
if fullname then
local shortinfo = fonts.handlers.otf.readers.getinfo (fullname, {
- subfont = nil,
+ subfont = subfont,
platformnames = true,
rawfamilynames = true,
})
@@ -712,7 +701,8 @@ local show_font_info = function (basename, askedname, detail)
[[%s is a font collection]], basename)
for subfont = 1, nfonts do
logreport (true, 1, "resolve",
- [[Showing info for font no. %d]], n)
+ [[Showing info for font no. %d]],
+ subfont)
show_info_items(shortinfo[subfont])
if detail == true then
show_full_info(fullname, subfont)
@@ -1184,7 +1174,8 @@ actions.query = function (job)
needle = tmpspec.resolved or tmpspec.name
end
elseif tmpspec.lookup == "file" then
- needle = tmpspec.name
+ needle = tmpspec.name
+ subfont = tmpspec.sub
end
if needle then
@@ -1202,7 +1193,8 @@ actions.query = function (job)
"Resolved file name %q", foundname)
end
if job.show_info then
- show_font_info (foundname, query, job.full_info)
+ logreport (false, 3, "resolve", "Dump extra info.")
+ show_font_info (foundname, query, job.full_info, subfont)
iowrite "\n"
end
else