From ceff00fea0513d997cf985dcc39db0190f390be0 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 2 Aug 2019 21:18:39 +0000 Subject: luatexko (1aug19) git-svn-id: svn://tug.org/texlive/trunk@51803 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/luatex/luatexko/luatexko-normalize.lua | 4 +- .../tex/luatex/luatexko/luatexko-uhc2utf8.lua | 4 +- Master/texmf-dist/tex/luatex/luatexko/luatexko.lua | 347 +++++++++++++-------- Master/texmf-dist/tex/luatex/luatexko/luatexko.sty | 6 +- 4 files changed, 225 insertions(+), 136 deletions(-) (limited to 'Master/texmf-dist/tex/luatex') diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua index 9213f4c3e1b..97c2b0ccf87 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua @@ -13,8 +13,8 @@ luatexbase.provides_module({ name = "luatexko-normalize", - version = "2.3", - date = "2019/06/21", + version = "2.4", + date = "2019/08/01", author = "Dohyun Kim, Soojin Nam", description = "Hangul normalization", license = "LPPL v1.3+", diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua index a26f6212383..82d11379cb5 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua @@ -13,8 +13,8 @@ luatexbase.provides_module({ name = "luatexko-uhc2utf8", - version = "2.3", - date = "2019/06/21", + version = "2.4", + date = "2019/08/01", author = "Dohyun Kim, Soojin Nam", description = "UHC (CP949) input encoding", license = "LPPL v1.3+", diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua index 5f6cd602e53..3ab4f18961a 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua @@ -13,8 +13,8 @@ luatexbase.provides_module { name = 'luatexko', - date = '2019/06/21', - version = '2.3', + date = '2019/08/01', + version = '2.4', description = 'typesetting Korean with LuaTeX', author = 'Dohyun Kim, Soojin Nam', license = 'LPPL v1.3+', @@ -52,11 +52,12 @@ local fontfonts = font.fonts local fontgetfont = font.getfont local getparameters = font.getparameters -local texcount = tex.count -local texround = tex.round -local texset = tex.set -local texsp = tex.sp -local texsprint = tex.sprint +local texattribute = tex.attribute +local texcount = tex.count +local texset = tex.set +local texsp = tex.sp + +local set_macro = token.set_macro local stringformat = string.format @@ -142,6 +143,10 @@ local hangul_tonemark = { [0x302E] = true, [0x302F] = true, } +local function is_compat_jamo (c) + return c >= 0x3131 and c <= 0x318E +end + local function is_unicode_var_sel (c) return c >= 0xFE00 and c <= 0xFE0F or c >= 0xE0100 and c <= 0xE01EF @@ -180,10 +185,10 @@ end local function is_hangul_jamo (c) return is_hangul(c) + or is_compat_jamo(c) or is_chosong(c) or is_jungsong(c) or is_jongsong(c) - or c >= 0x3131 and c <= 0x318E end local stretch_f = 5/100 -- should be consistent for ruby @@ -306,7 +311,7 @@ local function hangul_space_skip (curr, newfont) newsp = nodes.simple_font_handler(newsp) newwd = newsp and newsp.width or false if newwd then - newwd = { texround(newwd), texround(newwd/2), texround(newwd/3) } + newwd = { texsp(newwd), texsp(newwd/2), texsp(newwd/3) } end char_font_options.hangulspaceskip[newfont] = newwd if newsp then @@ -337,13 +342,22 @@ local function process_fonts (head) hangul_space_skip(curr, p.font) curr.font = p.font end + + if not active_processes.reorderTM and + hangul_tonemark[c] and + option_in_font(curr.font, "script") == "hang" then + luatexko.activate("reorderTM") -- activate reorderTM here + active_processes.reorderTM = true + end + else local hf = has_attribute(curr, hangulfontattr) or false local hjf = has_attribute(curr, hanjafontattr) or false - local fontdata = get_font_data(curr.font) - local format = fontdata.format - local no_legacy = format == "opentype" or format == "truetype" - if hf and no_legacy and force_hangul[c] and curr.lang ~= nohyphen then + local fontdata = get_font_data(curr.font) + local format = fontdata.format + local encode = fontdata.encodingbytes + local widefont = encode == 2 or format == "opentype" or format == "truetype" + if hf and widefont and force_hangul[c] and curr.lang ~= nohyphen then curr.font = hf elseif hf and luatexko.hangulbyhangulfont and is_hangul_jamo(c) then hangul_space_skip(curr, hf) @@ -363,13 +377,6 @@ local function process_fonts (head) end end - if not active_processes.reorderTM - and hangul_tonemark[c] - and option_in_font(curr.font, "script") == "hang" then - luatexko.activate("reorderTM") -- activate reorderTM here - active_processes.reorderTM = true - end - props.unicode = c end elseif id == discid then @@ -469,11 +476,11 @@ local breakable_after = setmetatable({ [0xFF1E] = true, [0xFF5E] = true, [0xFF70] = true, },{ __index = function (_,c) return is_hangul_jamo(c) and not is_chosong(c) - or is_noncjk_char(c) - or is_hanja(c) - or is_cjk_combining(c) - or is_kana(c) - or charclass[c] >= 2 + or is_noncjk_char(c) + or is_hanja(c) + or is_cjk_combining(c) + or is_kana(c) + or charclass[c] >= 2 end }) luatexko.breakableafter = breakable_after @@ -498,10 +505,12 @@ local breakable_before = setmetatable({ [0xFF6F] = 1000, [0x1B150] = 1000, [0x1B151] = 1000, [0x1B152] = 1000, [0x1B164] = 1000, [0x1B165] = 1000, [0x1B166] = 1000, [0x1B167] = 1000, },{ __index = function(_,c) - return is_hangul_jamo(c) and not is_jungsong(c) and not is_jongsong(c) - or is_hanja(c) - or is_kana(c) - or charclass[c] == 1 + return is_hangul(c) + or is_compat_jamo(c) + or is_chosong(c) + or is_hanja(c) + or is_kana(c) + or charclass[c] == 1 end }) luatexko.breakablebefore = breakable_before @@ -521,14 +530,50 @@ local function is_blocking_node (curr) end local function ruby_char_font (rb) - local n, c, f = has_glyph(rb.list), 0, 0 + local n = has_glyph(rb.list) if n then - c, f = my_node_props(n).unicode or n.char, n.font or 0 + local c, f = my_node_props(n).unicode or n.char, n.font if is_chosong(c) or hangul_tonemark[c] then c = 0xAC00 end + return c, f + end +end + +local function hbox_ini_char_font (box) + local curr = box.list + while curr do + local id = curr.id + if id == glyphid then + local c = my_node_props(curr).unicode or curr.char + if c and not is_cjk_combining(c) then + return c, curr.font + end + elseif id == hlistid and curr.list then + return hbox_ini_char_font(curr) + elseif is_blocking_node(curr) then + return + end + curr = getnext(curr) + end +end + +local function hbox_fin_char_font (box) + local curr = nodeslide(box.list) + while curr do + local id = curr.id + if id == glyphid then + local c = my_node_props(curr).unicode or curr.char + if c and not is_cjk_combining(c) then + return c, curr.font + end + elseif id == hlistid and curr.list then + return hbox_fin_char_font(curr) + elseif is_blocking_node(curr) then + return + end + curr = getprev(curr) end - return c, f end local function get_actualtext (curr) @@ -626,20 +671,35 @@ local function process_linebreak (head, par) while curr do local id = curr.id if id == glyphid then - local cc = my_node_props(curr).unicode or curr.char - local old = has_attribute(curr, classicattr) - head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, old, curr.font, par) + local c = my_node_props(curr).unicode or curr.char + if c and not is_unicode_var_sel(c) then + local old = has_attribute(curr, classicattr) + head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, c, old, curr.font, par) + end - elseif id == hlistid and has_attribute(curr, rubyattr) then - local cc, fi = ruby_char_font(curr) -- rubybase + elseif id == hlistid and curr.list then local old = has_attribute(curr, classicattr) - head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, old, fi, par) + if has_attribute(curr, rubyattr) then + local c, f = ruby_char_font(curr) -- rubybase + if c and f then + head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, c, old, f, par) + else + pc, pcl = false, 0 + end + else + local c, f = hbox_ini_char_font(curr) + if c and f then + head = maybe_linebreak(head, curr, pc, pcl, c, old, f, par) + end + pc = hbox_fin_char_font(curr) + pcl = pc and get_char_class(pc, old) or 0 + end elseif id == whatsitid and curr.mode == directmode then - local glyf, cc, fin = get_actualtext(curr) - if cc and fin and glyf then + local glyf, c, fin = get_actualtext(curr) + if c and fin and glyf then local old = has_attribute(glyf, classicattr) - head = maybe_linebreak(head, curr, pc, pcl, cc, old, glyf.font, par) + head = maybe_linebreak(head, curr, pc, pcl, c, old, glyf.font, par) pc, pcl, curr = fin, 0, goto_end_actualtext(curr) end @@ -712,34 +772,8 @@ local function is_cjk_char (c) or rawget(breakable_after, c) and c >= 0x2000 end -local function is_cjk (n, c) -- node, char - if n and c then - if is_unicode_var_sel(c) then - local p = getprev(n) - if p and p.id == glyphid then - local pc = my_node_props(p).unicode or p.char or 0 - return is_cjk_char(pc) - end - end - return is_cjk_char(c) - end -end - -local function is_noncjk (n, c) -- node, char - if n and c then - if is_unicode_var_sel(c) then - local p = getprev(n) - if p and p.id == glyphid then - local pc = my_node_props(p).unicode or p.char or 0 - return is_noncjk_char(pc) - end - end - return is_noncjk_char(c) - end -end - local function do_interhangul_option (head, curr, pc, c, fontid, par) - local cc = (is_hangul(c) or is_chosong(c)) and 1 or 0 + local cc = (is_hangul(c) or is_compat_jamo(c) or is_chosong(c)) and 1 or 0 if cc*pc == 1 and curr.lang ~= nohyphen then local dim = get_font_opt_dimen(fontid, "interhangul") @@ -757,17 +791,32 @@ local function process_interhangul (head, par) local id = curr.id if id == glyphid then local c = my_node_props(curr).unicode or curr.char - head, pc = do_interhangul_option(head, curr, pc, c, curr.font, par) + if c and not is_unicode_var_sel(c) then + head, pc = do_interhangul_option(head, curr, pc, c, curr.font, par) - if is_chosong(c) then - pc = 0 - elseif is_jungsong(c) or is_jongsong(c) or hangul_tonemark[c] then - pc = 1 + if is_chosong(c) then + pc = 0 + elseif is_jungsong(c) or is_jongsong(c) or hangul_tonemark[c] then + pc = 1 + end end - elseif id == hlistid and has_attribute(curr, rubyattr) then - local c, fi = ruby_char_font(curr) - head, pc = do_interhangul_option(head, curr, pc, c, fi, par) + elseif id == hlistid and curr.list then + if has_attribute(curr, rubyattr) then + local c, f = ruby_char_font(curr) + if c and f then + head, pc = do_interhangul_option(head, curr, pc, c, f, par) + else + pc = 0 + end + else + local c, f = hbox_ini_char_font(curr) + if c and f then + head = do_interhangul_option(head, curr, pc, c, f, par) + end + c = hbox_fin_char_font(curr) + pc = c and is_hangul_jamo(c) and 1 or 0 + end elseif id == whatsitid and curr.mode == directmode then local glyf, c = get_actualtext(curr) @@ -787,21 +836,21 @@ local function process_interhangul (head, par) end local function do_interlatincjk_option (head, curr, pc, pf, pcl, c, cf, par) - local cc = is_cjk(curr, c) and 1 or is_noncjk(curr, c) and 2 or 0 + local cc = is_cjk_char(c) and 1 or is_noncjk_char(c) and 2 or 0 local old = has_attribute(curr, classicattr) local ccl = get_char_class(c, old) if cc*pc == 2 and curr.lang ~= nohyphen then local brb = cc == 2 or breakable_before[c] -- numletter != br_before if brb then - local fid = cc == 1 and cf or pf - local dim = get_font_opt_dimen(fid, "interlatincjk") + local f = cc == 1 and cf or pf + local dim = get_font_opt_dimen(f, "interlatincjk") if dim then local ict = old and intercharclass[pcl][ccl] -- under classic env. only if ict then - dim = get_font_opt_dimen(fid, "intercharacter") or 0 + dim = get_font_opt_dimen(f, "intercharacter") or 0 end - head = insert_glue_before(head, curr, par, true, brb, old, ict, dim, fid) + head = insert_glue_before(head, curr, par, true, brb, old, ict, dim, f) end end end @@ -815,12 +864,33 @@ local function process_interlatincjk (head, par) local id = curr.id if id == glyphid then local c = my_node_props(curr).unicode or curr.char - head, pc, pf, pcl = do_interlatincjk_option(head, curr, pc, pf, pcl, c, curr.font, par) - pc = breakable_after[c] and pc or 0 + if c and not is_unicode_var_sel(c) then + head, pc, pf, pcl = do_interlatincjk_option(head, curr, pc, pf, pcl, c, curr.font, par) + pc = breakable_after[c] and pc or 0 + end - elseif id == hlistid and has_attribute(curr, rubyattr) then - local c, cf = ruby_char_font(curr) - head, pc, pf, pcl = do_interlatincjk_option(head, curr, pc, pf, pcl, c, cf, par) + elseif id == hlistid and curr.list then + if has_attribute(curr, rubyattr) then + local c, f = ruby_char_font(curr) + if c and f then + head, pc, pf, pcl = do_interlatincjk_option(head, curr, pc, pf, pcl, c, f, par) + else + pc, pf, pcl = 0, 0, 0 + end + else + local c, f = hbox_ini_char_font(curr) + if c and f then + head = do_interlatincjk_option(head, curr, pc, pf, pcl, c, f, par) + end + c, f = hbox_fin_char_font(curr) + if c and breakable_after[c] then + pc = is_cjk_char(c) and 1 or is_noncjk_char(c) and 2 or 0 + else + pc = 0 + end + pcl = c and get_char_class(c, has_attribute(curr, classicattr)) or 0 + pf = f or 0 + end elseif id == whatsitid and curr.mode == directmode then local glyf, c = get_actualtext(curr) @@ -833,16 +903,17 @@ local function process_interlatincjk (head, par) if pc == 1 then head = do_interlatincjk_option(head, curr, pc, pf, pcl, 0x30, pf, par) end - pc, pcl, curr = 2, 0, end_of_math(curr) + pc, pf, pcl = 2, 0, 0 + curr = end_of_math(curr) elseif id == dirid then if pc == 1 and curr.dir:sub(1,1) == "+" then head = do_interlatincjk_option(head, curr, pc, pf, pcl, 0x30, pf, par) - pc, pcl = 0, 0 + pc, pf, pcl = 0, 0, 0 end elseif is_blocking_node(curr) then - pc, pcl = 0 + pc, pf, pcl = 0, 0, 0 end curr = getnext(curr) end @@ -861,18 +932,28 @@ local function process_remove_spaces (head) for k, v in pairs{ p = getprev(curr), n = getnext(curr) } do local ok while v do - local vid = v.id - if vid ~= whatsitid -- skip whatsit or kern except userkern - and ( vid ~= kernid or v.subtype == userkern ) then + local id = v.id + if id ~= whatsitid -- skip whatsit or kern except userkern + and ( id ~= kernid or v.subtype == userkern ) then local vchar, vfont - if vid == glyphid and v.lang ~= nohyphen then - vchar, vfont = v.char, v.font - elseif vid == hlistid and has_attribute(v, rubyattr) then - vchar, vfont = ruby_char_font(v) + if id == glyphid and v.lang ~= nohyphen then + local c = my_node_props(v).unicode or v.char or 0 + if is_unicode_var_sel(c) then + v = getprev(v) or v + end + vchar, vfont = my_node_props(v).unicode or v.char, v.font + elseif id == hlistid and v.list then + if has_attribute(v, rubyattr) then + vchar, vfont = ruby_char_font(v) + elseif k == "p" then + vchar, vfont = hbox_fin_char_font(v) + else + vchar, vfont = hbox_ini_char_font(v) + end end if vchar and vfont and option_in_font(vfont, opt_name) then - ok = is_cjk(v, vchar) + ok = is_cjk_char(vchar) end break @@ -1037,7 +1118,11 @@ local function process_dotemph (head, tofree) local dotattr = has_attribute(curr, dotemphattr) if dotattr then local c = my_node_props(curr).unicode or curr.char - if is_hangul(c) or is_hanja(c) or is_chosong(c) or is_kana(c) then + if is_hangul(c) or + is_compat_jamo(c) or + is_chosong(c) or + is_hanja(c) or + is_kana(c) then local currwd = curr.width if currwd >= get_en_size(curr.font) then local box = nodecopy(dotemphbox[dotattr]) @@ -1178,7 +1263,7 @@ local function getrubystretchfactor (box) local str = get_font_opt_dimen(fid, "intercharstretch") if str then local em = get_en_size(fid) * 2 - texsprint(stringformat("\\def\\luatexkostretchfactor{%.4f}", str/em/2)) + set_macro("luatexkostretchfactor", stringformat("%.4f", str/em/2)) end end luatexko.getrubystretchfactor = getrubystretchfactor @@ -1517,10 +1602,12 @@ local function process_vertical_font (fontdata) local scale = parameters.factor or 655.36 local quad = parameters.quad or 655360 local ascender = parameters.ascender or quad*0.8 - local goffset = fontdata_opt_dim(fontdata, "charraise") - if not goffset then - goffset = (parameters.x_height or quad/2) / 2 - end + + local goffset = fontdata_opt_dim(fontdata, "charraise") or + (parameters.x_height or quad/2)/2 + -- declare shift amount of horizontal box inside vertical env. + fontdata.horizboxmoveleftamount = quad/2-goffset + for i,v in pairs(fontdata.characters) do local voff = goffset - (v.width or 0)/2 local bbox = descriptions[i] and descriptions[i].boundingbox or {0,0,0,0} @@ -1585,6 +1672,22 @@ local function process_vertical_font (fontdata) end end +local function get_horizbox_moveleft () + for _, v in ipairs{ fontcurrent(), + texattribute.luatexkohangulfontattr, + texattribute.luatexkohanjafontattr, + texattribute.luatexkofallbackfontattr } do + if v and v > 0 then + local amount = get_font_data(v).horizboxmoveleftamount + if amount then + set_macro("luatexkohorizboxmoveleft", texsp(amount).."sp") + break + end + end + end +end +luatexko.gethorizboxmoveleft = get_horizbox_moveleft + -- charraise local function process_charriase_font (fontdata) @@ -1807,11 +1910,17 @@ function(head) local curr = head while curr do local id = curr.id - if id == glyphid then - if curr.subtype == 1 and - curr.lang ~= nohyphen and - is_cjk(curr, curr.char) then - curr.lang = langkor + if id == glyphid and curr.subtype == 1 and curr.lang ~= nohyphen then + local c = curr.char + if c then + if is_unicode_var_sel(c) then + local p = getprev(curr) + if p.id == glyphid then + curr.lang = p.lang + end + elseif is_cjk_char(c) then + curr.lang = langkor + end end elseif id == mathid then curr = end_of_math(curr) @@ -1858,25 +1967,3 @@ local function current_has_hangul_chars (cnt) end luatexko.currenthashangulchars = current_has_hangul_chars -local function get_gid_of_charslot (fd, slot) - if type(fd) == "number" then - fd = get_font_data(fd) - end - local character = fd.characters[slot] - return character and character.index -end -luatexko.get_gid_of_charslot = get_gid_of_charslot - -local function get_charslots_of_gid (fd, gid) - if type(fd) == "number" then - fd = get_font_data(fd) - end - local t = {} - for i, v in pairs(fd.characters) do - if v.index == gid then - t[#t + 1] = i - end - end - return t -end -luatexko.get_charslots_of_gid = get_charslots_of_gid diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty index dbe1be8411a..7599a0977b7 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty @@ -13,7 +13,7 @@ \ifdefined\luatexkohangulfontattr \endinput\fi \ifdefined\selectfont - \ProvidesPackage{luatexko}[2019/06/21 v2.3 typesetting Korean with LuaTeX] + \ProvidesPackage{luatexko}[2019/08/01 v2.4 typesetting Korean with LuaTeX] \RequirePackage{luatexbase} \RequirePackage{fontspec} \else @@ -257,7 +257,9 @@ \pdfliteral{q 0 -1 1 0 0 0 cm}\box#1\pdfliteral{Q}% \vfil }}} % horizontal box inside vertical writing +\def\luatexkohorizboxmoveleft{0.5ex} \protected\def\horizontal#1{% + \directlua{ luatexko.gethorizboxmoveleft() }% \leavevmode \setbox\z@\vbox\bgroup \hsize#1\relax @@ -265,7 +267,7 @@ \protected\def\endhorizontal{% \egroup \luatexkounrotatebox\z@ - \box\z@ } + \lower\luatexkohorizboxmoveleft\box\z@ } \protected\def\luatexkounrotatebox#1{% \setbox#1\hbox to\dimexpr\ht#1+\dp#1{% \vbox to\wd#1{% -- cgit v1.2.3