diff options
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | doc/luaotfload-main.tex | 13 | ||||
-rw-r--r-- | doc/luaotfload.conf.rst | 5 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-font-con.lua | 31 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-font-oti.lua | 4 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-font-otl.lua | 2 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-font-otr.lua | 130 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-font-ots.lua | 108 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-util-fil.lua | 68 | ||||
-rw-r--r-- | src/fontloader/runtime/fontloader-reference.lua | 284 | ||||
-rw-r--r-- | src/luaotfload-configuration.lua | 19 | ||||
-rw-r--r-- | src/luaotfload-database.lua | 20 | ||||
-rw-r--r-- | src/luaotfload-features.lua | 2 | ||||
-rw-r--r-- | src/luaotfload-main.lua | 12 | ||||
-rwxr-xr-x | src/luaotfload-tool.lua | 38 |
15 files changed, 577 insertions, 177 deletions
@@ -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 |