OSDN Git Service

ltj-rmlgbm.lua: support vertical form.
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Wed, 7 May 2014 11:14:17 +0000 (20:14 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Wed, 7 May 2014 11:14:17 +0000 (20:14 +0900)
src/ltj-direction.lua
src/ltj-jfmglue.lua
src/ltj-plain.sty
src/ltj-rmlgbm.lua
src/ltj-setwidth.lua
src/luatexja-core.sty
src/luatexja.lua

index 8717556..ee3331a 100644 (file)
@@ -4,6 +4,7 @@
 
 luatexja.load_module('base');      local ltjb = luatexja.base
 luatexja.load_module('stack');     local ltjs = luatexja.stack
+luatexja.load_module('rmlgbm');    local ltjr = luatexja.rmlgbm
 luatexja.direction = {}
 
 local attr_dir = luatexbase.attributes['ltj@dir']
@@ -62,24 +63,30 @@ end
 
 do 
    local tex_getcount = tex.getcount
-   local function set_dir_flag(h)
-      local new_dir = ltjs.table_current_stack[DIR]
-      local w = node_new(id_whatsit, sid_user)
+   local function set_dir_flag(h, gc)
+      local hd, new_dir = to_direct(h), ltjs.table_current_stack[DIR]
+      local w
+      if hd and getid(hd)==id_whatsit and getsubtype(hd)==sid_user 
+      and getfield(hd, 'user_id')==wh_DIR then
+        w = hd
+      else
+        w = node_new(id_whatsit, sid_user)
+        setfield(w, 'next', hd)
+      end
       setfield(w, 'user_id', wh_DIR)
       setfield(w, 'type', 100)
       setfield(w, 'value', new_dir)
-      setfield(w, 'next', to_direct(h))
       return to_node(w)
    end
    luatexbase.add_to_callback('hpack_filter', set_dir_flag, 'ltj.set_dir_flag', 10000)
    luatexbase.add_to_callback('vpack_filter', 
-                             function (h)
+                             function (h, gc)
                                 local box_set, cl = 0, tex.currentgrouplevel + 1
                                 for w in traverse_id(id_whatsit, to_direct(h)) do
                                    if getfield(w, 'value')==cl then box_set = 1; break end
                                 end
                                 ltjs.report_stack_level(tex_getcount('ltj@@stack') + box_set)
-                                return set_dir_flag(h)
+                                return set_dir_flag(h, gc)
                              end, 'ltj.set_dir_flag', 1)
    luatexbase.add_to_callback('post_linebreak_filter', 
                              function (h)
@@ -87,7 +94,7 @@ do
                                 for line in traverse_id(id_hlist, to_direct(h)) do
                                    set_attr(line, attr_dir, new_dir)
                                 end
-                                return h
+                                return set_dir_flag(h, gc)
                              end, 'ltj.set_dir_flag', 100)
 
 end
@@ -149,8 +156,9 @@ do
       },
    }
 
-   make_dir_node = function (head, b, new_dir)
+   make_dir_node = function (head, b, new_dir, origin)
       -- head: list head, b: box
+      -- origin: コール元 (for debug)
       -- return value: (new head), (next of b), (new b), (is_b_dir_node)
       -- (new b): b か dir_node に被せられた b
       local old_dir
@@ -159,13 +167,14 @@ do
           and getfield(bh, 'user_id')==wh_DIR then
             old_dir = getfield(bh, 'value')
             setfield(b, 'head', node_next(bh))
-           set_attr(b, attr_icflag, PROCESSED)
+            set_attr(b, attr_icflag, PROCESSED)
             node_free(bh)
       else
         old_dir = has_attr(b, attr_dir) or dir_yoko
         if old_dir==0 then old_dir =dir_yoko end
       end
-      if old_dir==new_dir  then 
+      --print('make_dir_node', origin, old_dir,new_dir)
+      if old_dir==new_dir then 
         set_attr(b, attr_icflag, PROCESSED)
         return head, node_next(b), b, false
       elseif  -old_dir == new_dir  then 
@@ -225,13 +234,14 @@ do
         return nh, nb, ret, flag
       end
    end
-   local function process_dir_node(head)
+   local function process_dir_node(head, gc)
       local h = to_direct(head)
       local x, new_dir = h, ltjs.table_current_stack[DIR] or dir_yoko 
       while x do
         local xid = getid(x)
-        if (xid==id_hlist and has_attr(x, attr_icflag)~=PACKED) or xid==id_vlist then
-           h, x = make_dir_node(h, x, new_dir)
+        if (xid==id_hlist and has_attr(x, attr_icflag)~=PACKED) 
+        or xid==id_vlist then
+           h, x = make_dir_node(h, x, new_dir, 'process_dir_node:' .. gc)
         else
            x = node_next(x)
         end
