OSDN Git Service

Another rewrite (not yet finished)
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Sun, 8 May 2011 21:19:16 +0000 (06:19 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Sun, 8 May 2011 21:19:16 +0000 (06:19 +0900)
src/luatexja-core.lua
src/luatexja-core.sty
src/luatexja-rmlgbm.lua
src/luatexja-xkanji.lua
test/jfm-test.lua [new file with mode: 0644]
test/test04-jfm.pdf
test/test04-jfm.tex

index ca6391c..ce7cd0e 100644 (file)
@@ -41,6 +41,8 @@ local TEMPORARY = 2
 local FROM_JFM = 3
 local KINSOKU = 4
 local LINE_END = 5
+local KANJI_SKIP = 6
+local XKANJI_SKIP = 7
 
 ------------------------------------------------------------------------
 -- naming:
@@ -270,7 +272,7 @@ local function main1_suppress_hyphenate_ja(head)
       end
    end
    lang.hyphenate(head)
-   return head -- 互換性のために値を返す
+   return head
 end
 
 -- CALLBACKS
@@ -397,10 +399,14 @@ function debug_show_node_list_X(p,print_fn)
       elseif pt == 'glue' then
         s = debug_depth.. ' glue   ' ..  p.subtype 
            .. ' ' ..  print_spec(p.spec)
-        if has_attr(p, attr_icflag)==2 then
+        if has_attr(p, attr_icflag)==TEMPORARY then
            s = s .. ' (might be replaced)'
-        elseif has_attr(p, attr_icflag)==3 then
+        elseif has_attr(p, attr_icflag)==FROM_JFM then
            s = s .. ' (from JFM)'
+        elseif has_attr(p, attr_icflag)==KANJI_SKIP then
+           s = s .. ' (kanjiskip)'
+        elseif has_attr(p, attr_icflag)==XKANJI_SKIP then
+           s = s .. ' (xkanjiskip)'
         end
         print_fn(s)
       elseif pt == 'kern' then
index 5c9d43e..6ad407c 100644 (file)
@@ -15,8 +15,6 @@
 \newcount\ltj@tempcntc
 \newdimen\ltj@tempdima
 
-\newcount\ltj@autospc
-\newcount\ltj@autoxspc
 
 \newcount\jcharwidowpenalty
 \newskip\kanjiskip
index 1a7dbfc..8cace65 100644 (file)
@@ -1,7 +1,7 @@
 local rmlgbm_data = require('luatexja-rmlgbm-data')
+local cache_chars = { [655360] = rmlgbm_data.characters }
 
 local function mk_rml(name, size, id)
-
    local specification = fonts.define.analyze(name,size)
    specification = fonts.define.specify[':'](specification)
    local features = specification.features.normal
@@ -12,7 +12,8 @@ local function mk_rml(name, size, id)
       fontdata[k] = v
       cachedata[k] = v
    end
-
+   fontdata.characters = nil
+   cachedata.characters = nil
    fontdata.unicodes = nil
    fontdata.shared = nil
    cachedata.shared = {}
@@ -25,19 +26,19 @@ local function mk_rml(name, size, id)
    shared.processes, shared.features = fonts.otf.set_features(cachedata,fonts.define.check(features,fonts.otf.features.default))
    
    -- characters & scaling
-   local characters = {}
-   local orig_chars = rmlgbm_data.characters
    if size < 0 then size = -size * 655.36 end
    local scale = size / 655360
-   -- local size_cache = {}
-   for k, v in pairs(orig_chars) do
-      characters[k] = {}
-      characters[k].index = v.index
-      characters[k].width = v.width * scale
-      characters[k].tounicode = v.tounicode
+   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
+      end
    end
-   fontdata.characters = characters
-   cachedata.characters = characters
+   fontdata.characters = cache_chars[size]
+   cachedata.characters = cache_chars[size]
 
    local parameters = {}
    for k, v in pairs(rmlgbm_data.parameters) do
index 0c9abe3..f09bd78 100644 (file)
@@ -36,12 +36,15 @@ local TEMPORARY = 2
 local FROM_JFM = 3
 local KINSOKU = 4
 local LINE_END = 5
+local KANJI_SKIP = 6
+local XKANJI_SKIP = 7
 
 local kanji_skip
 local xkanji_skip
 
 -- (glyph_node nr) ... (node nq) <GLUE> ,,, (node np)
-local np, nq, nrc
+local np, nq, nrc, nrf
+local np_spc, nr_spc
 local no_skip = 0 
 local after_schar = 1
 local after_wchar = 2 -- nr is a Japanese glyph_node
@@ -62,6 +65,32 @@ local function get_zero_glue()
    return g
 end
 
+local function get_kanji_skip_from_jfm(pf)
+   if pf then
+      local px = { ltj.font_metric_table[pf].size, 
+                  ltj.font_metric_table[pf].jfm }
+      local i = ltj.metrics[px[2]].kanjiskip
+      if i then
+        return { round(i[1]*px[1]), round(i[2]*px[1]), round(i[3]*px[1]) }
+      else return nil
+      end
+   else return nil
+   end
+end
+
+local function get_xkanji_skip_from_jfm(pf)
+   if pf then
+      local px = { ltj.font_metric_table[pf].size, 
+                  ltj.font_metric_table[pf].jfm }
+      local i = ltj.metrics[px[2]].xkanjiskip
+      if i then
+        return { round(i[1]*px[1]), round(i[2]*px[1]), round(i[3]*px[1]) }
+      else return nil
+      end
+   else return nil
+   end
+end
+
 -- the following 2 functions are the lowest part.
 -- cx: the Kanji code of np
 local function insert_ascii_kanji_xkskip(q, cx)
@@ -72,7 +101,7 @@ local function insert_ascii_kanji_xkskip(q, cx)
 end
 
 local function insert_kanji_ascii_xkskip(q, p)
-   local g=true
+   local g = true
    local c = p.char
    while p.components and p.subtype 
       and math.floor(p.subtype/2)%2==1 do
@@ -82,10 +111,38 @@ local function insert_kanji_ascii_xkskip(q, p)
       if cstb_get_inhibit_xsp_table(nrc)%2 == 0 then g = false end
    else g = false
    end
-   if g then
-      g = node_new(id_glue)
-      g.subtype = 0; g.spec = node.copy(xkanji_skip)
-      node_insert_after(head, q, g)
+   if g then -- 挿入
+      g = node_new(id_glue); g.subtype = 0
+      if nr_spc[1] or np_spc[1] then
+        if xkanji_skip.width==max_dimen then -- use kanjiskip from JFM
+           local gx = node_new(id_glue_spec);
+           gx.stretch_order = 0; gx.shrink_order = 0
+           local ak = get_xkanji_skip_from_jfm(p.font)
+           if ak then
+              gx.width = ak[1]; gx.stretch = ak[2]; gx.shrink = ak[3]
+           else gx = get_zero_glue() -- fallback
+           end
+           g.spec = gx
+        else g.spec=node.copy(xkanji_skip)
+        end
+      else g.spec = get_zero_glue()
+      end
+      local h = node_prev(p)
+      if h  and has_attr(h, attr_icflag)==TEMPORARY then
+        if h.id==id_kern then
+           g.spec.width = g.spec.width + h.kern
+           node.set_attribute(g,attr_icflag,XKANJI_SKIP)
+           node_insert_after(head, q, g)
+           head = node.remove(head, h)
+        else
+           h.spec.width = g.spec.width + h.spec.width
+           h.spec.stretch = g.spec.stretch + h.spec.stretch
+           h.spec.shrink = g.spec.shrink + h.spec.shrink
+        end
+      else
+        node.set_attribute(g,attr_icflag,XKANJI_SKIP)
+        node_insert_after(head, q, g)
+      end
    end
 end
 
@@ -103,57 +160,47 @@ local function set_insert_skip_after_achar(p)
   end
 end
 
-local function get_kanji_skip_from_jfm(p)
-   local px = { ltj.font_metric_table[p.font].size, 
-               ltj.font_metric_table[p.font].jfm }
-   local i = ltj.metrics[px[2]].kanjiskip
-   print(p.font, px[1], px[2], ltj.metrics[px[2]].dir, i)
-   if i then
-      return { round(i[1]*px[1]), round(i[2]*px[1]), round(i[3]*px[1]) }
-   else return nil
-   end
-end
-
 local function insert_kanji_skip()
-   print('a', utf.char(np.char))
-   local g = node_new(id_glue); g.subtype=0
-   if kanji_skip.width==max_dimen then -- use kanjiskip from JFM
-      local gx = node_new(id_glue_spec);
-      gx.stretch_order = 0; gx.shrink_order = 0
-      local bk = nil -- incomplete
-      local ak = get_kanji_skip_from_jfm(np)
-      if bk then
-        if ak then
-           gx.width = round(ltj.ja_diffmet_rule(bk[1], ak[1]))
-           gx.stretch = round(ltj.ja_diffmet_rule(bk[2], ak[2]))
-           gx.shrink = -round(ltj.ja_diffmet_rule(-bk[3], -ak[3]))
+      local g = node_new(id_glue); g.subtype=0
+      if nr_spc[1] or np_spc[1] then
+        if kanji_skip.width==max_dimen then -- use kanjiskip from JFM
+           local gx = node_new(id_glue_spec);
+           gx.stretch_order = 0; gx.shrink_order = 0
+           local bk = get_kanji_skip_from_jfm(nrf)
+           local ak = get_kanji_skip_from_jfm(np.font)
+           if bk then
+              if ak then
+                 gx.width = round(ltj.ja_diffmet_rule(bk[1], ak[1]))
+                 gx.stretch = round(ltj.ja_diffmet_rule(bk[2], ak[2]))
+                 gx.shrink = -round(ltj.ja_diffmet_rule(-bk[3], -ak[3]))
+              else
+                 gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3]
+              end
+           elseif ak then
+              gx.width = ak[1]; gx.stretch = ak[2]; gx.shrink = ak[3]
+           else gx = get_zero_glue() -- fallback
+           end
+           g.spec = gx
+        else g.spec=node.copy(kanji_skip)
+        end
+      else g.spec = get_zero_glue()
+      end
+      local h = node_prev(np)
+      if h  and has_attr(h, attr_icflag)==TEMPORARY then
+        if h.id==id_kern then
+           g.spec.width = g.spec.width + h.kern
+           head = node.remove(head, h)
+           node.set_attribute(g,attr_icflag,KANJI_SKIP)
+           node_insert_before(head, np, g)
         else
