+-- 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 = {
+ ascender = 655360*0.88,
+ descender = 655360*0.12,
+ },
+ embedding = "no", cache = "yes", factor = 0, hfactor = 0, vfactor = 0,
+ tounicode = 1,
+ }
+ cidfont_data[cid_name] = k
+
+ -- CID => Unicode 符号空間
+ local tth, cidmo = {}, {}
+ tt, cidm = tth, cidmo
+ for i = 0,kx[2] do cidm[i] = -1 end
+ open_cmap_file(kx[1] .. "-H", increment, tonumber, entry)
+ k.characters = tth
+
+ -- Unicode にマップされなかった文字の処理
+ -- これらは TrueType フォントを使って表示するときはおかしくなる
+ local ttu, pricode = {}, 0xF0000
+ for i,v in ipairs(cidmo) do
+ if v==-1 then
+ tth[pricode], cidmo[i], pricode
+ = { index = i }, pricode, pricode+1;
+ end
+ ttu[cid_order .. '.' .. i] = cidmo[i]
+ end
+
+ -- shared
+ k.shared = {
+ otfdata = {
+ cidinfo= k.cidinfo, verbose = false,
+ shared = { featuredata = {}, },
+ },
+ dynamics = {}, features = {}, processes = {},
+ --rawdata = { descriptions = {} },
+ }
+ k.resources = { unicodes = ttu, }
+ k.descriptions = {}
+ cache_chars[cid_name] = { [655360] = k.characters }
+
+ -- 縦書用字形
+ tt, cidm = {}, {}
+ local ttv = {}; k.shared.ltj_vert_table = ttv
+ for i = 0,kx[2] do cidm[i] = -1 end
+ open_cmap_file(kx[1] .. "-V", increment, tonumber, entry)
+ for i,v in pairs(tt) do
+ ttv[i] = cidmo[v.index]
+ end
+
+ -- tounicode エントリ
+ local cidp = {nil, nil}; 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
+
+--
+local cidf_vert_processor
+do
+ local traverse_id = node.traverse_id
+ local id_glyph = node.id('glyph')
+ cidf_vert_processor = {
+ function (head, fnum)
+ local fontdata = identifiers[fnum]
+ if fontdata.is_ltj_vert then
+ local vt = fontdata.shared.ltj_vert_table
+ for n in traverse_id(id_glyph, head) do
+ if n.font==fnum then
+ n.char = vt[n.char] or n.char
+ end
+ end
+ return head, false
+ end
+ end
+ }
+end
+
+local function cid_cache_outdated(t) return t.version~=cache_ver end
+local function read_cid_font()
+ local dat = ltjb.load_cache("ltj-cid-auto-" .. string.lower(cid_name),
+ cid_cache_outdated )
+ if dat then
+ cidfont_data[cid_name] = dat[1]