+-- reading CID maps
+local make_cid_font
+do
+ local line, fh -- line, file handler
+ local tt,cidm -- characters, cid->(Unicode)
+
+ local function load_cid_char(cid_dec, mke)
+ local cid, ucs, ucsa
+ line = fh:read("*l")
+ while line do
+ if string.find(line, "end...?char") then
+ line = fh:read("*l"); return
+ else -- WMA l is in the form "<%x+>%s%d+"
+ ucs, cid = string.match(line, "<(%x+)>%s+<?(%x+)>?")
+ cid = cid_dec(cid); ucs = tonumber(ucs, 16);
+ if not tt[ucs] then
+ tt[ucs] = mke(cid); cidm[cid]=ucs
+ end
+ end
+ line = fh:read("*l")
+ end
+ end
+
+ local function load_cid_range(inc, cid_dec, mke)
+ local bucs, eucs, cid
+ line = fh:read("*l")
+ while line do
+ if string.find(line, "end...?range") then
+ line = fh:read("*l"); return
+ else -- WMA l is in the form "<%x+>%s+<%x+>"
+ bucs, eucs, cid = string.match(line, "<(%x+)>%s+<(%x+)>%s+<?(%x+)>?")
+ cid = cid_dec(cid);
+ bucs = tonumber(bucs, 16); eucs = tonumber(eucs, 16)
+ for ucs = bucs, eucs do
+ if not tt[ucs] then
+ tt[ucs] = mke(cid); cidm[cid]=ucs
+ end
+ cid = inc(cid)
+ end
+ end
+ line = fh:read("*l")
+ end
+ end
+
+ local function open_cmap_file(name, inc, cid_dec, mke)
+ fh = io.open(kpse.find_file(name, 'cmap files'), "r")
+ line = fh:read("*l")
+ while line do
+ if string.find(line, "%x+%s+begin...?char") then
+ load_cid_char(cid_dec, mke)
+ elseif string.find(line, "%x+%s+begin...?range") then
+ load_cid_range(inc, cid_dec, mke)
+ else
+ line = fh:read("*l")
+ end
+ end
+ fh:close();
+ end
+
+ local function increment(a) return a+1 end
+ local function entry(a)
+ return {index = a}
+ end
+ make_cid_font = function ()
+ local kx = cid_replace[cid_name]
+ if not kx then return end
+ local k = {
+ cidinfo = { ordering=cid_order, registry=cid_reg, supplement=kx[3] },
+ encodingbytes = 2, extend=1000, format = 'opentype',
+ direction = 0, characters = {}, parameters = {}, embedding = "no", cache = "yes",
+ ascender = 0, descender = 0, factor = 0, hfactor = 0, vfactor = 0,
+ tounicode = 1,
+ }
+ cidfont_data[cid_name] = k
+
+ -- CID => Unicode 符号空間
+ -- TODO: vertical fonts?
+ tt, cidm = {}, {}
+ for i = 0,kx[2] do cidm[i] = -1 end
+ open_cmap_file(kx[1] .. "-H", increment, tonumber, entry)
+ k.characters = tt
+
+ -- Unicode にマップされなかった文字の処理
+ -- これらは TrueType フォントを使って表示するときはおかしくなる
+ local ttu, pricode = {}, 0xF0000
+ for i,v in ipairs(cidm) do
+ if v==-1 then
+ tt[pricode], cidm[i], pricode
+ = { index = i }, pricode, pricode+1;
+ end
+ ttu[cid_order .. '.' .. i] = cidm[i]
+ end
+ -- shared
+ k.shared = {
+ otfdata = {
+ cidinfo= k.cidinfo, verbose = false,
+ shared = { featuredata = {}, },
+ luatex = { features = {},
+ defaultwidth=1000,
+ sequences = { }, },
+ },
+ dynamics = {}, features = {}, processes = {},
+ }
+ k.resources = { unicodes = ttu, }
+ k.descriptions = {}
+ cache_chars[cid_name] = { [655360] = k.characters }
+
+ -- tounicode エントリ
+ local cidp = {nil, nil}; local cidmo = cidm
+ tt, ttu, cidm = {}, {}, {}
+ open_cmap_file(cid_name .. "-UCS2",
+ function(a)
+ a[2] = a[2] +1 ; return a
+ end,
+ function(a)
+ cidp[1] = string.upper(string.sub(a,1,string.len(a)-4))
+ cidp[2] = tonumber(string.sub(a,-4),16)
+ return cidp
+ end,
+ function(a) return a[1] ..string.format('%04X',a[2]) end)
+ -- tt は cid -> tounicode になっているので cidm -> tounicode に変換
+ local kxf = kx[4]
+ for i,v in ipairs(cidmo) do
+ k.characters[v].width = kxf(i)
+ if v>=0xF0000 then
+ k.characters[v].tounicode = tt[i]
+ end
+ end
+
+ -- Save
+ k.characters[46].width = math.floor(655360/14);
+ ltjb.save_cache( "ltj-cid-auto-" .. string.lower(cid_name),
+ {
+ version = cache_ver,
+ k,
+ })
+ end
+end
+