From: Hironori Kitagawa Date: Sun, 8 May 2011 21:19:16 +0000 (+0900) Subject: Another rewrite (not yet finished) X-Git-Tag: master-20110808~12 X-Git-Url: http://git.osdn.jp/view?a=commitdiff_plain;h=758f2ea699a9424c6d0e40f6209e408f290c9ff2;p=luatex-ja%2Fluatexja.git Another rewrite (not yet finished) --- diff --git a/src/luatexja-core.lua b/src/luatexja-core.lua index ca6391c..ce7cd0e 100644 --- a/src/luatexja-core.lua +++ b/src/luatexja-core.lua @@ -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 diff --git a/src/luatexja-core.sty b/src/luatexja-core.sty index 5c9d43e..6ad407c 100644 --- a/src/luatexja-core.sty +++ b/src/luatexja-core.sty @@ -15,8 +15,6 @@ \newcount\ltj@tempcntc \newdimen\ltj@tempdima -\newcount\ltj@autospc -\newcount\ltj@autoxspc \newcount\jcharwidowpenalty \newskip\kanjiskip diff --git a/src/luatexja-rmlgbm.lua b/src/luatexja-rmlgbm.lua index 1a7dbfc..8cace65 100644 --- a/src/luatexja-rmlgbm.lua +++ b/src/luatexja-rmlgbm.lua @@ -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 diff --git a/src/luatexja-xkanji.lua b/src/luatexja-xkanji.lua index 0c9abe3..f09bd78 100644 --- a/src/luatexja-xkanji.lua +++ b/src/luatexja-xkanji.lua @@ -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) ,,, (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 index 0000000..00e7ed5 --- /dev/null +++ b/test/jfm-test.lua @@ -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, + } +} diff --git a/test/test04-jfm.pdf b/test/test04-jfm.pdf index ede188e..963b705 100644 Binary files a/test/test04-jfm.pdf and b/test/test04-jfm.pdf differ diff --git a/test/test04-jfm.tex b/test/test04-jfm.tex index 6d34690..644ed9d 100644 --- a/test/test04-jfm.tex +++ b/test/test04-jfm.tex @@ -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 @@ -175,6 +175,8 @@ \vfill\eject \kanjiskip=\maxdimen -\setbox0=\hbox{\rmlh ンン}\dumplist0 +\message{SSS} +\setbox0=\hbox{\rmlh \ltjsetparameter{autospacing=true}ンン\ltjsetparameter{autospacing=false}ンン}\message{SSS} +\dumplist0 \end