summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/font-map.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-map.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/font-map.lua236
1 files changed, 75 insertions, 161 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-map.lua b/Master/texmf-dist/tex/context/base/font-map.lua
index 299508764a1..76733adeac6 100644
--- a/Master/texmf-dist/tex/context/base/font-map.lua
+++ b/Master/texmf-dist/tex/context/base/font-map.lua
@@ -6,15 +6,18 @@ if not modules then modules = { } end modules ['font-map'] = {
license = "see context related readme files"
}
-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 P, R, S, C, Ct, Cc, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.match
local utfbyte = utf.byte
-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 trace_loading = false trackers.register("fonts.loading", function(v) trace_loading = v end)
+local trace_mapping = false trackers.register("fonts.mapping", function(v) trace_unimapping = v end)
-local ctxcatcodes = tex and tex.ctxcatcodes
+local report_fonts = logs.reporter("fonts","loading") -- not otf only
+
+local fonts = fonts
+local mappings = { }
+fonts.mappings = mappings
--[[ldx--
<p>Eventually this code will disappear because map files are kind
@@ -22,50 +25,46 @@ of obsolete. Some code may move to runtime or auxiliary modules.</p>
<p>The name to unciode related code will stay of course.</p>
--ldx]]--
-fonts = fonts or { }
-fonts.map = fonts.map or { }
-
-local function load_lum_table(filename) -- will move to font goodies
+local function loadlumtable(filename) -- will move to font goodies
local lumname = file.replacesuffix(file.basename(filename),"lum")
- local lumfile = resolvers.find_file(lumname,"map") or ""
+ local lumfile = resolvers.findfile(lumname,"map") or ""
if lumfile ~= "" and lfs.isfile(lumfile) then
- if trace_loading or trace_unimapping then
- logs.report("load otf","enhance: loading %s ",lumfile)
+ if trace_loading or trace_mapping then
+ report_fonts("enhance: loading %s ",lumfile)
end
lumunic = dofile(lumfile)
return lumunic, lumfile
end
end
-local hex = lpeg.R("AF","09")
+local hex = R("AF","09")
local hexfour = (hex*hex*hex*hex) / function(s) return tonumber(s,16) end
local hexsix = (hex^1) / function(s) return tonumber(s,16) end
-local dec = (lpeg.R("09")^1) / tonumber
-local period = lpeg.P(".")
-
-local unicode = lpeg.P("uni") * (hexfour * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexfour^1) * lpeg.Cc(true))
-local ucode = lpeg.P("u") * (hexsix * (period + lpeg.P(-1)) * lpeg.Cc(false) + lpeg.Ct(hexsix ^1) * lpeg.Cc(true))
-local index = lpeg.P("index") * dec * lpeg.Cc(false)
+local dec = (R("09")^1) / tonumber
+local period = P(".")
+local unicode = P("uni") * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true))
+local ucode = P("u") * (hexsix * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true))
+local index = P("index") * dec * Cc(false)
local parser = unicode + ucode + index
local parsers = { }
-local function make_name_parser(str)
+local function makenameparser(str)
if not str or str == "" then
return parser
else
local p = parsers[str]
if not p then
- p = lpeg.P(str) * period * dec * lpeg.Cc(false)
+ p = P(str) * period * dec * Cc(false)
parsers[str] = p
end
return p
end
end
---~ local parser = fonts.map.make_name_parser("Japan1")
---~ local parser = fonts.map.make_name_parser()
+--~ local parser = mappings.makenameparser("Japan1")
+--~ local parser = mappings.makenameparser()
--~ local function test(str)
--~ local b, a = lpegmatch(parser,str)
--~ print((a and table.serialize(b)) or b)
@@ -106,7 +105,7 @@ end
--~
--~ local cache = { }
--~
---~ function fonts.map.tounicode16(unicode)
+--~ function mappings.tounicode16(unicode)
--~ local s = cache[unicode]
--~ if not s then
--~ if unicode < 0x10000 then
@@ -119,14 +118,14 @@ 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
+mappings.loadlumtable = loadlumtable
+mappings.makenameparser = makenameparser
+mappings.tounicode16 = tounicode16
+mappings.tounicode16sequence = tounicode16sequence
-local separator = lpeg.S("_.")
-local other = lpeg.C((1 - separator)^1)
-local ligsplitter = lpeg.Ct(other * (separator * other)^0)
+local separator = S("_.")
+local other = C((1 - separator)^1)
+local ligsplitter = Ct(other * (separator * other)^0)
--~ print(table.serialize(lpegmatch(ligsplitter,"this")))
--~ print(table.serialize(lpegmatch(ligsplitter,"this.that")))
@@ -134,8 +133,11 @@ local ligsplitter = lpeg.Ct(other * (separator * other)^0)
--~ 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
+function mappings.addtounicode(data,filename)
+ local resources = data.resources
+ local properties = data.properties
+ local descriptions = data.descriptions
+ local unicodes = resources.unicodes
if not unicodes then
return
end
@@ -145,28 +147,35 @@ fonts.map.add_to_unicode = function(data,filename)
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 private = fonts.constructors.privateoffset
+ local unknown = format("%04X",utfbyte("?"))
+ local unicodevector = fonts.encodings.agl.unicodes -- loaded runtime in context
+ local tounicode = { }
+ local originals = { }
+ resources.tounicode = tounicode
+ resources.originals = originals
local lumunic, uparser, oparser
+ local cidinfo, cidnames, cidcodes, usedmap
if false then -- will become an option
- lumunic = load_lum_table(filename)
+ lumunic = loadlumtable(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]
+ --
+ cidinfo = properties.cidinfo
+ usedmap = cidinfo and fonts.cid.getmap(cidinfo)
+ --
if usedmap then
- oparser = usedmap and make_name_parser(cidinfo.ordering)
+ oparser = usedmap and makenameparser(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
+ uparser = makenameparser()
+ local ns, nl = 0, 0
+ for unic, glyph in next, descriptions do
+ local index = glyph.index
+ local name = glyph.name
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])
+ local unicode = lumunic and lumunic[name] or unicodevector[name]
if unicode then
originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1
end
@@ -210,7 +219,7 @@ fonts.map.add_to_unicode = function(data,filename)
-- skip
elseif nplit == 1 then
local base = split[1]
- unicode = unicodes[base] or (aglmap and aglmap[base])
+ unicode = unicodes[base] or unicodevector[base]
if unicode then
if type(unicode) == "table" then
unicode = unicode[1]
@@ -218,19 +227,25 @@ fonts.map.add_to_unicode = function(data,filename)
originals[index], tounicode[index], ns = unicode, tounicode16(unicode), ns + 1
end
else
- local t = { }
+ local t, n = { }, 0
for l=1,nplit do
local base = split[l]
- local u = unicodes[base] or (aglmap and aglmap[base])
+ local u = unicodes[base] or unicodevector[base]
if not u then
break
elseif type(u) == "table" then
- t[#t+1] = u[1]
+ n = n + 1
+ t[n] = u[1]
else
- t[#t+1] = u
+ n = n + 1
+ t[n] = u
end
end
- if #t > 0 then -- done then
+ if n == 0 then -- done then
+ -- nothing
+ elseif n == 1 then
+ originals[index], tounicode[index], nl, unicode = t[1], tounicode16(t[1]), nl + 1, true
+ else
originals[index], tounicode[index], nl, unicode = t, tounicode16sequence(t), nl + 1, true
end
end
@@ -251,120 +266,19 @@ fonts.map.add_to_unicode = function(data,filename)
end
end
end
- if trace_unimapping then
- for index, glyph in table.sortedhash(data.glyphs) do
- local toun, name, unic = tounicode[index], glyph.name, glyph.unicode or -1 -- play safe
+ if trace_mapping then
+ for unic, glyph in table.sortedhash(descriptions) do
+ local name = glyph.name
+ local index = glyph.index
+ local toun = tounicode[index]
if toun then
- logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X, tounicode: %s",index,name,unic,toun)
+ report_fonts("internal: 0x%05X, name: %s, unicode: U+%05X, tounicode: %s",index,name,unic,toun)
else
- logs.report("load otf","internal: 0x%05X, name: %s, unicode: 0x%05X",index,name,unic)
+ report_fonts("internal: 0x%05X, name: %s, unicode: U+%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)
+ report_fonts("enhance: %s tounicode entries added (%s ligatures)",nl+ns, ns)
end
end
-
--- the following is sort of obsolete
---
--- fonts.map.data = fonts.map.data or { }
--- fonts.map.encodings = fonts.map.encodings or { }
--- fonts.map.loaded = fonts.map.loaded or { }
--- fonts.map.line = fonts.map.line or { }
---
--- function fonts.map.line.pdftex(e)
--- if e.name and e.fontfile then
--- local fullname = e.fullname or ""
--- if e.slant and e.slant ~= 0 then
--- if e.encoding then
--- pdf.mapline(format('= %s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.fontfile)))
--- else
--- pdf.mapline(format('= %s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.fontfile)))
--- end
--- elseif e.extend and e.extend ~= 1 and e.extend ~= 0 then
--- if e.encoding then
--- pdf.mapline(format('= %s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.extend,e.encoding,e.fontfile)))
--- else
--- pdf.mapline(format('= %s %s "%g ExtendFont" <%s',e.name,fullname,e.extend,e.fontfile)))
--- end
--- else
--- if e.encoding then
--- pdf.mapline(format('= %s %s <%s <%s',e.name,fullname,e.encoding,e.fontfile)))
--- else
--- pdf.mapline(format('= %s %s <%s',e.name,fullname,e.fontfile)))
--- end
--- end
--- else
--- return nil
--- end
--- end
---
--- function fonts.map.flush(backend) -- will also erase the accumulated data
--- local flushline = fonts.map.line[backend or "pdftex"] or fonts.map.line.pdftex
--- for _, e in next, fonts.map.data do
--- flushline(e)
--- end
--- fonts.map.data = { }
--- end
---
--- fonts.map.line.dvips = fonts.map.line.pdftex
--- fonts.map.line.dvipdfmx = function() end
---
--- function fonts.map.convert_entries(filename)
--- if not fonts.map.loaded[filename] then
--- fonts.map.data, fonts.map.encodings = fonts.map.load_file(filename,fonts.map.data, fonts.map.encodings)
--- fonts.map.loaded[filename] = true
--- end
--- end
---
--- function fonts.map.load_file(filename, entries, encodings)
--- entries = entries or { }
--- encodings = encodings or { }
--- local f = io.open(filename)
--- if f then
--- local data = f:read("*a")
--- if data then
--- for line in gmatch(data,"(.-)[\n\t]") do
--- if find(line,"^[%#%%%s]") then
--- -- print(line)
--- else
--- local extend, slant, name, fullname, fontfile, encoding
--- line = gsub(line,'"(.+)"', function(s)
--- extend = find(s,'"([^"]+) ExtendFont"')
--- slant = find(s,'"([^"]+) SlantFont"')
--- return ""
--- end)
--- if not name then
--- -- name fullname encoding fontfile
--- name, fullname, encoding, fontfile = match(line,"^(%S+)%s+(%S*)[%s<]+(%S*)[%s<]+(%S*)%s*$")
--- end
--- if not name then
--- -- name fullname (flag) fontfile encoding
--- name, fullname, fontfile, encoding = match(line,"^(%S+)%s+(%S*)[%d%s<]+(%S*)[%s<]+(%S*)%s*$")
--- end
--- if not name then
--- -- name fontfile
--- name, fontfile = match(line,"^(%S+)%s+[%d%s<]+(%S*)%s*$")
--- end
--- if name then
--- if encoding == "" then encoding = nil end
--- entries[name] = {
--- name = name, -- handy
--- fullname = fullname,
--- encoding = encoding,
--- fontfile = fontfile,
--- slant = tonumber(slant),
--- extend = tonumber(extend)
--- }
--- encodings[name] = encoding
--- elseif line ~= "" then
--- -- print(line)
--- end
--- end
--- end
--- end
--- f:close()
--- end
--- return entries, encodings
--- end