-           gx.width = bk[1]; gx.stretch = bk[2]; gx.shrink = bk[3]
+           h.spec.width = g.spec.width + h.spec.width
+           h.spec.stretch = g.spec.stretch + h.spec.stretch
+           h.spec.shrink = g.spec.shrink + h.spec.shrink
         end
-      elseif ak then
-        gx.width = ak[1]; gx.stretch = ak[2]; gx.shrink = ak[3]
       else
-        gx = get_zero_glue()-- ???
-      end
-      g.spec = gx
-   else
-      g.spec=node.copy(kanji_skip)
-   end
-   local h = node_prev(np)
-   if h  and has_attr(h, attr_icflag)==TEMPORARY then
-      if h.id==id_kern then
-        g.spec.width = g.spec.width + h.kern
-        head = node.remove(head, h)
+        node.set_attribute(g,attr_icflag,KANJI_SKIP)
         node_insert_before(head, np, g)
-      else
-        h.spec.width = g.spec.width + h.spec.width
-        h.spec.stretch = g.spec.stretch + h.spec.stretch
-        h.spec.shrink = g.spec.shrink + h.spec.shrink
       end
-   else
-      node_insert_before(head, np, g)
-   end
-   print('b', utf.char(np.char))
 end
 
 -- When p is a glyph_node ...
