X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fluatexja%2Frmlgbm.lua;h=d567e09203fa7841f2ca1d45cf5f3442738aece4;hb=9e0530c0ce86d394f0d93d20eec2bc93c9adce5c;hp=42fe6e39f2123a21f40dad04ce545690c4ea3c93;hpb=53f7e2d9406b8186bc4453cb6c13ac0f3b4156cb;p=luatex-ja%2Fluatexja.git diff --git a/src/luatexja/rmlgbm.lua b/src/luatexja/rmlgbm.lua index 42fe6e3..d567e09 100644 --- a/src/luatexja/rmlgbm.lua +++ b/src/luatexja/rmlgbm.lua @@ -3,16 +3,143 @@ -- luatexbase.provides_module({ name = 'luatexja.rmlgbm', - date = '2011/06/27', - version = '0.1', + date = '2012/02/17', + version = '0.2', description = 'Definitions of non-embedded Japanese fonts', }) module('luatexja.rmlgbm', package.seeall) local err, warn, info, log = luatexbase.errwarinf(_NAME) -local rmlgbm_data = require('luatexja-rmlgbm-data') -local cache_chars = { [655360] = rmlgbm_data.characters } +require('luatexja.base'); local ltjb = luatexja.base +local round = tex.round +local cidfont_data = {} +local cache_chars = {} +local cid_reg, cid_order, cid_supp, cid_name +local taux_dir = 'luatex-cache/luatexja' +local path = { + localdir = file.join(kpse.expand_var("$TEXMFVAR"), aux_dir), + systemdir = file.join(kpse.expand_var("$TEXMFSYSVAR"), aux_dir), +} +local cid_replace = { + ["Adobe-Japan1"] = "UniJISX0213-UTF32", + ["Adobe-Korea1"] = "UniKS-UTF32", + ["Adobe-GB1"] = "UniGB-UTF32", + ["Adobe-CNS1"] = "UniCNS-UTF32", +} + +-- reading CID maps +local line, fh, tt + +local function load_bf_char() + local cid, ucs, ucsa + line = fh:read("*l") + while line do + if line == "endcidchar" then + line = fh:read("*l"); return + else -- WMA l is in the form "<%x+>%s%d+" + ucs, cid = string.match(line, "<(%x+)>%s+(%d+)") + cid = tonumber(cid, 10); ucs = tonumber(ucs, 16); + if not tt[ucs] then + tt[ucs] = { index = cid, width = 655360 } + end + end + line = fh:read("*l") + end +end + +local function load_bf_range() + local bucs, eucs, cid + line = fh:read("*l") + while line do + if line == "endcidrange" 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+(%d+)") + cid = tonumber(cid, 10); bucs = tonumber(bucs, 16); eucs = tonumber(eucs, 16); + for ucs = bucs, eucs do + if not tt[ucs] then + tt[ucs] = { index = cid, width = 655360 } + end + cid = cid+1 + end + end + line = fh:read("*l") + end +end + +local function make_cid_font() + cidfont_data[cid_name] = { + cidinfo = { ordering=cid_order, registry=cid_reg, supplement=cid_supp }, + encodingbytes = 2, extend=1000, format = 'opentype', + direction = 0, characters = {}, parameters = {}, embedding = "no", cache = "yes", + ascender = 0, descender = 0, factor = 0, hfactor = 0, vfactor = 0, + } + tt = {} + + -- Open + -- TODO: vertical fonts? + fh = io.open(kpse.find_file(cid_replace[cid_name] .. "-H", 'cmap files'), "r") + line = fh:read("*l") + while line do + if string.find(line, "%x+%s+begincidchar") then + load_bf_char() + elseif string.find(line, "%x+%s+begincidrange") then + load_bf_range() + else + line = fh:read("*l") + end + end + fh:close(); cidfont_data[cid_name].characters = tt + cache_chars[cid_name] = { [655360] = cidfont_data[cid_name].characters } + + -- Save + local savepath = path.localdir + if not lfs.isdir(savepath) then + dir.mkdirs(savepath) + end + savepath = file.join(savepath, "luatexja-cid-auto-" + .. string.lower(cid_name) .. ".lua") + if file.iswritable(savepath) then + table.tofile(savepath, cidfont_data[cid_name],'return', false, true, false ) + else + ltjb.package_warning('luatexja', + 'failed to save informations of non-embedded 2-byte fonts', '') + end +end + +-- +local function read_cid_font() + local names = { + "luatexja-cid-std-" .. string.lower(cid_name) .. ".lua", + "luatexja-cid-auto-" .. string.lower(cid_name) .. ".lua", + } + local s + for i,v in ipairs(names) do + local localpath = file.join(path.localdir, v) + local systempath = file.join(path.systemdir, v) + local kpsefound = kpse.find_file(v) + if kpsefound and file.isreadable(kpsefound) then + cidfont_data[cid_name] = require(kpsefound) + cache_chars[cid_name] = { [655360] = cidfont_data[cid_name].characters } + return + elseif file.isreadable(localpath) then + cidfont_data[cid_name] = require(localpath) + cache_chars[cid_name] = { [655360] = cidfont_data[cid_name].characters } + return + elseif file.isreadable(systempath) then + cidfont_data[cid_name] = require(systempath) + cache_chars[cid_name] = { [655360] = cidfont_data[cid_name].characters } + return + end + end + -- Now we must create the virtual metrics from CMap. + ltjb.package_info('luatexja', + 'I try to generate informations of non-embedded 2-byte fonts...', '') + make_cid_font() +end + +-- High-level local function mk_rml(name, size, id) local specification = fonts.define.analyze(name,size) specification = fonts.define.specify[':'](specification) @@ -20,7 +147,12 @@ local function mk_rml(name, size, id) local fontdata = {} local cachedata = {} - for k, v in pairs(rmlgbm_data) do + local s = cidfont_data[cid_name] + if not s then + -- error message? + s = cidfont_data["Adobe-Japan1"] + end + for k, v in pairs(s) do fontdata[k] = v cachedata[k] = v end @@ -28,70 +160,58 @@ local function mk_rml(name, size, id) cachedata.characters = nil fontdata.unicodes = nil fontdata.shared = nil - cachedata.shared = {} - local shared = cachedata.shared - for k, v in pairs(rmlgbm_data.shared) do - shared[k] = v + cachedata.shared = nil + if cidfont_data[cid_name].shared then + cachedata.shared = {} + local shared = cachedata.shared + for k, v in pairs(cidfont_data[cid_name].shared) do + shared[k] = v + end + + shared.set_dynamics = fonts.otf.set_dynamics + shared.processes, shared.features = fonts.otf.set_features(cachedata,fonts.define.check(features,fonts.otf.features.default)) end - shared.set_dynamics = fonts.otf.set_dynamics - shared.processes, shared.features = fonts.otf.set_features(cachedata,fonts.define.check(features,fonts.otf.features.default)) - -- characters & scaling if size < 0 then size = -size * 655.36 end local scale = size / 655360 - if not cache_chars[size] then - cache_chars[size] = {} - for k, v in pairs(cache_chars[655360]) do - cache_chars[size][k] = {} - cache_chars[size][k].index = v.index - cache_chars[size][k].width = v.width * scale - cache_chars[size][k].tounicode = v.tounicode + if not cache_chars[cid_name][size] then + cache_chars[cid_name][size] = {} + for k, v in pairs(cache_chars[cid_name][655360]) do + cache_chars[cid_name][size][k] = {} + cache_chars[cid_name][size][k].index = v.index + cache_chars[cid_name][size][k].width = round(v.width * scale) + cache_chars[cid_name][size][k].tounicode = v.tounicode end end - fontdata.characters = cache_chars[size] - cachedata.characters = cache_chars[size] + fontdata.characters = cache_chars[cid_name][size] + cachedata.characters = cache_chars[cid_name][size] local parameters = {} - for k, v in pairs(rmlgbm_data.parameters) do + for k, v in pairs(cidfont_data[cid_name].parameters) do parameters[k] = v * scale end - fontdata.parameters = parameters - cachedata.parameters = parameters - - fontdata.ascender = fontdata.ascender * scale - cachedata.ascender = fontdata.ascender - fontdata.descender = fontdata.descender * scale - cachedata.descender = fontdata.descender - fontdata.factor = fontdata.factor * scale - cachedata.factor = fontdata.factor - fontdata.hfactor = fontdata.hfactor * scale - cachedata.hfactor = fontdata.hfactor - fontdata.vfactor = fontdata.vfactor * scale - cachedata.vfactor = fontdata.vfactor - fontdata.size = size - cachedata.size = size + fontdata.parameters = parameters; cachedata.parameters = parameters + fontdata.ascender = fontdata.ascender * scale; cachedata.ascender = fontdata.ascender + fontdata.descender = fontdata.descender * scale; cachedata.descender = fontdata.descender + fontdata.factor = fontdata.factor * scale; cachedata.factor = fontdata.factor + fontdata.hfactor = fontdata.hfactor * scale; cachedata.hfactor = fontdata.hfactor + fontdata.vfactor = fontdata.vfactor * scale; cachedata.vfactor = fontdata.vfactor + fontdata.size = size; cachedata.size = size -- no embedding local var = '' if features.slant then - fontdata.slant = features.slant*1000 - cachedata.slant = fontdata.slant + fontdata.slant = features.slant*1000; cachedata.slant = fontdata.slant var = var .. 's' .. tostring(features.slant) end if features.extend then - fontdata.extend = features.extend*1000 - cachedata.extend = fontdata.extend + fontdata.extend = features.extend*1000; cachedata.extend = fontdata.extend var = var .. 'x' .. tostring(features.extend) end - fontdata.name = specification.name .. size .. var - cachedata.name = fontdata.name - fontdata.fullname = specification.name .. var - cachedata.fullname = fontdata.fullname - - fontdata.psname = specification.name - cachedata.psname = fontdata.psname - + fontdata.name = specification.name .. size .. var; cachedata.name = fontdata.name + fontdata.fullname = specification.name .. var; cachedata.fullname = fontdata.fullname + fontdata.psname = specification.name; cachedata.psname = fontdata.psname fonts.ids[id] = cachedata return fontdata @@ -101,8 +221,26 @@ local dr_orig = fonts.define.read function fonts.define.read(name, size, id) local p = utf.find(name, ":") or utf.len(name)+1 if utf.sub(name, 1, p-1) == 'psft' then - return mk_rml(utf.sub(name,p+1), size, id) + local s = "Adobe-Japan1-6" + local basename = utf.sub(name,p+1) + local p = utf.find(basename, ":") + if p then + local xname = utf.sub(basename, p+1) + p = 1 + while p do + local q = utf.find(xname, ";", p+1) or utf.len(xname)+1 + if utf.sub(xname, p, p+3)=='cid=' and q>p+4 then + s = utf.sub(xname, p+4, q-1) + end + if utf.len(xname)+1==q then p = nil else p = q + 1 end + end + end + cid_reg, cid_order, cid_supp = string.match(s, "(.-)%-(.-)%-(%d-)") + cid_name = cid_reg .. '-' .. cid_order + if not cidfont_data[cid_name] then read_cid_font() end + return mk_rml(basename, size, id) else return dr_orig(name, size, id) end end +