@@ -246,7 +256,6 @@ end
 local font_vert_table = {} -- key: fontnumber
 do
    local font_vert_basename = {} -- key: basename
-
    local function add_feature_table(tname, src, dest)
       for i,v in pairs(src) do
         if type(v.slookups)=='table' then
@@ -262,7 +271,7 @@ do
       -- test if already loaded
       if type(id)=='number' then -- sometimes id is an integer
          font_vert_table[n] = font_vert_table[id]; return
-      elseif not id then return
+      elseif (not id) or font_vert_table[n]  then return
       end
 
       local fname = id.filename
@@ -289,7 +298,7 @@ do
    
    function luatexja.direction.get_vert_glyph(n, chr)
       local fn = font_vert_table[n]
-      return (fn and fn[chr]) or chr
+      return fn and fn[chr] or chr
    end
 
    luatexbase.add_to_callback('luatexja.define_font',
@@ -297,5 +306,8 @@ do
                                 prepare_vert_data(id, res)
                              end,
                              'prepare_vert_data', 1)
+
+   local function a (n, dat) font_vert_table[n] = dat end
+   luatexja.rmlgbm.vert_addfunc = a
    
 end
index 4e26e27..9910c55 100644 (file)
@@ -34,6 +34,7 @@ local insert_before = Dnode.insert_before
 local insert_after = Dnode.insert_after
 local node_next = (Dnode ~= node) and Dnode.getnext or node.next
 local round = tex.round
+local ltjd_make_dir_node = ltjd.make_dir_node
 local ltjf_font_metric_table = ltjf.font_metric_table
 local ltjf_find_char_class = ltjf.find_char_class
 local node_new = Dnode.new
@@ -306,14 +307,14 @@ local calc_np_auxtable = {
    end,
    [id_hlist] = function(lp) 
       local op, flag
-      head, lp, op, flag = ltjd.make_dir_node(head, lp, list_dir)
+      head, lp, op, flag = ltjd_make_dir_node(head, lp, list_dir, 'jfm hlist')
       Np.first = Np.first or op; Np.last = op; Np.nuc = op; 
       Np.id = (flag or getfield(op, 'shift')~=0) and id_box_like or id_hlist
       return true, lp
    end,
    box_like = function(lp)
       local op
-      head, lp, op = ltjd.make_dir_node(head, lp, list_dir)
+      head, lp, op = ltjd_make_dir_node(head, lp, list_dir, 'jfm:' .. getid(lp))
       Np.first = Np.first or op; Np.last = op; Np.nuc = op; 
       Np.id = id_box_like;
       return true, lp
index ab264ff..493a40c 100644 (file)
@@ -62,6 +62,7 @@
   xkanjiskip=.25\zw plus 1pt minus 1pt,
   autospacing, autoxspacing, jacharrange={-1}, 
   yalbaselineshift=0pt, yjabaselineshift=0pt,
+  talbaselineshift=0pt, tjabaselineshift=0pt,
   jcharwidowpenalty=500, differentjfm=paverage
 }
 
index 484960f..a785a57 100644 (file)
@@ -5,7 +5,7 @@ luatexja.load_module('base');      local ltjb = luatexja.base
 
 local cidfont_data = {}
 local cache_chars = {}
