From e064aa2dc70fb819cfdb6b3c0bdf1d081859584f Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Mon, 22 Feb 2010 14:26:34 +0200 Subject: Updating to latest ConTeXt beta (2010.02.23) Now many of our fixes are incorporated upstream or fixed in a different way. --- luaotfload.dtx | 2 +- otfl-font-dum.lua | 5 +- otfl-font-map.lua | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++-- otfl-font-otf.lua | 164 +++++------------------------------------------------- otfl-font-tfm.lua | 5 +- otfl-font-xtx.lua | 16 ++---- otfl-luat-dum.lua | 5 +- 7 files changed, 184 insertions(+), 174 deletions(-) diff --git a/luaotfload.dtx b/luaotfload.dtx index d481938..f543fd0 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -477,6 +477,7 @@ luaotfload.loadmodule('node-dum.lua') luaotfload.loadmodule('font-ini.lua') luaotfload.loadmodule('font-tfm.lua') luaotfload.loadmodule('font-cid.lua') +luaotfload.loadmodule('font-map.lua') luaotfload.loadmodule('font-ott.lua') luaotfload.loadmodule('font-otf.lua') luaotfload.loadmodule('font-otd.lua') @@ -487,7 +488,6 @@ luaotfload.loadmodule('font-ota.lua') luaotfload.loadmodule('font-otc.lua') luaotfload.loadmodule('font-def.lua') luaotfload.loadmodule('font-xtx.lua') -luaotfload.loadmodule('font-map.lua') luaotfload.loadmodule('font-dum.lua') luaotfload.loadmodule('font-clr.lua') diff --git a/otfl-font-dum.lua b/otfl-font-dum.lua index 94dc676..5b83b3b 100644 --- a/otfl-font-dum.lua +++ b/otfl-font-dum.lua @@ -10,8 +10,9 @@ fonts = fonts or { } -- general -fonts.otf.pack = false -fonts.tfm.resolve_vf = false -- no sure about this +fonts.otf.pack = false +fonts.tfm.resolve_vf = false -- no sure about this +fonts.tfm.fontname_mode = "specification" -- somehow latex needs this -- readers diff --git a/otfl-font-map.lua b/otfl-font-map.lua index 9e85516..9dd2bd0 100644 --- a/otfl-font-map.lua +++ b/otfl-font-map.lua @@ -6,10 +6,13 @@ if not modules then modules = { } end modules ['font-map'] = { license = "see context related readme files" } -local match, format, find, concat, gsub = string.match, string.format, string.find, table.concat, string.gsub +local utf = unicode.utf8 +local match, format, find, concat, gsub, lower = string.match, string.format, string.find, table.concat, string.gsub, string.lower local lpegmatch = lpeg.match +local utfbyte = utf.byte -local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) +local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) +local trace_unimapping = false trackers.register("otf.unimapping", function(v) trace_unimapping = v end) local ctxcatcodes = tex and tex.ctxcatcodes @@ -128,7 +131,7 @@ function fonts.map.load_file(filename, entries, encodings) return entries, encodings end -function fonts.map.load_lum_table(filename) +local function load_lum_table(filename) local lumname = file.replacesuffix(file.basename(filename),"lum") local lumfile = resolvers.find_file(lumname,"map") or "" if lumfile ~= "" and lfs.isfile(lumfile) then @@ -154,7 +157,7 @@ local parser = unicode + ucode + index local parsers = { } -function fonts.map.make_name_parser(str) +local function make_name_parser(str) if not str or str == "" then return parser else @@ -181,7 +184,7 @@ end --~ test("index1234") --~ test("Japan1.123") -function fonts.map.tounicode16(unicode) +local function tounicode16(unicode) if unicode < 0x10000 then return format("%04X",unicode) else @@ -189,7 +192,7 @@ function fonts.map.tounicode16(unicode) end end -function fonts.map.tounicode16sequence(unicodes) +local function tounicode16sequence(unicodes) local t = { } for l=1,#unicodes do local unicode = unicodes[l] @@ -222,3 +225,149 @@ end --~ return s --~ end +fonts.map.load_lum_table = load_lum_table +fonts.map.make_name_parser = make_name_parser +fonts.map.tounicode16 = tounicode16 +fonts.map.tounicode16sequence = tounicode16sequence + +local separator = lpeg.S("_.") +local other = lpeg.C((1 - separator)^1) +local ligsplitter = lpeg.Ct(other * (separator * other)^0) + +--~ print(table.serialize(lpegmatch(ligsplitter,"this"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"this.that"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"japan1.123"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more"))) +--~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more.that"))) + +fonts.map.add_to_unicode = function(data,filename) + local unicodes = data.luatex and data.luatex.unicodes + if not unicodes then + return + end + -- we need to move this code + unicodes['space'] = unicodes['space'] or 32 + unicodes['hyphen'] = unicodes['hyphen'] or 45 + unicodes['zwj'] = unicodes['zwj'] or 0x200D + unicodes['zwnj'] = unicodes['zwnj'] or 0x200C + -- the tounicode mapping is sparse and only needed for alternatives + local tounicode, originals, ns, nl, private, unknown = { }, { }, 0, 0, fonts.private, format("%04X",utfbyte("?")) + data.luatex.tounicode, data.luatex.originals = tounicode, originals + local lumunic, uparser, oparser + if false then -- will become an option + lumunic = load_lum_table(filename) + lumunic = lumunic and lumunic.tounicode + end + local cidinfo, cidnames, cidcodes = data.cidinfo + local usedmap = cidinfo and cidinfo.usedname + usedmap = usedmap and lower(usedmap) + usedmap = usedmap and fonts.cid.map[usedmap] + if usedmap then + oparser = usedmap and make_name_parser(cidinfo.ordering) + cidnames = usedmap.names + cidcodes = usedmap.unicodes + end + uparser = make_name_parser() + local aglmap = fonts.map and fonts.map.agl_to_unicode + for index, glyph in next, data.glyphs do + local name, unic = glyph.name, glyph.unicode or -1 -- play safe + if unic == -1 or unic >= private or (unic >= 0xE000 and unic <= 0xF8FF) or unic == 0xFFFE or unic == 0xFFFF then + local unicode = (lumunic and lumunic[name]) or (aglmap and aglmap[name]) + if unicode then + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + end + -- cidmap heuristics, beware, there is no guarantee for a match unless + -- the chain resolves + if (not unicode) and usedmap then + local foundindex = lpegmatch(oparser,name) + if foundindex then + unicode = cidcodes[foundindex] -- name to number + if unicode then + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + else + local reference = cidnames[foundindex] -- number to name + if reference then + local foundindex = lpegmatch(oparser,reference) + if foundindex then + unicode = cidcodes[foundindex] + if unicode then + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + end + end + if not unicode then + local foundcodes, multiple = lpegmatch(uparser,reference) + if foundcodes then + if multiple then + originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true + else + originals[index], tounicode[index], ns, unicode = foundcodes, tounicode16(foundcodes), ns + 1, foundcodes + end + end + end + end + end + end + end + -- a.whatever or a_b_c.whatever or a_b_c (no numbers) + if not unicode then + local split = lpegmatch(ligsplitter,name) + local nplit = (split and #split) or 0 + if nplit == 0 then + -- skip + elseif nplit == 1 then + local base = split[1] + unicode = unicodes[base] or (aglmap and aglmap[base]) + if unicode then + if type(unicode) == "table" then + unicode = unicode[1] + end + originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 + end + else + local t = { } + for l=1,nplit do + local base = split[l] + local u = unicodes[base] or (aglmap and aglmap[base]) + if not u then + break + elseif type(u) == "table" then + t[#t+1] = u[1] + else + t[#t+1] = u + end + end + if #t > 0 then -- done then + originals[index], tounicode[index], nl, unicode = t, tounicode16sequence(t), nl + 1, true + end + end + end + -- last resort + if not unicode then + local foundcodes, multiple = lpegmatch(uparser,name) + if foundcodes then + if multiple then + originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true + else + originals[index], tounicode[index], ns, unicode = foundcodes, tounicode16(foundcodes), ns + 1, foundcodes + end + end + end + if not unicode then + originals[index], tounicode[index] = 0xFFFD, "FFFD" + end + end + end + if trace_unimapping then + for index, glyph in table.sortedpairs(data.glyphs) do + local toun, name, unic = tounicode[index], glyph.name, glyph.unicode or -1 -- play safe + if toun then + logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X, tounicode: %s",index,name,unic,toun) + else + logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X",index,name,unic) + end + end + end + if trace_loading and (ns > 0 or nl > 0) then + logs.report("load otf","enhance: %s tounicode entries added (%s ligatures)",nl+ns, ns) + end +end diff --git a/otfl-font-otf.lua b/otfl-font-otf.lua index efe1319..94f5dcf 100644 --- a/otfl-font-otf.lua +++ b/otfl-font-otf.lua @@ -19,14 +19,10 @@ local trace_features = false trackers.register("otf.features", function(v local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end) local trace_sequences = false trackers.register("otf.sequences", function(v) trace_sequences = v end) local trace_math = false trackers.register("otf.math", function(v) trace_math = v end) -local trace_unimapping = false trackers.register("otf.unimapping", function(v) trace_unimapping = v end) local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) --~ trackers.enable("otf.loading") -local zwnj = 0x200C -local zwj = 0x200D - --[[ldx--