@@ -164,12 +211,13 @@ local function insks_around_char()
       elseif insert_skip==after_schar then
         insert_ascii_kanji_xkskip(nq, np.char)
       end
-      insert_skip=after_wchar; nrc = np.char
+      insert_skip=after_wchar
+      nrc = np.char; nrf = np.font; nr_spc = np_spc
    else
       if insert_skip==after_wchar then
         insert_kanji_ascii_xkskip(nq, np)
       end
-      set_insert_skip_after_achar(np)
+      set_insert_skip_after_achar(np); nr_spc = np_spc
    end
    nq = np
 end
@@ -224,10 +272,12 @@ local function insks_around_hbox()
       if check_box(np.head) then
         -- first char
         if is_japanese_glyph_node(first_char) then
-           nrc = first_char.char
+           nrc = first_char.char; nrf = first_char.font
            if insert_skip==after_schar then 
               insert_ascii_kanji_xkskip(nq, first_char.char)
            elseif insert_skip==after_wchar then
+              np_spc = { has_attr(first_char, attr_autospc)==1, 
+                         has_attr(first_char, attr_autoxspc)==1 }
               insert_kanji_skip()
            end
            insert_skip = after_wchar
@@ -244,9 +294,14 @@ local function insks_around_hbox()
               g.subtype = 0; g.spec = node.copy(kanji_skip)
               node_insert_after(head, np, g)
            end
