diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-otf.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/font-otf.lua | 496 |
1 files changed, 311 insertions, 185 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-otf.lua b/Master/texmf-dist/tex/context/base/font-otf.lua index c1f2f14fc6f..0a5d1cfea04 100644 --- a/Master/texmf-dist/tex/context/base/font-otf.lua +++ b/Master/texmf-dist/tex/context/base/font-otf.lua @@ -18,9 +18,9 @@ local utfbyte = utf.byte local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring local abs = math.abs -local getn = table.getn +local insert = table.insert local lpegmatch = lpeg.match -local reversed, concat, remove = table.reversed, table.concat, table.remove +local reversed, concat, remove, sortedkeys = table.reversed, table.concat, table.remove, table.sortedkeys local ioflush = io.flush local fastcopy, tohash, derivetable = table.fastcopy, table.tohash, table.derive local formatters = string.formatters @@ -48,7 +48,7 @@ local otf = fonts.handlers.otf otf.glists = { "gsub", "gpos" } -otf.version = 2.743 -- beware: also sync font-mis.lua +otf.version = 2.755 -- beware: also sync font-mis.lua otf.cache = containers.define("fonts", "otf", otf.version, true) local fontdata = fonts.hashes.identifiers @@ -73,6 +73,9 @@ local packdata = true local syncspace = true local forcenotdef = false local includesubfonts = false +local overloadkerns = false -- experiment + +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes local wildcard = "*" local default = "dflt" @@ -81,12 +84,50 @@ local fontloaderfields = fontloader.fields local mainfields = nil local glyphfields = nil -- not used yet +local formats = fonts.formats + +formats.otf = "opentype" +formats.ttf = "truetype" +formats.ttc = "truetype" +formats.dfont = "truetype" + registerdirective("fonts.otf.loader.cleanup", function(v) cleanup = tonumber(v) or (v and 1) or 0 end) registerdirective("fonts.otf.loader.force", function(v) forceload = v end) registerdirective("fonts.otf.loader.usemetatables", function(v) usemetatables = v end) registerdirective("fonts.otf.loader.pack", function(v) packdata = v end) registerdirective("fonts.otf.loader.syncspace", function(v) syncspace = v end) registerdirective("fonts.otf.loader.forcenotdef", function(v) forcenotdef = v end) +registerdirective("fonts.otf.loader.overloadkerns", function(v) overloadkerns = v end) + +function otf.fileformat(filename) + local leader = lower(io.loadchunk(filename,4)) + local suffix = lower(file.suffix(filename)) + if leader == "otto" then + return formats.otf, suffix == "otf" + elseif leader == "ttcf" then + return formats.ttc, suffix == "ttc" + -- elseif leader == "true" then + -- return formats.ttf, suffix == "ttf" + elseif suffix == "ttc" then + return formats.ttc, true + elseif suffix == "dfont" then + return formats.dfont, true + else + return formats.ttf, suffix == "ttf" + end +end + +-- local function otf_format(filename) +-- -- return formats[lower(file.suffix(filename))] +-- end + +local function otf_format(filename) + local format, okay = otf.fileformat(filename) + if not okay then + report_otf("font %a is actually an %a file",filename,format) + end + return format +end local function load_featurefile(raw,featurefile) if featurefile and featurefile ~= "" then @@ -198,7 +239,7 @@ local valid_fields = table.tohash { "upos", "use_typo_metrics", "uwidth", - -- "validation_state", + "validation_state", "version", "vert_base", "weight", @@ -321,7 +362,7 @@ function enhancers.register(what,action) -- only already registered can be overl actions[what] = action end -function otf.load(filename,format,sub,featurefile) +function otf.load(filename,sub,featurefile) -- second argument (format) is gone ! local base = file.basename(file.removesuffix(filename)) local name = file.removesuffix(base) local attr = lfs.attributes(filename) @@ -420,7 +461,7 @@ function otf.load(filename,format,sub,featurefile) data = { size = size, time = time, - format = format, + format = otf_format(filename), featuredata = featurefiles, resources = { filename = resolvers.unresolve(filename), -- no shortcut @@ -449,7 +490,7 @@ function otf.load(filename,format,sub,featurefile) }, goodies = { }, - helpers = { + helpers = { -- might go away tounicodelist = splitter, tounicodetable = lpeg.Ct(splitter), }, @@ -494,6 +535,9 @@ function otf.load(filename,format,sub,featurefile) report_otf("loading from cache using hash %a",hash) end enhance("unpack",data,filename,nil,false) + if applyruntimefixes then + applyruntimefixes(filename,data) + end enhance("add dimensions",data,filename,nil,false) if trace_sequences then showfeatureorder(data,filename) @@ -643,15 +687,22 @@ actions["prepare glyphs"] = function(data,filename,raw) local glyph = cidglyphs[index] if glyph then local unicode = glyph.unicode +if unicode >= 0x00E000 and unicode <= 0x00F8FF then + unicode = -1 +elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFD then + unicode = -1 +elseif unicode >= 0x100000 and unicode <= 0x10FFFD then + unicode = -1 +end local name = glyph.name or cidnames[index] - if not unicode or unicode == -1 or unicode >= criterium then + if not unicode or unicode == -1 then -- or unicode >= criterium then unicode = cidunicodes[index] end if unicode and descriptions[unicode] then report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) unicode = -1 end - if not unicode or unicode == -1 or unicode >= criterium then + if not unicode or unicode == -1 then -- or unicode >= criterium then if not name then name = format("u%06X",private) end @@ -703,7 +754,7 @@ actions["prepare glyphs"] = function(data,filename,raw) if glyph then local unicode = glyph.unicode local name = glyph.name - if not unicode or unicode == -1 or unicode >= criterium then + if not unicode or unicode == -1 then -- or unicode >= criterium then unicode = private unicodes[name] = private if trace_private then @@ -726,7 +777,7 @@ actions["prepare glyphs"] = function(data,filename,raw) } local altuni = glyph.altuni if altuni then - local d + -- local d for i=1,#altuni do local a = altuni[i] local u = a.unicode @@ -741,15 +792,15 @@ actions["prepare glyphs"] = function(data,filename,raw) vv = { [u] = unicode } variants[v] = vv end - elseif d then - d[#d+1] = u - else - d = { u } + -- elseif d then + -- d[#d+1] = u + -- else + -- d = { u } end end - if d then - duplicates[unicode] = d - end + -- if d then + -- duplicates[unicode] = d -- is this needed ? + -- end end else report_otf("potential problem: glyph %U is used but empty",index) @@ -765,6 +816,10 @@ end -- the next one is still messy but will get better when we have -- flattened map/enc tables in the font loader +-- the next one is not using a valid base for unicode privates +-- +-- PsuedoEncodeUnencoded(EncMap *map,struct ttfinfo *info) + actions["check encoding"] = function(data,filename,raw) local descriptions = data.descriptions local resources = data.resources @@ -777,9 +832,11 @@ actions["check encoding"] = function(data,filename,raw) local mapdata = raw.map or { } local unicodetoindex = mapdata and mapdata.map or { } + local indextounicode = mapdata and mapdata.backmap or { } -- local encname = lower(data.enc_name or raw.enc_name or mapdata.enc_name or "") local encname = lower(data.enc_name or mapdata.enc_name or "") local criterium = 0xFFFF -- for instance cambria has a lot of mess up there + local privateoffset = constructors.privateoffset -- end of messy @@ -787,42 +844,44 @@ actions["check encoding"] = function(data,filename,raw) if trace_loading then report_otf("checking embedded unicode map %a",encname) end - for unicode, index in next, unicodetoindex do -- altuni already covers this - if unicode <= criterium and not descriptions[unicode] then - local parent = indices[index] -- why nil? - if not parent then - report_otf("weird, unicode %U points to nowhere with index %H",unicode,index) + local reported = { } + -- we loop over the original unicode->index mapping but we + -- need to keep in mind that that one can have weird entries + -- so we need some extra checking + for maybeunicode, index in next, unicodetoindex do + if descriptions[maybeunicode] then + -- we ignore invalid unicodes (unicode = -1) (ff can map wrong to non private) + else + local unicode = indices[index] + if not unicode then + -- weird (cjk or so?) + elseif maybeunicode == unicode then + -- no need to add + elseif unicode > privateoffset then + -- we have a non-unicode else - local parentdescription = descriptions[parent] - if parentdescription then - local altuni = parentdescription.altuni - if not altuni then - altuni = { { unicode = parent } } - parentdescription.altuni = altuni - duplicates[parent] = { unicode } + local d = descriptions[unicode] + if d then + local c = d.copies + if c then + c[maybeunicode] = true else - local done = false - for i=1,#altuni do - if altuni[i].unicode == parent then - done = true - break - end - end - if not done then - -- let's assume simple cjk reuse - altuni[#altuni+1] = { unicode = parent } - table.insert(duplicates[parent],unicode) - end + d.copies = { [maybeunicode] = true } end - if trace_loading then - report_otf("weird, unicode %U points to nowhere with index %H",unicode,index) - end - else - report_otf("weird, unicode %U points to %U with index %H",unicode,index) + elseif index and not reported[index] then + report_otf("missing index %i",index) + reported[index] = true end end end end + for unicode, data in next, descriptions do + local d = data.copies + if d then + duplicates[unicode] = sortedkeys(d) + data.copies = nil + end + end elseif properties.cidinfo then report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname) else @@ -830,12 +889,15 @@ actions["check encoding"] = function(data,filename,raw) end if mapdata then - mapdata.map = { } -- clear some memory + mapdata.map = { } -- clear some memory + mapdata.backmap = { } -- clear some memory end end -- for the moment we assume that a font with lookups will not use --- altuni so we stick to kerns only +-- altuni so we stick to kerns only .. alternatively we can always +-- do an indirect lookup uni_to_uni . but then we need that in +-- all lookups actions["add duplicates"] = function(data,filename,raw) local descriptions = data.descriptions @@ -846,31 +908,43 @@ actions["add duplicates"] = function(data,filename,raw) local duplicates = resources.duplicates for unicode, d in next, duplicates do - for i=1,#d do - local u = d[i] - if not descriptions[u] then - local description = descriptions[unicode] - local duplicate = table.copy(description) -- else packing problem - duplicate.comment = format("copy of U+%05X", unicode) - descriptions[u] = duplicate - local n = 0 - for _, description in next, descriptions do - if kerns then - local kerns = description.kerns - for _, k in next, kerns do - local ku = k[unicode] - if ku then - k[u] = ku - n = n + 1 + local nofduplicates = #d + if nofduplicates > 4 then + if trace_loading then + report_otf("ignoring excessive duplicates of %U (n=%s)",unicode,nofduplicates) + end + else + -- local validduplicates = { } + for i=1,nofduplicates do + local u = d[i] + if not descriptions[u] then + local description = descriptions[unicode] + local n = 0 + for _, description in next, descriptions do + if kerns then + local kerns = description.kerns + for _, k in next, kerns do + local ku = k[unicode] + if ku then + k[u] = ku + n = n + 1 + end end end + -- todo: lookups etc + end + if u > 0 then -- and + local duplicate = table.copy(description) -- else packing problem + duplicate.comment = format("copy of U+%05X", unicode) + descriptions[u] = duplicate + -- validduplicates[#validduplicates+1] = u + if trace_loading then + report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n) + end end - -- todo: lookups etc - end - if trace_loading then - report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n) end end + -- duplicates[unicode] = #validduplicates > 0 and validduplicates or nil end end end @@ -1038,20 +1112,21 @@ local g_directions = { gsub_reversecontextchain = -1, gpos_reversecontextchain = -1, } - --- Research by Khaled Hosny has demonstrated that the font loader merges --- regular and AAT features and that these can interfere (especially because --- we dropped checking for valid features elsewhere. So, we just check for --- the special flag and drop the feature if such a tag is found. - -local function supported(features) - for i=1,#features do - if features[i].ismac then - return false - end - end - return true -end +-- The following is no longer needed as AAT is ignored per end October 2013. +-- +-- -- Research by Khaled Hosny has demonstrated that the font loader merges +-- -- regular and AAT features and that these can interfere (especially because +-- -- we dropped checking for valid features elsewhere. So, we just check for +-- -- the special flag and drop the feature if such a tag is found. +-- +-- local function supported(features) +-- for i=1,#features do +-- if features[i].ismac then +-- return false +-- end +-- end +-- return true +-- end actions["reorganize subtables"] = function(data,filename,raw) local resources = data.resources @@ -1066,8 +1141,7 @@ actions["reorganize subtables"] = function(data,filename,raw) for k=1,#dw do local gk = dw[k] local features = gk.features --- if features and supported(features) then - if not features or supported(features) then -- not always features ! + -- if not features or supported(features) then -- not always features ! local typ = gk.type local chain = g_directions[typ] or 0 local subtables = gk.subtables @@ -1101,10 +1175,16 @@ actions["reorganize subtables"] = function(data,filename,raw) elseif features then -- scripts, tag, ismac local f = { } + local o = { } for i=1,#features do local df = features[i] local tag = strip(lower(df.tag)) - local ft = f[tag] if not ft then ft = {} f[tag] = ft end + local ft = f[tag] + if not ft then + ft = { } + f[tag] = ft + o[#o+1] = tag + end local dscripts = df.scripts for i=1,#dscripts do local d = dscripts[i] @@ -1124,6 +1204,7 @@ actions["reorganize subtables"] = function(data,filename,raw) subtables = subtables, markclass = markclass, features = f, + order = o, } else lookups[name] = { @@ -1134,7 +1215,7 @@ actions["reorganize subtables"] = function(data,filename,raw) markclass = markclass, } end - end + -- end end end end @@ -1541,80 +1622,97 @@ actions["merge kern classes"] = function(data,filename,raw) local resources = data.resources local unicodes = resources.unicodes local splitter = data.helpers.tounicodetable + local ignored = 0 + local blocked = 0 for gp=1,#gposlist do local gpos = gposlist[gp] local subtables = gpos.subtables if subtables then + local first_done = { } -- could become an option so that we can deal with buggy fonts that don't get fixed + local split = { } -- saves time .. although probably not that much any more in the fixed luatex kernclass table for s=1,#subtables do local subtable = subtables[s] local kernclass = subtable.kernclass -- name is inconsistent with anchor_classes + local lookup = subtable.lookup or subtable.name if kernclass then -- the next one is quite slow - local split = { } -- saves time - for k=1,#kernclass do - local kcl = kernclass[k] - local firsts = kcl.firsts - local seconds = kcl.seconds - local offsets = kcl.offsets - local lookups = kcl.lookup -- singular - if type(lookups) ~= "table" then - lookups = { lookups } - end - -- if offsets[1] == nil then - -- offsets[1] = "" - -- end - -- we can check the max in the loop - -- local maxseconds = getn(seconds) - for n, s in next, firsts do - split[s] = split[s] or lpegmatch(splitter,s) - end - local maxseconds = 0 - for n, s in next, seconds do - if n > maxseconds then - maxseconds = n - end - split[s] = split[s] or lpegmatch(splitter,s) + if #kernclass > 0 then + kernclass = kernclass[1] + lookup = type(kernclass.lookup) == "string" and kernclass.lookup or lookup + report_otf("fixing kernclass table of lookup %a",lookup) + end + local firsts = kernclass.firsts + local seconds = kernclass.seconds + local offsets = kernclass.offsets + -- if offsets[1] == nil then + -- offsets[1] = "" -- defaults ? + -- end + for n, s in next, firsts do + split[s] = split[s] or lpegmatch(splitter,s) + end + local maxseconds = 0 + for n, s in next, seconds do + if n > maxseconds then + maxseconds = n end - for l=1,#lookups do - local lookup = lookups[l] - for fk=1,#firsts do -- maxfirsts ? - local fv = firsts[fk] - local splt = split[fv] - if splt then - local extrakerns = { } - local baseoffset = (fk-1) * maxseconds - for sk=2,maxseconds do -- will become 1 based in future luatex - local sv = seconds[sk] - -- for sk, sv in next, seconds do - local splt = split[sv] - if splt then -- redundant test - local offset = offsets[baseoffset + sk] - if offset then - for i=1,#splt do - extrakerns[splt[i]] = offset - end - end + split[s] = split[s] or lpegmatch(splitter,s) + end + for fk=1,#firsts do -- maxfirsts ? + local fv = firsts[fk] + local splt = split[fv] + if splt then + local extrakerns = { } + local baseoffset = (fk-1) * maxseconds + for sk=2,maxseconds do -- will become 1 based in future luatex + local sv = seconds[sk] + -- for sk, sv in next, seconds do + local splt = split[sv] + if splt then -- redundant test + local offset = offsets[baseoffset + sk] + if offset then + for i=1,#splt do + extrakerns[splt[i]] = offset end end - for i=1,#splt do - local first_unicode = splt[i] - local description = descriptions[first_unicode] - if description then - local kerns = description.kerns - if not kerns then - kerns = { } -- unicode indexed ! - description.kerns = kerns - end - local lookupkerns = kerns[lookup] - if not lookupkerns then - lookupkerns = { } - kerns[lookup] = lookupkerns - end + end + end + for i=1,#splt do + local first_unicode = splt[i] + if first_done[first_unicode] then + report_otf("lookup %a: ignoring further kerns of %C",lookup,first_unicode) + blocked = blocked + 1 + else + first_done[first_unicode] = true + local description = descriptions[first_unicode] + if description then + local kerns = description.kerns + if not kerns then + kerns = { } -- unicode indexed ! + description.kerns = kerns + end + local lookupkerns = kerns[lookup] + if not lookupkerns then + lookupkerns = { } + kerns[lookup] = lookupkerns + end + if overloadkerns then for second_unicode, kern in next, extrakerns do lookupkerns[second_unicode] = kern end - elseif trace_loading then - report_otf("no glyph data for %U", first_unicode) + else + for second_unicode, kern in next, extrakerns do + local k = lookupkerns[second_unicode] + if not k then + lookupkerns[second_unicode] = kern + elseif k ~= kern then + if trace_loading then + report_otf("lookup %a: ignoring overload of kern between %C and %C, rejecting %a, keeping %a",lookup,first_unicode,second_unicode,k,kern) + end + ignored = ignored + 1 + end + end end + elseif trace_loading then + report_otf("no glyph data for %U", first_unicode) end end end @@ -1625,6 +1723,12 @@ actions["merge kern classes"] = function(data,filename,raw) end end end + if ignored > 0 then + report_otf("%s kern overloads ignored",ignored) + end + if blocked > 0 then + report_otf("%s succesive kerns blocked",blocked) + end end end @@ -1653,6 +1757,13 @@ actions["check metadata"] = function(data,filename,raw) ttftables[i].data = "deleted" end end + -- + if metadata.validation_state and table.contains(metadata.validation_state,"bad_ps_fontname") then + local name = file.nameonly(filename) + metadata.fontname = "bad-fontname-" .. name + metadata.fullname = "bad-fullname-" .. name + end + -- end actions["cleanup tables"] = function(data,filename,raw) @@ -1894,10 +2005,24 @@ local function copytotfm(data,cache_id) end end -- end math + -- we need a runtime lookup because of running from cdrom or zip, brrr (shouldn't we use the basename then?) + local filename = constructors.checkedfilename(resources) + local fontname = metadata.fontname + local fullname = metadata.fullname or fontname + local units = metadata.units_per_em or 1000 + -- + if units == 0 then -- catch bugs in fonts + units = 1000 -- maybe 2000 when ttf + metadata.units_per_em = 1000 + report_otf("changing %a units to %a",0,units) + end + -- local monospaced = metadata.isfixedpitch or (pfminfo.panose and pfminfo.panose.proportion == "Monospaced") local charwidth = pfminfo.avgwidth -- or unset - local italicangle = metadata.italicangle local charxheight = pfminfo.os2_xheight and pfminfo.os2_xheight > 0 and pfminfo.os2_xheight +-- charwidth = charwidth * units/1000 +-- charxheight = charxheight * units/1000 + local italicangle = metadata.italicangle properties.monospaced = monospaced parameters.italicangle = italicangle parameters.charwidth = charwidth @@ -1927,16 +2052,6 @@ local function copytotfm(data,cache_id) end end spaceunits = tonumber(spaceunits) or 500 -- brrr - -- we need a runtime lookup because of running from cdrom or zip, brrr (shouldn't we use the basename then?) - local filename = constructors.checkedfilename(resources) - local fontname = metadata.fontname - local fullname = metadata.fullname or fontname - local units = metadata.units_per_em or 1000 - -- - if units == 0 then -- catch bugs in fonts - units = 1000 - metadata.units_per_em = 1000 - end -- parameters.slant = 0 parameters.space = spaceunits -- 3.333 (cmr10) @@ -1947,10 +2062,10 @@ local function copytotfm(data,cache_id) if spaceunits < 2*units/5 then -- todo: warning end - if italicangle then + if italicangle and italicangle ~= 0 then parameters.italicangle = italicangle parameters.italicfactor = math.cos(math.rad(90+italicangle)) - parameters.slant = - math.round(math.tan(italicangle*math.pi/180)) + parameters.slant = - math.tan(italicangle*math.pi/180) end if monospaced then parameters.space_stretch = 0 @@ -1979,7 +2094,10 @@ local function copytotfm(data,cache_id) -- properties.space = spacer properties.encodingbytes = 2 - properties.format = data.format or fonts.formats[filename] or "opentype" + properties.format = data.format or otf_format(filename) or formats.otf +-- if units ~= 1000 and format ~= "truetype" then +-- properties.format = "truetype" +-- end properties.noglyphnames = true properties.filename = filename properties.fontname = fontname @@ -2008,10 +2126,28 @@ local function otftotfm(specification) local name = specification.name local sub = specification.sub local filename = specification.filename - local format = specification.format + -- local format = specification.format local features = specification.features.normal - local rawdata = otf.load(filename,format,sub,features and features.featurefile) + local rawdata = otf.load(filename,sub,features and features.featurefile) if rawdata and next(rawdata) then + local descriptions = rawdata.descriptions + local duplicates = rawdata.resources.duplicates + if duplicates then + local nofduplicates, nofduplicated = 0, 0 + for parent, list in next, duplicates do + for i=1,#list do + local unicode = list[i] + if not descriptions[unicode] then + descriptions[unicode] = descriptions[parent] -- or copy + nofduplicated = nofduplicated + 1 + end + end + nofduplicates = nofduplicates + #list + end + if trace_otf and nofduplicated ~= nofduplicates then + report_otf("%i extra duplicates copied out of %i",nofduplicated,nofduplicates) + end + end rawdata.lookuphash = { } tfmdata = copytotfm(rawdata,cache_id) if tfmdata and next(tfmdata) then @@ -2104,48 +2240,38 @@ function otf.collectlookups(rawdata,kind,script,language) return nil, nil end --- readers +-- readers (a bit messy, this forced so I might redo that bit: foo.ttf FOO.ttf foo.TTF FOO.TTF) -local function check_otf(forced,specification,suffix,what) +local function check_otf(forced,specification,suffix) local name = specification.name if forced then - name = file.addsuffix(name,suffix,true) + name = specification.forcedname -- messy end local fullname = findbinfile(name,suffix) or "" if fullname == "" then fullname = fonts.names.getfilename(name,suffix) or "" end - if fullname ~= "" then + if fullname ~= "" and not fonts.names.ignoredfile(fullname) then specification.filename = fullname - specification.format = what return read_from_otf(specification) end end -local function opentypereader(specification,suffix,what) +local function opentypereader(specification,suffix) local forced = specification.forced or "" - if forced == "otf" then - return check_otf(true,specification,forced,"opentype") - elseif forced == "ttf" or forced == "ttc" or forced == "dfont" then - return check_otf(true,specification,forced,"truetype") + if formats[forced] then + return check_otf(true,specification,forced) else - return check_otf(false,specification,suffix,what) + return check_otf(false,specification,suffix) end end -readers.opentype = opentypereader - -local formats = fonts.formats - -formats.otf = "opentype" -formats.ttf = "truetype" -formats.ttc = "truetype" -formats.dfont = "truetype" +readers.opentype = opentypereader -- kind of useless and obsolete -function readers.otf (specification) return opentypereader(specification,"otf",formats.otf ) end -function readers.ttf (specification) return opentypereader(specification,"ttf",formats.ttf ) end -function readers.ttc (specification) return opentypereader(specification,"ttf",formats.ttc ) end -function readers.dfont(specification) return opentypereader(specification,"ttf",formats.dfont) end +function readers.otf (specification) return opentypereader(specification,"otf") end +function readers.ttf (specification) return opentypereader(specification,"ttf") end +function readers.ttc (specification) return opentypereader(specification,"ttf") end +function readers.dfont(specification) return opentypereader(specification,"ttf") end -- this will be overloaded |