diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-map.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/font-map.lua | 125 |
1 files changed, 111 insertions, 14 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-map.lua b/Master/texmf-dist/tex/context/base/font-map.lua index 64ff268fb7e..c597d48552b 100644 --- a/Master/texmf-dist/tex/context/base/font-map.lua +++ b/Master/texmf-dist/tex/context/base/font-map.lua @@ -6,9 +6,16 @@ if not modules then modules = { } end modules ['font-map'] = { license = "see context related readme files" } +local match, format, find, concat = string.match, string.format, string.find, table.concat + +local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) + +local ctxcatcodes = tex.ctxcatcodes + --[[ldx-- <p>Eventually this code will disappear because map files are kind 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 { } @@ -29,21 +36,21 @@ function fonts.map.line.pdftex(e) -- so far no combination of slant and stretch local fullname = e.fullname or "" if e.slant and e.slant ~= 0 then if e.encoding then - return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.fontfile)) + return fonts.map.line.pdfmapline("=",format('%s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.fontfile)) else - return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.fontfile)) + return fonts.map.line.pdfmapline("=",format('%s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.fontfile)) end elseif e.stretch and e.stretch ~= 1 and e.stretch ~= 0 then if e.encoding then - return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.stretch,e.encoding,e.fontfile)) + return fonts.map.line.pdfmapline("=",format('%s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.stretch,e.encoding,e.fontfile)) else - return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s',e.name,fullname,e.stretch,e.fontfile)) + return fonts.map.line.pdfmapline("=",format('%s %s "%g ExtendFont" <%s',e.name,fullname,e.stretch,e.fontfile)) end else if e.encoding then - return fonts.map.line.pdfmapline("=",string.format('%s %s <%s <%s',e.name,fullname,e.encoding,e.fontfile)) + return fonts.map.line.pdfmapline("=",format('%s %s <%s <%s',e.name,fullname,e.encoding,e.fontfile)) else - return fonts.map.line.pdfmapline("=",string.format('%s %s <%s',e.name,fullname,e.fontfile)) + return fonts.map.line.pdfmapline("=",format('%s %s <%s',e.name,fullname,e.fontfile)) end end else @@ -54,7 +61,7 @@ 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 pairs(fonts.map.data) do - tex.sprint(tex.ctxcatcodes,flushline(e)) + tex.sprint(ctxcatcodes,flushline(e)) end fonts.map.data = { } end @@ -76,27 +83,27 @@ function fonts.map.load_file(filename, entries, encodings) if f then local data = f:read("*a") if data then - for line in data:gmatch("(.-)[\n\t]") do - if line:find("^[%#%%%s]") then + for line in gmatch(data,"(.-)[\n\t]") do + if find(line,"^[%#%%%s]") then -- print(line) else local stretch, slant, name, fullname, fontfile, encoding line = line:gsub('"(.+)"', function(s) - stretch = s:find('"([^"]+) ExtendFont"') - slant = s:find('"([^"]+) SlantFont"') + stretch = find(s,'"([^"]+) ExtendFont"') + slant = find(s,'"([^"]+) SlantFont"') return "" end) if not name then -- name fullname encoding fontfile - name, fullname, encoding, fontfile = line:match("^(%S+)%s+(%S*)[%s<]+(%S*)[%s<]+(%S*)%s*$") + 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 = line:match("^(%S+)%s+(%S*)[%d%s<]+(%S*)[%s<]+(%S*)%s*$") + name, fullname, fontfile, encoding = match(line,"^(%S+)%s+(%S*)[%d%s<]+(%S*)[%s<]+(%S*)%s*$") end if not name then -- name fontfile - name, fontfile = line:match("^(%S+)%s+[%d%s<]+(%S*)%s*$") + name, fontfile = match(line,"^(%S+)%s+[%d%s<]+(%S*)%s*$") end if name then if encoding == "" then encoding = nil end @@ -119,3 +126,93 @@ function fonts.map.load_file(filename, entries, encodings) end return entries, encodings end + +function fonts.map.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 + if trace_loading or trace_unimapping then + logs.report("load otf","enhance: loading %s ",lumfile) + end + lumunic = dofile(lumfile) + return lumunic, lumfile + end +end + +local hex = lpeg.R("AF","09") +local hexfour = (hex*hex*hex*hex) / 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 index = lpeg.P("index") * dec * lpeg.Cc(false) + +local parser = unicode + index + +local parsers = { } + +function fonts.map.make_name_parser(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) + parsers[str] = p + end + return p + end +end + +--~ local parser = fonts.map.make_name_parser("Japan1") +--~ local function test(str) +--~ local b, a = parser:match(str) +--~ print((a and table.serialize(b)) or b) +--~ end +--~ test("uni1234") +--~ test("uni1234.xx") +--~ test("uni12349876") +--~ test("index1234") +--~ test("Japan1.123") + +function fonts.map.tounicode16(unicode) + if unicode < 0x10000 then + return format("%04X",unicode) + else + return format("%04X%04X",unicode/1024+0xD800,unicode%1024+0xDC00) + end +end + +function fonts.map.tounicode16sequence(unicodes) + local t = { } + for l=1,#unicodes do + local unicode = unicodes[l] + if unicode < 0x10000 then + t[l] = format("%04X",unicode) + else + t[l] = format("%04X%04X",unicode/1024+0xD800,unicode%1024+0xDC00) + end + end + return concat(t) +end + +--~ This is quite a bit faster but at the cost of some memory but if we +--~ do this we will also use it elsewhere so let's not follow this route +--~ now. I might use this method in the plain variant (no caching there) +--~ but then I need a flag that distinguishes between code branches. +--~ +--~ local cache = { } +--~ +--~ function fonts.map.tounicode16(unicode) +--~ local s = cache[unicode] +--~ if not s then +--~ if unicode < 0x10000 then +--~ s = format("%04X",unicode) +--~ else +--~ s = format("%04X%04X",unicode/1024+0xD800,unicode%1024+0xDC00) +--~ end +--~ cache[unicode] = s +--~ end +--~ return s +--~ end + |