The fontforge table has organized lookups in a certain way. A first implementation of this code was organized featurewise: information related to features was @@ -84,7 +80,7 @@ otf.features.default = otf.features.default or { } otf.enhancers = otf.enhancers or { } otf.glists = { "gsub", "gpos" } -otf.version = 2.643 -- beware: also sync font-mis.lua +otf.version = 2.645 -- beware: also sync font-mis.lua otf.pack = true -- beware: also sync font-mis.lua otf.syncspace = true otf.notdef = false @@ -179,7 +175,7 @@ otf.tables.valid_fields = { local function load_featurefile(ff,featurefile) if featurefile then - featurefile = resolvers.find_file(file.addsuffix(featurefile,'fea')) -- "FONTFEATURES" + featurefile = resolvers.find_file(file.addsuffix(featurefile,'fea'),'fea') if featurefile and featurefile ~= "" then if trace_loading then logs.report("load otf", "featurefile: %s", featurefile) @@ -502,145 +498,7 @@ otf.enhancers["analyse marks"] = function(data,filename) end end -local separator = lpeg.S("_.") -local other = lpeg.C((1 - separator)^1) -local ligsplitter = lpeg.Ct(other * (separator * other)^0) - ---~ print(table.serialize(lpegmatch(ligsplitter,"this"))) ---~ print(table.serialize(lpegmatch(ligsplitter,"this.that"))) ---~ print(table.serialize(lpegmatch(ligsplitter,"japan1.123"))) ---~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more"))) ---~ print(table.serialize(lpegmatch(ligsplitter,"such_so_more.that"))) - -otf.enhancers["analyse unicodes"] = function(data,filename) - local tounicode16, tounicode16sequence = fonts.map.tounicode16, fonts.map.tounicode16sequence - local unicodes = data.luatex.unicodes - -- we need to move this code - unicodes['space'] = unicodes['space'] or 32 -- handly later on - unicodes['hyphen'] = unicodes['hyphen'] or 45 -- handly later on - unicodes['zwj'] = unicodes['zwj'] or zwj -- handly later on - unicodes['zwnj'] = unicodes['zwnj'] or zwnj -- handly later on - -- the tounicode mapping is sparse and only needed for alternatives - local tounicode, originals, ns, nl, private, unknown = { }, { }, 0, 0, fonts.private, format("%04X",utfbyte("?")) - data.luatex.tounicode, data.luatex.originals = tounicode, originals - local lumunic, uparser, oparser - if false then -- will become an option - lumunic = fonts.map.load_lum_table(filename) - lumunic = lumunic and lumunic.tounicode - end - local cidinfo, cidnames, cidcodes = data.cidinfo - local usedmap = cidinfo and cidinfo.usedname - usedmap = usedmap and lower(usedmap) - usedmap = usedmap and fonts.cid.map[usedmap] - if usedmap then - oparser = usedmap and fonts.map.make_name_parser(cidinfo.ordering) - cidnames = usedmap.names - cidcodes = usedmap.unicodes - end - uparser = fonts.map.make_name_parser() - local aglmap = fonts.map and fonts.map.agl_to_unicode - for index, glyph in next, data.glyphs do - local name, unic = glyph.name, glyph.unicode or -1 -- play safe - if unic == -1 or unic >= private or (unic >= 0xE000 and unic <= 0xF8FF) or unic == 0xFFFE or unic == 0xFFFF then - local unicode = lumunic and lumunic[name] - if unicode then - originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 - end - -- cidmap heuristics, beware, there is no guarantee for a match unless - -- the chain resolves - if (not unicode) and usedmap then - local foundindex = lpegmatch(oparser,name) - if foundindex then - unicode = cidcodes[foundindex] -- name to number - if unicode then - originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 - else - local reference = cidnames[foundindex] -- number to name - if reference then - local foundindex = lpegmatch(oparser,reference) - if foundindex then - unicode = cidcodes[foundindex] - if unicode then - originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 - end - end - if not unicode then - local foundcodes, multiple = lpegmatch(uparser,reference) - if foundcodes then - if multiple then - originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true - else - originals[index], tounicode[index], ns, unicode = foundcodes, tounicode16(foundcodes), ns + 1, foundcodes - end - end - end - end - end - end - end - -- a.whatever or a_b_c.whatever or a_b_c (no numbers) - if not unicode then - local split = lpegmatch(ligsplitter,name) - local nplit = (split and #split) or 0 - if nplit == 0 then - -- skip - elseif nplit == 1 then - local base = split[1] - unicode = unicodes[base] or (agl and agl[base]) - if unicode then - if type(unicode) == "table" then - unicode = unicode[1] - end - originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1 - end - else - local t = { } - for l=1,nplit do - local base = split[l] - local u = unicodes[base] or (agl and agl[base]) - if not u then - break - elseif type(u) == "table" then - t[#t+1] = u[1] - else - t[#t+1] = u - end - end - if #t > 0 then -- done then - originals[index], tounicode[index], nl, unicode = t, tounicode16sequence(t), nl + 1, true - end - end - end - -- last resort - if not unicode then - local foundcodes, multiple = lpegmatch(uparser,name) - if foundcodes then - if multiple then - originals[index], tounicode[index], nl, unicode = foundcodes, tounicode16sequence(foundcodes), nl + 1, true - else - originals[index], tounicode[index], ns, unicode = foundcodes, tounicode16(foundcodes), ns + 1, foundcodes - end - end - end - if not unicode then - originals[index], tounicode[index] = 0xFFFD, "FFFD" - end - end - end - if trace_unimapping then - for index, glyph in table.sortedpairs(data.glyphs) do - local toun, name, unic = tounicode[index], glyph.name, glyph.unicode or -1 -- play safe - if toun then - logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X, tounicode: %s",index,name,unic,toun) - else - logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X",index,name,unic) - end - end - end - if trace_loading and (ns > 0 or nl > 0) then - logs.report("load otf","enhance: %s tounicode entries added (%s ligatures)",nl+ns, ns) - end -end +otf.enhancers["analyse unicodes"] = fonts.map.add_to_unicode otf.enhancers["analyse subtables"] = function(data,filename) data.luatex = data.luatex or { } @@ -1785,8 +1643,7 @@ function tfm.read_from_open_type(specification) local tfmtable = otf.otf_to_tfm(specification) if tfmtable then local otfdata = tfmtable.shared.otfdata ---KH tfmtable.name = specification.name - tfmtable.name = specification.specification -- see mpg/luaotfload#3 + tfmtable.name = specification.name tfmtable.sub = specification.sub local s = specification.size local m = otfdata.metadata.math @@ -1837,8 +1694,17 @@ function tfm.read_from_open_type(specification) else tfmtable.format = specification.format end ---KH tfmtable.name = tfmtable.filename or tfmtable.fullname or tfmtable.fontname - tfmtable.name = tfmtable.name or tfmtable.filename or tfmtable.fullname or tfmtable.fontname -- see mpg/luaotfload#3 + tfmtable.name = tfmtable.filename or tfmtable.fullname or tfmtable.fontname + if tfm.fontname_mode == "specification" then + -- not to be used in context ! + local specname = specification.specification + if specname then + tfmtable.name = specname + if trace_defining then + logs.report("define font","overloaded fontname: '%s'",specname) + end + end + end end fonts.logger.save(tfmtable,file.extname(specification.filename),specification) end diff --git a/otfl-font-tfm.lua b/otfl-font-tfm.lua index 2f96de4..fd3d8b4 100644 --- a/otfl-font-tfm.lua +++ b/otfl-font-tfm.lua @@ -47,6 +47,7 @@ supplied by .