-local cache_ver = '2'
+local cache_ver = '3'
 
 local cid_reg, cid_order, cid_supp, cid_name
 local cid_replace = {
@@ -121,40 +121,48 @@ do
       cidfont_data[cid_name] = k
 
       -- CID => Unicode 符号空間
-      -- TODO: vertical fonts?
-      tt, cidm = {}, {}
+      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 = tt
+      k.characters = tth
 
       -- Unicode にマップされなかった文字の処理
       -- これらは TrueType フォントを使って表示するときはおかしくなる
       local ttu, pricode = {}, 0xF0000
-      for i,v in ipairs(cidm) do
+      for i,v in ipairs(cidmo) do
          if v==-1 then 
-            tt[pricode], cidm[i], pricode 
+            tth[pricode], cidmo[i], pricode 
               = { index = i }, pricode, pricode+1;
          end
-         ttu[cid_order .. '.' .. i] = cidm[i]
+         ttu[cid_order .. '.' .. i] = cidmo[i]
       end
+
+      -- 縦書用字形
+      tt, cidm = {}, {}
+      for i = 0,kx[2] do cidm[i] = -1 end
+      open_cmap_file(kx[1] .. "-V", increment, tonumber, entry)
+      local ttv = {}
+      for i,v in pairs(tt) do ttv[i] =  cidmo[v.index] end
+
       -- shared
       k.shared = {
          otfdata = { 
             cidinfo= k.cidinfo, verbose = false, 
             shared = { featuredata = {}, }, 
-            luatex = { features = {}, 
+           luatex = { features = {}, 
                       defaultwidth=1000, 
-                      sequences = {  }, },
+                    },
          },
          dynamics = {}, features = {}, processes = {}, 
+        ltj_vert_table = ttv
       }
       k.resources = { unicodes = ttu, }
       k.descriptions = {}
       cache_chars[cid_name]  = { [655360] = k.characters }
 
       -- tounicode エントリ
-      local cidp = {nil, nil}; local cidmo = cidm
-      tt, ttu, cidm = {}, {}, {}
+      local cidp = {nil, nil}; tt, ttu, cidm = {}, {}, {}
       open_cmap_file(cid_name .. "-UCS2",
                     function(a) 
                        a[2] = a[2] +1 ; return a
@@ -215,6 +223,7 @@ local function mk_rml(name, size, id)
    local fontdata = {}
    local cachedata = {}
    local s = cidfont_data[cid_name]
+   luatexja.rmlgbm.vert_addfunc(id, s.shared.ltj_vert_table)
    for k, v in pairs(s) do
       fontdata[k] = v
       cachedata[k] = v
@@ -330,11 +339,13 @@ local function font_callback(name, size, id, fallback)
    end
 end
 
-cid_reg, cid_order, cid_name, cid_supp = 'Adobe', 'Japan1', 'Adobe-Japan1'
-read_cid_font()
-
-
 luatexja.rmlgbm = {
    cidfont_data = cidfont_data,
    font_callback = font_callback,
+   vert_addfunc = function () end, -- dummy, set in ltj-direction.lua
 }
+
+cid_reg, cid_order, cid_name, cid_supp = 'Adobe', 'Japan1', 'Adobe-Japan1'
+read_cid_font()
+
+
index 93c7b49..7ce76b0 100644 (file)
@@ -45,6 +45,8 @@ local attr_jchar_class = luatexbase.attributes['ltj@charclass']
 local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
 local attr_yablshift = luatexbase.attributes['ltj@yablshift']
 local attr_ykblshift = luatexbase.attributes['ltj@ykblshift']
+local attr_tablshift = luatexbase.attributes['ltj@tablshift']
+local attr_tkblshift = luatexbase.attributes['ltj@tkblshift']
 local attr_icflag = luatexbase.attributes['ltj@icflag']
 
 local ltjf_font_metric_table = ltjf.font_metric_table
@@ -122,7 +124,7 @@ local function capsule_glyph_tate(p, met, class)
    setfield(p, 'char', ltjd.get_vert_glyph(getfont(p), getchar(p)))
 
       local y_shift
-         = - getfield(p, 'yoffset') + (has_attr(p,attr_ykblshift) or 0)
+         = - getfield(p, 'yoffset') + (has_attr(p,attr_tkblshift) or 0)
       local q
       head, q = node_remove(head, p)
       local box = node_new(id_hlist)
@@ -182,8 +184,9 @@ luatexja.setwidth.capsule_glyph_math = capsule_glyph_math
 function luatexja.setwidth.set_ja_width(ahead, adir)
    local p = ahead; head  = p; dir = adir or 'TLT'
    local m = false -- is in math mode?
-   local capsule_glyph = (ltjs.table_current_stack[DIR]==dir_yoko)
-      and capsule_glyph_yoko or capsule_glyph_tate
+   local is_dir_tate = ltjs.table_current_stack[DIR]==dir_tate
+   local capsule_glyph = is_dir_tate and capsule_glyph_tate or capsule_glyph_yoko
+   local attr_ablshift = is_dir_tate and attr_tablshift or attr_yablshift
    while p do
       local pid = getid(p)
       if (pid==id_glyph) 
@@ -195,7 +198,7 @@ function luatexja.setwidth.set_ja_width(ahead, adir)
         else
            set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p))
            setfield(p, 'yoffset',
-                    getfield(p, 'yoffset') - (has_attr(p,attr_yablshift) or 0))
+                    getfield(p, 'yoffset') - (has_attr(p,attr_ablshift) or 0))
            p = node_next(p)
         end
       elseif pid==id_math then
index ebd25c1..07e1adb 100644 (file)
 \newluatexattribute\ltj@charclass %
 \newluatexattribute\ltj@autospc   % attribute for autospacing
 \newluatexattribute\ltj@autoxspc  % attribute for autoxspacing
