X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=src%2Fltj-jfont.lua;h=d3572312b97cff7d874aa5b783fba93c2c22ceb5;hb=ab23049deb6fb90ca689fdf4924b3783f08f8f2e;hp=62b0e329c3a38bd1ec9dbd55e9f9ad870901818a;hpb=43b3b49da87473dc407934da9fd9c652b938ba54;p=luatex-ja%2Fluatexja.git diff --git a/src/ltj-jfont.lua b/src/ltj-jfont.lua index 62b0e32..d357231 100644 --- a/src/ltj-jfont.lua +++ b/src/ltj-jfont.lua @@ -3,7 +3,7 @@ -- luatexbase.provides_module({ name = 'luatexja.jfont', - date = '2015/05/03', + date = '2016/04/03', description = 'Loader for Japanese fonts', }) module('luatexja.jfont', package.seeall) @@ -13,19 +13,14 @@ luatexja.load_module('charrange'); local ltjc = luatexja.charrange luatexja.load_module('rmlgbm'); local ltjr = luatexja.rmlgbm luatexja.load_module('direction'); local ltjd = luatexja.direction +local setfield = node.direct.setfield +local getid = node.direct.getid +local to_direct = node.direct.todirect -local Dnode = node.direct or node - -local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end -local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end - -local nullfunc = function(n) return n end -local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc - -local node_new = Dnode.new -local node_free = Dnode.free -local has_attr = Dnode.has_attribute -local set_attr = Dnode.set_attribute +local node_new = node.direct.new +local node_free = node.direct.free +local has_attr = node.direct.has_attribute +local set_attr = node.direct.set_attribute local round = tex.round local font_getfont = font.getfont @@ -34,8 +29,6 @@ local attr_curjfnt = luatexbase.attributes['ltj@curjfnt'] local attr_curtfnt = luatexbase.attributes['ltj@curtfnt'] local id_glyph = node.id('glyph') local id_kern = node.id('kern') -local id_glue_spec = node.id('glue_spec') -local id_glue = node.id('glue') local cat_lp = luatexbase.catcodetables['latex-package'] local FROM_JFM = luatexja.icflag_table.FROM_JFM local tokenlib = luatexja.token @@ -48,10 +41,20 @@ font_metric_table={} -- [font number] -> jfm_name, jfm_var, size luatexbase.create_callback("luatexja.load_jfm", "data", function (ft, jn) return ft end) -local jfm_file_name, jfm_var +local jfm_file_name, jfm_var, jfm_ksp local defjfm_res local jfm_dir, is_def_jfont, is_vert_enabled +local function norm_val(a) + if (not a) or (a==0.) then + return nil + elseif a==true then + return 1 + else + return a + end +end + function define_jfm(t) local real_char -- Does current character class have the 'real' character? if t.dir~=jfm_dir then @@ -64,16 +67,13 @@ function define_jfm(t) if type(i) == 'number' then -- char_type if not v.chars then if i ~= 0 then defjfm_res= nil; return end - real_char = true else - real_char = false for j,w in pairs(v.chars) do if type(w) == 'number' and w~=-1 then - real_char = true; elseif type(w) == 'string' and utf.len(w)==1 then - real_char = true; w = utf.byte(w) + w = utf.byte(w) elseif type(w) == 'string' and utf.len(w)==2 and utf.sub(w,2) == '*' then - real_char = true; w = utf.byte(utf.sub(w,1,1)) + w = utf.byte(utf.sub(w,1,1)) end if not t.chars[w] then t.chars[w] = i @@ -81,44 +81,43 @@ function define_jfm(t) defjfm_res= nil; return end end - if type(v.align)~='string' then - v.align = 'left' -- left - end - if real_char then - if type(v.width)~='number' and v.width~='prop' then - defjfm_res= nil; return - else - if v.width=='prop' and jfm_dir=='tate' then - v.width = 1.0 - end - if type(v.height)~='number' then - v.height = 0.0 - end - if type(v.depth)~='number' then - v.depth = 0.0 - end - if type(v.italic)~='number' then - v.italic = 0.0 - end - if type(v.left)~='number' then - v.left = 0.0 - end - if type(v.down)~='number' then - v.down = 0.0 - end - end - end v.chars = nil end + if type(v.align)~='string' then + v.align = 'left' -- left + end + if type(v.width)~='number' then + v.width = (jfm_dir=='tate') and 1.0 + end + if type(v.height)~='number' then + v.height = (jfm_dir=='tate') and 0.0 + end + if type(v.depth)~='number' then + v.depth = (jfm_dir=='tate') and 0.0 + end + if type(v.italic)~='number' then + v.italic = 0.0 + end + if type(v.left)~='number' then + v.left = 0.0 + end + if type(v.down)~='number' then + v.down = 0.0 + end v.kern = v.kern or {}; v.glue = v.glue or {} - for j in pairs(v.glue) do + for j,x in pairs(v.glue) do if v.kern[j] then defjfm_res= nil; return end + x.ratio, x[5] = (x.ratio or (x[5] and 0.5*(1+x[5]) or 0.5)), nil + x.priority, x[4] = (x.priority or x[4] or 0), nil + x.kanjiskip_natural = norm_val(x.kanjiskip_natural) + x.kanjiskip_stretch = norm_val(x.kanjiskip_stretch) + x.kanjiskip_shrink = norm_val(x.kanjiskip_shrink) end for j,x in pairs(v.kern) do if type(x)=='number' then - v.kern[j] = {x, 0} + v.kern[j] = {x, 0.5} elseif type(x)=='table' then - v.kern[j] = {x[1], x[2] or 0} + v.kern[j] = { x[1], ratio=x.ratio or (x[2] and 0.5*(1+x[2]) or 0.5) } end end t.char_type[i] = v @@ -147,7 +146,6 @@ do return new else return nil end end - update_jfm_cache = function (j,sz) if metrics[j].size_cache[sz] then return end --local TEMP = node_new(id_kern) @@ -160,20 +158,22 @@ do ((v.align=='right') and 1 or 0.5) if type(i) == 'number' then -- char_type for k,w in pairs(v.glue) do - local h = node_new(id_glue_spec) - v[k] = {true, h, (w[5] and w[5]/sz or 0), FROM_JFM + (w[4] and w[4]/sz or 0)} - setfield(h, 'width', w[1]) - setfield(h, 'stretch', w[2]) - setfield(h, 'shrink', w[3]) - setfield(h, 'stretch_order', 0) - setfield(h, 'shrink_order', 0) + v[k] = { + nil, + ratio=w.ratio/sz, + priority=FROM_JFM + w.priority/sz, + width = w[1], stretch = w[2], shrink = w[3], + kanjiskip_natural = w.kanjiskip_natural and w.kanjiskip_natural/sz, + kanjiskip_stretch = w.kanjiskip_stretch and w.kanjiskip_stretch/sz, + kanjiskip_shrink = w.kanjiskip_shrink and w.kanjiskip_shrink/sz, + } end for k,w in pairs(v.kern) do local g = node_new(id_kern) setfield(g, 'kern', w[1]) setfield(g, 'subtype', 1) set_attr(g, attr_icflag, FROM_JFM) - v[k] = {false, g, w[2]/sz} + v[k] = {g, ratio=w[2]/sz} end end v.glue, v.kern = nil, nil @@ -248,7 +248,7 @@ do cstemp = csname:sub( (utf8.byte(csname,1,1) == tex.escapechar) and 2 or 1, -1) cstemp = cstemp:sub(1, ((cstemp:sub(-1,-1)==' ') and (cstemp:len()>=2)) and -2 or -1) global_flag = g and '\\global' or '' - tex.sprint(cat_lp, '\\expandafter\\font\\csname ', + tex.sprint(cat_lp, '\\expandafter\\font\\csname ', (cstemp==' ') and '\\space' or cstemp, '\\endcsname') end @@ -265,7 +265,7 @@ do "bad JFM `" .. jfm_file_name .. "'", 'The JFM file you specified is not valid JFM file.\n'.. 'So defining Japanese font is cancelled.') - tex.sprint(cat_lp, global_flag, '\\expandafter\\let\\csname ', + tex.sprint(cat_lp, global_flag, '\\expandafter\\let\\csname ', (cstemp==' ') and '\\space' or cstemp, '\\endcsname=\\relax') return @@ -274,6 +274,7 @@ do local ad = identifiers[fn].parameters local sz = metrics[j].size_cache[f.size] local fmtable = { jfm = j, size = f.size, var = jfm_var, + with_kanjiskip = jfm_ksp, zw = sz.zw, zh = sz.zh, ascent = ad.ascender, descent = ad.descender, @@ -312,7 +313,9 @@ do -- extract jfm_file_name and jfm_var -- normalize position of 'jfm=' and 'jfmvar=' keys local function extract_metric(name) - jfm_file_name = ''; jfm_var = '' + local is_braced = name:match('^{(.*)}$') + name= is_braced or name + jfm_file_name = ''; jfm_var = ''; jfm_ksp = true local tmp, index = name:sub(1, 5), 1 if tmp == 'file:' or tmp == 'name:' or tmp == 'psft:' then index = 6 @@ -350,15 +353,18 @@ do name = name .. 'jfmvar=' .. jfm_var end end + for x in string.gmatch (name, "[:;]([+%%-]?)ltjks") do + jfm_ksp = not (x=='-') + end if jfm_dir == 'tate' then - is_vert_enabled = (not name:match('-vert')) and (not name:match('-vrt2')) + is_vert_enabled = (not name:match('[:;]%-vert')) and (not name:match('[:;]%-vrt2')) if not name:match('vert') and not name:match('vrt2') then - name = name .. ';vert;vrt2' + name = name .. ';+vert;+vrt2' end else is_vert_enabled = nil end - return name + return is_braced and ('{' .. name .. '}') or name end -- define_font callback @@ -367,6 +373,7 @@ do function luatexja.font_callback(name, size, id) local new_name = is_def_jfont and extract_metric(name) or name is_def_jfont = false + --local res = otfl_fdr(new_name, size, id) local res = ltjr_font_callback(new_name, size, id, otfl_fdr) luatexbase.call_callback('luatexja.define_font', res, new_name, size, id) -- this callback processes variation selector, so we execute it always @@ -401,9 +408,9 @@ do kfam_list[fam]=true end function search_kfam(fam, use_fd) - if kfam_list[fam] then + if kfam_list[fam] then tex.sprint(cat_lp, '\\let\\ifin@\\iftrue '); return - elseif Nkfam_list[fam] then + elseif Nkfam_list[fam] then tex.sprint(cat_lp, '\\let\\ifin@\\iffalse '); return elseif use_fd then for i,_ in pairs(kyenc_list) do @@ -436,7 +443,7 @@ do tex.sprint(cat_lp, s) end function search_ffam_fd(fam) - if Nffam_list[fam] then + if Nffam_list[fam] then tex.sprint(cat_lp, '\\let\\ifin@\\iffalse '); return else for i,_ in pairs(fenc_list) do @@ -642,14 +649,13 @@ do for k,w in pairs(v) do if type(k)=='number' then --if w[1] then gs = gs + 1 else ke = ke + 1 end - node_free(w[2]) + if w[1] then node_free(w[1]) end end end end n.size_cache[i]=nil end end - --print('glue spec: ', gs, 'kern: ', ke) end end @@ -678,7 +684,10 @@ do local sort = table.sort local function add_fl_table(dest, glyphs, unitable, asc_des, units) - local tg, glyphmin, glyphmax = glyphs.glyphs, glyphs.glyphmin or 0, glyphs.glyphmax + local tg, glyphmin, glyphmax = glyphs.glyphs, 0, glyphs.glyphmax + for _,v in pairs(fields(glyphs)) do + if v=='glyphmin' then glyphmin, glyphmax = glyphs.glyphmin, glyphmax+1; break end + end for i = glyphmin, glyphmax-1 do local gv = tg[i] if gv then @@ -743,7 +752,7 @@ do end if fl.subfonts then for _,v in pairs(fl.subfonts) do - dest = add_fl_table(dest, v, unicodes, + dest = add_fl_table(dest, v, unicodes, fl.ascent + fl.descent, fl.units_per_em) end end @@ -755,7 +764,7 @@ do local bx = font_extra_basename[bname].vkerns local lookuphash = id.resources.lookuphash local desc = id.shared.rawdata.descriptions - if bx then + if bx and lookuphash then for i,v in pairs(bx) do lookuphash[i] = lookuphash[i] or v for j,w in pairs(v) do @@ -913,7 +922,7 @@ do return tfmdata end, - 'ltj.supply_tounicode', 1) + 'ltj.supply_tounicode', 1) end @@ -921,14 +930,24 @@ end -- MISC ------------------------------------------------------------------------ do - local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end - local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end + local getfont = node.direct.getfont + local getchar = node.direct.getchar local get_dir_count = ltjd.get_dir_count local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct local ensure_tex_attr = ltjb.ensure_tex_attr - local node_write = Dnode.write + local node_write = node.direct.write local font = font - local ITALIC = luatexja.icflag_table.ITALIC + local new_ic_kern + if status.luatex_version>=89 then + new_ic_kern = function(g) return node_new(id_kern,3) end + else + local ITALIC = luatexja.icflag_table.ITALIC + new_ic_kern = function() + local g = node_new(id_kern) + setfield(g, 'subtype', 1); set_attr(g, attr_icflag, ITALIC) + return g + end + end -- EXT: italic correction function append_italic() local p = to_direct(tex.nest[tex.nest.ptr].tail) @@ -938,18 +957,18 @@ do local j = font_metric_table[ has_attr(p, (get_dir_count()==dir_tate) and attr_curtfnt or attr_curjfnt) ] - local g = node_new(id_kern) - setfield(g, 'subtype', 1); set_attr(g, attr_icflag, ITALIC) + local g = new_ic_kern() setfield(g, 'kern', j.char_type[find_char_class(getchar(p), j)].italic) node_write(g); ensure_tex_attr(attr_icflag, 0) else local f = getfont(p) local h = font_getfont(f) or font.fonts[f] if h then - local g = node_new(id_kern) - setfield(g, 'subtype', 1); set_attr(g, attr_icflag, ITALIC) - setfield(g, 'kern', h.characters[getchar(p)].italic) - node_write(g); ensure_tex_attr(attr_icflag, 0) + local g = new_ic_kern() + if h.characters[getchar(p)] and h.characters[getchar(p)].italic then + setfield(g, 'kern', h.characters[getchar(p)].italic) + node_write(g); ensure_tex_attr(attr_icflag, 0) + end end end end @@ -969,4 +988,3 @@ vert_form_table = { [0xFF3B]=0xFE47, [0xFF3D]=0xFE48, [0xFF3F]=0xFE33, } setmetatable(vert_form_table, {__index=function(t,k) return k end}); -