-           insert_skip = after_wchar; nrc = last_char.char
+           insert_skip = after_wchar
+           nrc = last_char.char; nrf = last_char.font
+           nr_spc = { has_attr(last_char, attr_autospc)==1, 
+                      has_attr(last_char, attr_autoxspc)==1 }
         elseif last_char then
            set_insert_skip_after_achar(last_char)
+           nr_spc = { has_attr(last_char, attr_autospc)==1, 
+                      has_attr(last_char, attr_autoxspc)==1 }
         else insert_skip = no_skip
         end
       else insert_skip = no_skip
@@ -284,7 +339,7 @@ local function insks_around_math()
       insert_kanji_ascii_xkskip(nq, g)
       insert_skip = no_skip
    else
-      nq = np; set_insert_skip_after_achar(g)
+      nq = np; set_insert_skip_after_achar(g); nr_spc = np_spc
    end
 end
 
@@ -294,8 +349,12 @@ function ltj.int_insert_kanji_skip(ahead)
    head = ahead
    np = head; nq = nil; insert_skip = no_skip
    while np do
+      np_spc = { (has_attr(np, attr_autospc)==1), 
+                (has_attr(np, attr_autoxspc)==1) }
       if np.id==id_glyph then
         repeat 
+           np_spc = { has_attr(np, attr_autospc)==1, 
+                      has_attr(np, attr_autoxspc)==1 }
            insks_around_char(); np=node_next(np)
         until (not np) or np.id~=id_glyph
       else
diff --git a/test/jfm-test.lua b/test/jfm-test.lua
new file mode 100644 (file)
index 0000000..00e7ed5
--- /dev/null
@@ -0,0 +1,68 @@
+ltj.define_jfm {
+   dir = 'yoko',
+   zw = 1.0, zh = 1.0,
+   kanjiskip = { 0.0, 0.04, 0.05 },
+   xkanjiskip = { 0.25, 0.083, 0.083 },
+
+   [0] = {
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+   },
+   [1] = {
+      chars = { 'あ' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+      glue = { [3] = { 1.41, 0, 0} },
+      kern = { [8] = -1.41 , [2] = 2.0, [99] = 1.21 }
+   },
+   [11] = {
+      chars = { 'い' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+      glue = { [3] = { 1.41, 0, 0} },
+      kern = { [2] = 2.0, }
+   },
+   [21] = {
+      chars = { 'う' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+      glue = { [3] = { 1.41, 0, 0}, [99] ={ 1.73, 0, 0}  },
+      kern = { [8] = -1.41 , [2] = 2.0, }
+   },
+   [31] = {
+      chars = { 'え' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+      glue = { [3] = { 1.41, 0, 0} },
+      kern = { [2] = 2.0, [99] = 1.73}
+   },
+   [41] = {
+      chars = { 'お' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+      kern = { [8] = -1.41 , [2] = 2.0}
+   },
+
+   [2] = {
+      chars = { 'ア' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0
+   },
+   [3] = {
+      chars = { 'ウ' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0
+   },
+   [99] = {
+      chars = { 'jcharbdd' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+      glue = { [11] = { 1.41, 0, 0} },
+      kern = { [21] = 2.0, }
+   },
+   [8] = {
+      chars = { 'lineend' },
+      align = 'left', left = 0.0, down = 0.0,
+      width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+   }
+}
index ede188e..963b705 100644 (file)
Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ
index 6d34690..644ed9d 100644 (file)
@@ -1,7 +1,7 @@
 %#!luatex
 \input luatexja-core.sty
 
-\def\head#1{\medskip\noindent{\bf\tengt ■ #1}\par}
+\def\head#1{\medskip\penalty-100\noindent{\bf\tengt ■ #1}\par\penalty10000}
 \jfont\rml={psft:Ryumin-Light:jfm=ujis} at 10pt
 \rml あ\inhibitglue\char"201Cあ・い←Ryumin-Light
 
 
 \vfill\eject
 \kanjiskip=\maxdimen
-\setbox0=\hbox{\rmlh ンン}\dumplist0
+\message{SSS}
+\setbox0=\hbox{\rmlh \ltjsetparameter{autospacing=true}ンン\ltjsetparameter{autospacing=false}ンン}\message{SSS}
+\dumplist0
 
 \end