-\newluatexattribute\ltj@yablshift % attribute for \yabaselineshift
-\newluatexattribute\ltj@ykblshift % attribute for \ykbaselineshift
+\newluatexattribute\ltj@yablshift % attribute for yalbaselineshift
+\newluatexattribute\ltj@ykblshift % attribute for yjabaselineshift
+\newluatexattribute\ltj@tablshift % attribute for talbaselineshift
+\newluatexattribute\ltj@tkblshift % attribute for tjabaselineshift
 \newluatexattribute\jfam          % index for current jfam
 \newluatexattribute\ltj@dir       % temp attr for indicating box direction
 
   \directlua{tex.setattribute(luatexja.isglobal,
     luatexbase.attributes['ltj@ykblshift'],
     \ltj@safe@dimen@or\ltj@defdimen{#1})}}
+% talbaselineshift = <dimen>
+% tjabaselineshift = <dimen>
+\define@key[ltj]{japaram}{talbaselineshift}{%
+  \directlua{tex.setattribute(luatexja.isglobal,
+    luatexbase.attributes['ltj@tablshift'],
+    \ltj@safe@dimen@or\ltj@defdimen{#1})}}
+\define@key[ltj]{japaram}{tjabaselineshift}{%
+  \directlua{tex.setattribute(luatexja.isglobal,
+    luatexbase.attributes['ltj@tkblshift'],
+    \ltj@safe@dimen@or\ltj@defdimen{#1})}}
 
 % jaxspmode = {<char_code>, <mode>}
 % mode: inhibit, preonly, postonly, allow
index 3332c1e..7737163 100644 (file)
@@ -198,6 +198,12 @@ do
       yjabaselineshift = function(t) 
         return print_scaled(tex.getattribute('ltj@ykblshift'))..'pt'
       end,
+      talbaselineshift = function(t) 
+        return print_scaled(tex.getattribute('ltj@tablshift'))..'pt'
+      end,
+      tjabaselineshift = function(t) 
+        return print_scaled(tex.getattribute('ltj@tkblshift'))..'pt'
+      end,
       kanjiskip = function(t) 
         return print_spec(ltjs.get_stack_skip(stack_table_index.KSK, t))
       end,
@@ -295,7 +301,8 @@ do
    local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc
    local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc
    -- mode = true iff main_process is called from pre_linebreak_filter
-   local function main_process(head, mode, dir)
+   local function main_process(head, mode, dir, gc)
+      --print('main_process', gc, mode, tex.getcount('ltj@@stack'))
       tex.setattribute('global', attr_icflag, 0)
       local p = to_direct(head)
       p = ltjj.main(p,mode)
@@ -315,14 +322,14 @@ do
    luatexbase.add_to_callback(
       'pre_linebreak_filter', 
       function (head,groupcode)
-        return main_process(head, true, tex.textdir)
+        return main_process(head, true, tex.textdir, groupcode)
       end,'ltj.pre_linebreak_filter',
       luatexbase.priority_in_callback('pre_linebreak_filter',
                                      'luaotfload.node_processor') + 1)
    luatexbase.add_to_callback(
       'hpack_filter', 
       function (head,groupcode,size,packtype, dir)
-        return main_process(head, false, dir)
+        return main_process(head, false, dir, groupcode)
       end,'ltj.hpack_filter',
       luatexbase.priority_in_callback('hpack_filter',
                                      'luaotfload.node_processor') + 1)
@@ -363,16 +370,15 @@ local function debug_show_node_X(p,print_fn)
    local pt=node_type(p.id)
    local base = debug_depth .. string.format('%X', get_attr_icflag(p))
    .. ' ' .. pt .. ' ' .. tostring(p.subtype) .. ' '
-      .. ' dir=' .. tostring(has_attr(p, attr_dir)) .. ' '
    if pt == 'glyph' then
       s = base .. ' ' .. utf.char(p.char) .. ' '  .. tostring(p.font)
          .. ' (' .. print_scaled(p.height) .. '+' 
          .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
       print_fn(s)
-   elseif pt=='hlist' or pt=='vlist' then
+   elseif pt=='hlist' or pt=='vlist' or pt=='unset' then
       s = base .. '(' .. print_scaled(p.height) .. '+' 
          .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width) .. p.dir
-      if p.shift~=0 then
+      if p.shift or 0~=0 then
          s = s .. ', shifted ' .. print_scaled(p.shift)
       end
       if p.glue_sign >= 1 then 
@@ -429,7 +435,7 @@ local function debug_show_node_X(p,print_fn)
       end
       print_fn(s)
    elseif pt == 'whatsit' then
-      s = base
+      s = base .. '(' .. node.whatsits()[p.subtype] .. ') '
       if p.subtype==sid_user then
          if p.type ~= 110 then 
             s = s .. ' user_id: ' .. p.user_id .. ' ' .. p.value