tfm.resolve_vf = true -- false tfm.share_base_kerns = false -- true (.5 sec slower on mk but brings down mem from 410M to 310M, beware: then script/lang share too) tfm.mathactions = { } +tfm.fontname_mode = "fullpath" function tfm.enhance(tfmdata,specification) local name, size = specification.name, specification.size @@ -874,7 +875,5 @@ fonts.initializers.node.tfm.remap = tfm.remap -- status info statistics.register("fonts load time", function() - if statistics.elapsedindeed(fonts) then - return format("%s seconds",statistics.elapsedtime(fonts)) - end + return statistics.elapsedseconds(fonts) end) diff --git a/otfl-font-xtx.lua b/otfl-font-xtx.lua index e7137c5..fd0a474 100644 --- a/otfl-font-xtx.lua +++ b/otfl-font-xtx.lua @@ -162,8 +162,6 @@ local function isfile () list.lookup = 'file' end local function isname () list.lookup = 'name' end local function thename(s) list.name = s end local function issub (v) list.sub = v end -local function istrue (s) list[s] = 'yes' end -local function isfalse(s) list[s] = nil end -- was no, see mpg/luaotfload#4 --KH local function iskey (k,v) if k == "script" then parse_script(v) @@ -171,6 +169,9 @@ local function iskey (k,v) list[k] = v end +local function istrue (s) list[s] = true end +local function isfalse(s) list[s] = false end + local spaces = lpeg.P(" ")^0 -- ER: now accepting names like C:/program files/texlive/2009/... local namespec = (lpeg.R("az", "AZ") * lpeg.P(":"))^-1 * (1-lpeg.S("/:("))^1 -- was: (1-lpeg.S("/: ("))^0 @@ -178,11 +179,10 @@ local crapspec = spaces * lpeg.P("/") * (((1-lpeg.P(":"))^0)/isstyle) * spaces -- ER: can't understand why the 'file:' thing doesn't work with fontnames starting by c:... local filename = (lpeg.P("file:")/isfile * (namespec/thename)) + (lpeg.P("[") * lpeg.P(true)/isname * (((1-lpeg.P("]"))^0)/thename) * lpeg.P("]")) local fontname = (lpeg.P("name:")/isname * (namespec/thename)) + lpeg.P(true)/issome * (namespec/thename) -local sometext = (lpeg.R("az") + lpeg.R("AZ") + lpeg.R("09"))^1 +local sometext = (lpeg.R("az","AZ","09") + lpeg.S("+-."))^1 local truevalue = lpeg.P("+") * spaces * (sometext/istrue) local falsevalue = lpeg.P("-") * spaces * (sometext/isfalse) -local someval = (lpeg.S("+-.") + sometext)^1 -local keyvalue = (lpeg.C(sometext) * spaces * lpeg.P("=") * spaces * lpeg.C(someval))/iskey +local keyvalue = (lpeg.C(sometext) * spaces * lpeg.P("=") * spaces * lpeg.C(sometext))/iskey local somevalue = sometext/istrue local subvalue = lpeg.P("(") * (lpeg.C(lpeg.P(1-lpeg.S("()"))^1)/issub) * lpeg.P(")") -- for Kim local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces @@ -192,12 +192,6 @@ local pattern = (filename + fontname) * subvalue^0 * crapspec^0 * options^0 function fonts.define.specify.colonized(specification) -- xetex mode list = { } lpegmatch(pattern,specification.specification) - for k, v in next, list do - list[k] = v:is_boolean() - if type(list[a]) == "nil" then - list[k] = v - end - end if list.style then specification.style = list.style list.style = nil diff --git a/otfl-luat-dum.lua b/otfl-luat-dum.lua index a81131d..34dd9ed 100644 --- a/otfl-luat-dum.lua +++ b/otfl-luat-dum.lua @@ -57,12 +57,13 @@ local remapper = { ttf = "truetype fonts", ttc = "truetype fonts", dfont = "truetype dictionary", - cid = "other text files", -- will become "cid files" + cid = "cid maps", + fea = "font feature files", } function resolvers.find_file(name,kind) name = string.gsub(name,"\\","\/") - kind = kind and string.lower(kind) + kind = string.lower(kind) return kpse.find_file(name,(kind and kind ~= "" and (remapper[kind] or kind)) or "tex") end -- cgit v1.2.3