OSDN Git Service

Added cache tables of JFM for speed. (quick fix)
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Fri, 23 Sep 2011 07:24:04 +0000 (16:24 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Fri, 23 Sep 2011 07:24:04 +0000 (16:24 +0900)
src/luatexja-core.lua
src/luatexja/jfmglue.lua
src/luatexja/jfont.lua
src/luatexja/math.lua
src/luatexja/setwidth.lua
test/test04-jfm.pdf
test/test05-speed.tex

index 35448bd..aab611c 100644 (file)
@@ -18,7 +18,6 @@ local has_attr = node.has_attribute
 local node_insert_before = node.insert_before
 local node_insert_after = node.insert_after
 local node_hpack = node.hpack
-local round = tex.round
 
 local id_penalty = node.id('penalty')
 local id_glyph = node.id('glyph')
@@ -288,7 +287,7 @@ function debug_show_node_X(p,print_fn)
         s = s .. node.subtype(p.subtype)
       end
       print_fn(s)
-   --  ここから数式用 node
+   -------- math node --------
    elseif pt=='noad' then
       s = base ; print_fn(s)
       if p.nucleus then
index 598d94e..902d81c 100644 (file)
@@ -305,9 +305,9 @@ local function set_np_xspc_jachar(c,x)
    Np.pre = ltjs.get_penalty_table('pre', c, 0, ltjp.box_stack_level)
    Np.post = ltjs.get_penalty_table('post', c, 0, ltjp.box_stack_level)
    z = find_char_class('lineend', Np.met)
-   local y = Np.met.char_type[Np.class]
+   local y = Np.met.size_cache[Np.size].char_type[Np.class]
    if y.kern and y.kern[z] then 
-      Np.lend = round(Np.size*y.kern[z]) 
+      Np.lend = y.kern[z]
    else 
       Np.lend = 0 
    end
@@ -471,18 +471,18 @@ end
 local function new_jfm_glue(Nn, bc, ac)
 -- bc, ac: char classes
    local g = nil
-   local z = Nn.met.char_type[bc]
+   local z = Nn.met.size_cache[Nn.size].char_type[bc]
    if z.glue and z.glue[ac] then
       local h = node_new(id_glue_spec)
-      h.width   = round(Nn.size*z.glue[ac][1])
-      h.stretch = round(Nn.size*z.glue[ac][2])
-      h.shrink  = round(Nn.size*z.glue[ac][3])
+      h.width   = z.glue[ac][1]
+      h.stretch = z.glue[ac][2]
+      h.shrink  = z.glue[ac][3]
       h.stretch_order=0; h.shrink_order=0
       g = node_new(id_glue)
       g.subtype = 0; g.spec = h
    elseif z.kern and z.kern[ac] then
       g = node_new(id_kern)
-      g.subtype = 1; g.kern = round(Nn.size*z.kern[ac])
+      g.subtype = 1; g.kern = z.kern[ac]
    end
    if g then set_attr(g, attr_icflag, FROM_JFM) end
    return g
@@ -506,9 +506,9 @@ end
 
 -- get kanjiskip
 local function get_kanji_skip_from_jfm(Nn)
-   local i = Nn.met.kanjiskip
+   local i = Nn.met.size_cache[Nn.size].kanjiskip
    if i then
-      return { round(i[1]*Nn.size), round(i[2]*Nn.size), round(i[3]*Nn.size) }
+      return { i[1], i[2], i[3] }
    else return nil
    end
 end
@@ -600,9 +600,9 @@ end
 
 -- get xkanjiskip
 local function get_xkanji_skip_from_jfm(Nn)
-   local i = Nn.met.xkanjiskip
+   local i = Nn.met.size_cache[Nn.size].xkanjiskip
    if i then
-      return { round(i[1]*Nn.size), round(i[2]*Nn.size), round(i[3]*Nn.size) }
+      return { i[1], i[2], i[3] }
    else return nil
    end
 end
index 628952c..323114b 100644 (file)
@@ -96,9 +96,36 @@ function define_jfm(t)
         t[i] = nil
       end
    end
+   t.size_cache = {}
    defjfm_res= t
 end
 
+local function mult_table(old,scale) -- modified from table.fastcopy
+    if old then
+       local new = { }
+       for k,v in next, old do
+         if type(v) == "table" then
+            new[k] = mult_table(v,scale)
+         elseif type(v) == "number" then
+            new[k] = round(v*scale)
+         else
+            new[k] = v
+         end
+       end
+       return new
+    else return nil end
+end
+
+local function update_jfm_cache(j,sz)
+   if metrics[j].size_cache[sz] then return end
+   metrics[j].size_cache[sz] = {}
+   metrics[j].size_cache[sz].char_type = mult_table(metrics[j].char_type, sz)
+   metrics[j].size_cache[sz].kanjijskip = mult_table(metrics[j].kanjiskip, sz)
+   metrics[j].size_cache[sz].xkanjiskip = mult_table(metrics[j].xkanjiskip,sz)
+   metrics[j].size_cache[sz].zw = round(metrics[j].zw*sz)
+   metrics[j].size_cache[sz].zh = round(metrics[j].zh*sz)
+end
+
 function find_char_class(c,m)
 -- c: character code, m
    if not metrics[m] then return 0 end
@@ -158,6 +185,7 @@ function jfontdefY() -- for horizontal font
    font_metric_table[fn].jfm=j
    font_metric_table[fn].size=f.size
    font_metric_table[fn].var=jfm_var
+   update_jfm_cache(j, f.size)
    tex.sprint(cat_lp, ltj.is_global .. '\\protected\\expandafter\\def\\csname ' 
           .. cstemp  .. '\\endcsname{\\ltj@curjfnt=' .. fn .. '\\relax}')
 end
@@ -166,7 +194,7 @@ end
 function load_zw()
    local a = font_metric_table[tex.attribute[attr_curjfnt]]
    if a then
-      tex.setdimen('ltj@zw', round(a.size*metrics[a.jfm].zw))
+      tex.setdimen('ltj@zw', metrics[a.jfm].size_cache[a.size].zw)
    else 
       tex.setdimen('ltj@zw',0)
    end
@@ -175,9 +203,9 @@ end
 function load_zh()
    local a = font_metric_table[tex.attribute[attr_curjfnt]]
    if a then
-      tex.setdimen('ltj@zh', round(a.size*metrics[a.jfm].zh))
+      tex.setdimen('ltj@zh', metrics[a.jfm].size_cache[a.size].zh)
    else 
-      tex.setdimen('ltj@zh', round(a.size*metrics[a.jfm].zh))
+      tex.setdimen('ltj@zh',0)
    end
 end
 
@@ -231,7 +259,7 @@ function append_italic()
         f = has_attr(p, attr_curjfnt)
         local j = font_metric_table[f]
         local c = find_char_class(p.char, j.jfm)
-        g.kern = round(j.size * metrics[j.jfm].char_type[c].italic)
+        g.kern = metrics[j.jfm].size_cache[j.size].char_type[c].italic
       else
         g.kern = font.fonts[f].characters[p.char].italic
       end
index 73ded5e..6669512 100644 (file)
@@ -104,8 +104,8 @@ function (p, sty)
            set_attr(r, attr_yablshift, 0)
            local class = ltjf.find_char_class(p.char, ltjf.font_metric_table[f].jfm)
            set_attr(r, attr_jchar_class, class)
-           ltjw.met_tb = ltjf.font_metric_table[f]
-           ltjw.char_data = ltjf.metrics[ltjw.met_tb.jfm].char_type[class]
+           local met = ltjf.font_metric_table[f]
+           ltjw.char_data = ltjf.metrics[met.jfm].size_cache[met.size].char_type[class]
            ltjw.head = r; ltjw.capsule_glyph(r, tex.mathdir , true);
            q.head = ltjw.head; node_free(p); p=q;
         end
index 84c0ac6..2556fad 100644 (file)
@@ -37,7 +37,6 @@ local attr_icflag = luatexbase.attributes['ltj@icflag']
 
 local PACKED = 2
 
-met_tb = {}
 char_data = {}
 head = nil
 
@@ -49,15 +48,15 @@ end
 -- mode: true iff p will be always encapsuled by a hbox
 function capsule_glyph(p, dir, mode)
    local h, box, q, fwidth, fheight, fdepth
-   p.xoffset= p.xoffset - round(met_tb.size*char_data.left)
+   p.xoffset= p.xoffset - char_data.left
    if char_data.width ~= 'prop' then
-      fwidth = round(char_data.width*met_tb.size)
+      fwidth = char_data.width
    else fwidth = p.width end
-   fheight = round(met_tb.size*char_data.height)
-   fdepth = round(met_tb.size*char_data.depth)
+   fheight = char_data.height
+   fdepth = char_data.depth
    if mode or p.width ~= fwidth or p.height ~= fheight or p.depth ~= fdepth then
       local y_shift = - p.yoffset + (has_attr(p,attr_yablshift) or 0)
-      p.yoffset = -round(met_tb.size*char_data.down)
+      p.yoffset = -char_data.down
       head, q = node.remove(head, p)
       local total = fwidth - p.width
       if total == 0 then
@@ -86,7 +85,7 @@ function capsule_glyph(p, dir, mode)
       end
       return q
    else
-      p.yoffset = p.yoffset - (has_attr(p, attr_yablshift) or 0) - round(met_tb.size*char_data.down)
+      p.yoffset = p.yoffset - (has_attr(p, attr_yablshift) or 0) - char_data.down
       return node_next(p)
    end
 end
@@ -97,8 +96,8 @@ function set_ja_width(ahead, dir)
    while p do
       if p.id==id_glyph then
         if is_japanese_glyph_node(p) then
-           met_tb = ltjf.font_metric_table[p.font]
-           char_data = ltjf.metrics[met_tb.jfm].char_type[has_attr(p, attr_jchar_class)]
+           local met = ltjf.font_metric_table[p.font]
+           char_data = ltjf.metrics[met.jfm].size_cache[met.size].char_type[has_attr(p, attr_jchar_class)]
            p = capsule_glyph(p, dir, false)
         else 
            p.yoffset = p.yoffset - (has_attr(p,attr_yablshift) or 0); p = node_next(p)
index 2115345..5c1734c 100644 (file)
Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ
index 1be795a..9456ae5 100644 (file)
@@ -1,4 +1,4 @@
-%#! time luatex  "\count300=40\input test05-speed.tex"
+%#! time luatex  "\count300=10\input test05-speed.tex"
 \input luatexja-core.sty
 
 \newcount\cnt\newcount\cnta
@@ -13,8 +13,8 @@
 \end
 
 %     real time:
-% 40: 17.453
-% 30: 13.254
-% 20:  8.771
-% 10:  4.927
+% 40: 17.453 14.234s
+% 30: 13.254 10.624
+% 20:  8.771  7.097
+% 10:  4.927  4.145
 % env: C2D E7300, Mem 4GB, LuaTeX 0.71.0pre, Gentoo amd64 unstable
\ No newline at end of file