diff options
author | Karl Berry <karl@freefriends.org> | 2019-05-26 21:24:59 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-05-26 21:24:59 +0000 |
commit | 2014750e7bcf55bab5c430e3d98d8a11430eb979 (patch) | |
tree | bef9a778b3b51cea29fefadfbbf930a261791875 /Master/texmf-dist/tex/luatex/luatexko/luatexko.lua | |
parent | 5a993557f8f849481525f4d473d6c9f1da51981d (diff) |
luatexko (26may19)
git-svn-id: svn://tug.org/texlive/trunk@51228 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luatexko/luatexko.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luatexko/luatexko.lua | 268 |
1 files changed, 152 insertions, 116 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua index 01a274bfeda..87478153ada 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/05/01', - version = '2.0', + date = '2019/05/25', + version = '2.1', description = 'typesetting Korean with LuaTeX', author = 'Dohyun Kim, Soojin Nam', license = 'LPPL v1.3+', @@ -61,6 +61,7 @@ local stringformat = string.format local tableconcat = table.concat local tableinsert = table.insert +local tableunpack = table.unpack local add_to_callback = luatexbase.add_to_callback local attributes = luatexbase.attributes @@ -95,7 +96,6 @@ local italcorr = 3 local lua_number = 100 local lua_value = 108 local spaceskip = 13 -local xleaders = 102 local nohyphen = registernumber"l@nohyphenation" or -1 -- verbatim local hangulfontattr = attributes.luatexkohangulfontattr @@ -110,69 +110,69 @@ local vert_classic = 1 local SC_classic = 2 local function is_hanja (c) - return (c >= 0x3400 and c <= 0xA4C6) - or (c >= 0xF900 and c <= 0xFAD9) - or (c >= 0x20000 and c <= 0x2FFFD) - or (c >= 0x2E81 and c <= 0x2FD5) + return c >= 0x3400 and c <= 0xA4C6 + or c >= 0xF900 and c <= 0xFAD9 + or c >= 0x20000 and c <= 0x2FFFD + or c >= 0x2E81 and c <= 0x2FD5 end local function is_hangul (c) - return (c >= 0xAC00 and c <= 0xD7A3) + return c >= 0xAC00 and c <= 0xD7A3 end local function is_chosong (c) - return (c >= 0x1100 and c <= 0x115F) - or (c >= 0xA960 and c <= 0xA97C) + return c >= 0x1100 and c <= 0x115F + or c >= 0xA960 and c <= 0xA97C end local function is_jungsong (c) - return (c >= 0x1160 and c <= 0x11A7) - or (c >= 0xD7B0 and c <= 0xD7C6) + return c >= 0x1160 and c <= 0x11A7 + or c >= 0xD7B0 and c <= 0xD7C6 end local function is_jongsong (c) - return (c >= 0x11A8 and c <= 0x11FF) - or (c >= 0xD7CB and c <= 0xD7FB) + return c >= 0x11A8 and c <= 0x11FF + or c >= 0xD7CB and c <= 0xD7FB end local hangul_tonemark = { [0x302E] = true, [0x302F] = true, } -local function is_unicode_vs (c) - return (c >= 0xFE00 and c <= 0xFE0F) - or (c >= 0xE0100 and c <= 0xE01EF) +local function is_unicode_var_sel (c) + return c >= 0xFE00 and c <= 0xFE0F + or c >= 0xE0100 and c <= 0xE01EF end local function is_cjk_combining (c) - return (c >= 0x302A and c <= 0x302F) - or (c >= 0x3099 and c <= 0x309C) - or (c >= 0xFF9E and c <= 0xFF9F) - or is_unicode_vs(c) + return c >= 0x302A and c <= 0x302F + or c >= 0x3099 and c <= 0x309C + or c >= 0xFF9E and c <= 0xFF9F + or is_unicode_var_sel(c) end local function is_noncjkletter (c) - return (c >= 0x30 and c <= 0x39) - or (c >= 0x41 and c <= 0x5A) - or (c >= 0x61 and c <= 0x7A) - or (c >= 0xC0 and c <= 0xD6) - or (c >= 0xD8 and c <= 0xF6) - or (c >= 0xF8 and c <= 0x10FC) - or (c >= 0x1200 and c <= 0x1FFE) - or (c >= 0xA4D0 and c <= 0xA877) - or (c >= 0xAB01 and c <= 0xABBF) - or (c >= 0xFB00 and c <= 0xFDFD) - or (c >= 0xFE70 and c <= 0xFEFC) + return c >= 0x30 and c <= 0x39 + or c >= 0x41 and c <= 0x5A + or c >= 0x61 and c <= 0x7A + or c >= 0xC0 and c <= 0xD6 + or c >= 0xD8 and c <= 0xF6 + or c >= 0xF8 and c <= 0x10FC + or c >= 0x1200 and c <= 0x1FFE + or c >= 0xA4D0 and c <= 0xA877 + or c >= 0xAB01 and c <= 0xABBF + or c >= 0xFB00 and c <= 0xFDFD + or c >= 0xFE70 and c <= 0xFEFC end local function is_kana (c) - return (c >= 0x3041 and c <= 0x3096) - or (c >= 0x30A1 and c <= 0x30FA) - or (c >= 0x31F0 and c <= 0x31FF) - or (c >= 0xFF66 and c <= 0xFF6F) - or (c >= 0xFF71 and c <= 0xFF9D) - or c == 0x309F or c == 0x30FF - or (c >= 0x1B000 and c <= 0x1B16F) + return c >= 0x3041 and c <= 0x3096 + or c >= 0x30A1 and c <= 0x30FA + or c >= 0x31F0 and c <= 0x31FF + or c >= 0xFF66 and c <= 0xFF6F + or c >= 0xFF71 and c <= 0xFF9D + or c == 0x309F or c == 0x30FF + or c >= 0x1B000 and c <= 0x1B16F end local function is_hangul_jamo (c) @@ -180,7 +180,7 @@ local function is_hangul_jamo (c) or is_chosong(c) or is_jungsong(c) or is_jongsong(c) - or (c >= 0x3131 and c <= 0x318E) + or c >= 0x3131 and c <= 0x318E end local stretch_f, shrink_f = 5/100, 3/100 -- should be consistent for ruby @@ -189,14 +189,24 @@ local function get_font_data (fontid) return fontgetfont(fontid) or fontfonts[fontid] or {} end -local function get_en_size (f) - local pm +local function get_font_param (f, key) + local t if type(f) == "number" then - pm = getparameters(f) - elseif type(f) == "table" then - pm = f.parameters + t = getparameters(f) + if t and t[key] then + return t[key] + end + f = get_font_data(f) + end + if type(f) == "table" then + t = f.parameters + return t and t[key] end - return pm and pm.quad and pm.quad/2 or 327680 +end + +local function get_en_size (f) + local quad = get_font_param(f, "quad") + return quad and quad/2 or 327680 end local function char_in_font(fontdata, char) @@ -264,7 +274,7 @@ luatexko.updateforcehangul = update_force_hangul local active_processes = {} -local char_font_options ={ +local char_font_options = { interhangul = {}, interlatincjk = {}, intercharacter = {}, @@ -278,7 +288,8 @@ local function hangul_space_skip (curr, newfont) if n and n.id == glueid and n.subtype == spaceskip then local params = getparameters(curr.font) local oldwd, oldst, oldsh, oldsto, oldsho = getglue(n) - if oldwd == params.space + if params + and oldwd == params.space and oldst == params.space_stretch and oldsh == params.space_shrink and oldsto == 0 @@ -316,13 +327,12 @@ local function process_fonts (head) local c = curr.char - if is_unicode_vs(c) then + if is_unicode_var_sel(c) then local p = getprev(curr) if p.id == glyphid and curr.font ~= p.font then hangul_space_skip(curr, p.font) curr.font = p.font end - else local hf = has_attribute(curr, hangulfontattr) or false local hjf = has_attribute(curr, hanjafontattr) or false @@ -358,6 +368,10 @@ local function process_fonts (head) props.unicode = c end + elseif id == discid then + curr.pre = process_fonts(curr.pre) + curr.post = process_fonts(curr.post) + curr.replace = process_fonts(curr.replace) elseif id == mathid then curr = end_of_math(curr) elseif id == whatsitid @@ -450,7 +464,7 @@ local breakable_after = setmetatable({ [0xFE58] = true, [0xFE5A] = true, [0xFE5C] = true, [0xFE5E] = true, [0xFF1E] = true, [0xFF5E] = true, [0xFF70] = true, },{ __index = function (_,c) - return (is_hangul_jamo(c) and not is_chosong(c)) + return is_hangul_jamo(c) and not is_chosong(c) or is_noncjkletter(c) or is_hanja(c) or is_cjk_combining(c) @@ -480,7 +494,7 @@ 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)) + 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 @@ -499,7 +513,7 @@ local allowbreak_false_nodes = { local function is_blocking_node (curr) local id, subtype = curr.id, curr.subtype - return allowbreak_false_nodes[id] or (id == kernid and subtype == userkern) + return allowbreak_false_nodes[id] or id == kernid and subtype == userkern end local function ruby_char_font (rb) @@ -551,17 +565,13 @@ local function fontdata_opt_dim (fd, optname) end end -local function get_font_opt_dimen (fontid, option_name) - local fop_t = char_font_options[option_name] - local dim = fop_t and fop_t[fontid] +local function get_font_opt_dimen (fontid, optionname) + local t = char_font_options[optionname] + local dim = t and t[fontid] if dim == nil then local fd = get_font_data(fontid) - dim = fontdata_opt_dim(fd, option_name) - if dim then - fop_t[fontid] = dim -- cache - else - fop_t[fontid] = false - end + dim = fontdata_opt_dim(fd, optionname) + t[fontid] = dim or false -- cache end return dim end @@ -592,15 +602,15 @@ local function insert_glue_before (head, curr, par, br, brb, classic, ict, dim) return insert_before(head, curr, gl) end -local function maybe_linebreak (head, curr, pc, pcl, cc, gomun, fid, par) - local ccl = get_char_class(cc, gomun) +local function maybe_linebreak (head, curr, pc, pcl, cc, old, fid, par) + local ccl = get_char_class(cc, old) if pc and cc and curr.lang ~= nohyphen then local ict = intercharclass[pcl][ccl] local brb = breakable_before[cc] local br = brb and breakable_after[pc] local dim = get_font_opt_dimen(fid, "intercharacter") if ict or br or dim and (pcl >= 1 or ccl >= 1) then - head = insert_glue_before(head, curr, par, br, brb, gomun, ict, dim) + head = insert_glue_before(head, curr, par, br, brb, old, ict, dim) end end return head, cc, ccl @@ -612,20 +622,19 @@ local function process_linebreak (head, par) local id = curr.id if id == glyphid then local cc = my_node_props(curr).unicode or curr.char - local gomun = has_attribute(curr, classicattr) - - head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, gomun, curr.font, par) + local old = has_attribute(curr, classicattr) + head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, old, curr.font, par) elseif id == hlistid and has_attribute(curr, rubyattr) then local cc, fi = ruby_char_font(curr) -- rubybase - local gomun = has_attribute(curr, classicattr) - head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, gomun, fi, par) + local old = has_attribute(curr, classicattr) + head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, cc, old, fi, par) elseif id == whatsitid and curr.mode == directmode then local glyf, cc, fin = get_actualtext(curr) if cc and fin and glyf then - local gomun = has_attribute(glyf, classicattr) - head = maybe_linebreak(head, curr, pc, pcl, cc, gomun, glyf.font, par) + local old = has_attribute(glyf, classicattr) + head = maybe_linebreak(head, curr, pc, pcl, cc, old, glyf.font, par) pc, pcl, curr = fin, 0, goto_end_actualtext(curr) end @@ -652,17 +661,12 @@ local function process_glyph_width (head) and option_in_font(curr.font, "compresspunctuations") then local cc = my_node_props(curr).unicode or curr.char - local gomun = has_attribute(curr, classicattr) - local class = get_char_class(cc, gomun) - if (gomun or cc < 0x2000 or cc > 0x202F) -- exclude general puncts - and class >= 1 and class <= 4 then - - local gpos - if class ~= 1 then - gpos = getnext(curr) - else - gpos = getprev(curr) - end + local old = has_attribute(curr, classicattr) + local class = get_char_class(cc, old) + if class >= 1 and class <= 4 and + (old or cc < 0x2000 or cc > 0x202F) then -- exclude general puncts + + local gpos = class == 1 and getprev(curr) or getnext(curr) gpos = gpos and gpos.id == kernid and gpos.subtype == fontkern if not gpos then @@ -699,8 +703,8 @@ local function is_cjk (c) or is_cjk_combining(c) or is_kana(c) or charclass[c] >= 1 - or (rawget(breakable_before, c) and c >= 0x2000) - or (rawget(breakable_after, c) and c >= 0x2000) + or rawget(breakable_before, c) and c >= 0x2000 + or rawget(breakable_after, c) and c >= 0x2000 end local function do_interhangul_option (head, curr, pc, c, fontid, par) @@ -752,7 +756,7 @@ local function process_interhangul (head, par) end local function do_interlatincjk_option (head, curr, pc, pf, c, cf, par) - local cc = (is_cjk(c) and 1) or (is_noncjkletter(c) and 2) or 0 + local cc = is_cjk(c) and 1 or is_noncjkletter(c) and 2 or 0 local brb = cc == 2 or breakable_before[c] -- numletter != br_before if brb and cc*pc == 2 and curr.lang ~= nohyphen then @@ -899,19 +903,19 @@ local josa_code = setmetatable({ return c ~= 0x1160 and 2 elseif is_jongsong(c) then return c == 0x11AF and 1 or 3 - elseif (is_noncjkletter(c) and c <= 0x7A ) - or (c >= 0x2160 and c <= 0x217F) -- roman - or (c >= 0x2460 and c <= 0x24E9) -- ① - or (c >= 0x314F and c <= 0x3163) or (c >= 0x3187 and c <= 0x318E) -- ㅏ - or (c >= 0x320E and c <= 0x321E) -- ㈎ - or (c >= 0x326E and c <= 0x327F) -- ㉮ - or (c >= 0xFF10 and c <= 0xFF19) -- 0 - or (c >= 0xFF21 and c <= 0xFF3A) -- A - or (c >= 0xFF41 and c <= 0xFF5A) -- a + elseif is_noncjkletter(c) and c <= 0x7A + or c >= 0x2160 and c <= 0x217F -- roman + or c >= 0x2460 and c <= 0x24E9 -- ① + or c >= 0x314F and c <= 0x3163 or c >= 0x3187 and c <= 0x318E -- ㅏ + or c >= 0x320E and c <= 0x321E -- ㈎ + or c >= 0x326E and c <= 0x327F -- ㉮ + or c >= 0xFF10 and c <= 0xFF19 -- 0 + or c >= 0xFF21 and c <= 0xFF3A -- A + or c >= 0xFF41 and c <= 0xFF5A -- a then return 2 - elseif (c >= 0x3131 and c <= 0x314E) or (c >= 0x3165 and c <= 0x3186) -- ㄱ - or (c >= 0x3200 and c <= 0x320D) -- ㈀ - or (c >= 0x3260 and c <= 0x326D) -- ㉠ + elseif c >= 0x3131 and c <= 0x314E or c >= 0x3165 and c <= 0x3186 -- ㄱ + or c >= 0x3200 and c <= 0x320D -- ㈀ + or c >= 0x3260 and c <= 0x326D -- ㉠ then return 3 end end }) @@ -1031,11 +1035,11 @@ end local uline_f, uline_id = new_user_whatsit("uline","luatexko") local no_uline_id = new_user_whatsit_id("no_uline","luatexko") -local function ulboundary (i, n) +local function ulboundary (i, n, subtype) local what = uline_f() if n then what.type = lua_value -- table - what.value = { i, nodecopy(n) } + what.value = { i, nodecopy(n), subtype } else what.type = lua_number what.value = i @@ -1061,17 +1065,19 @@ function skip_white_nodes (n, ltr) end local function draw_uline (head, curr, parent, t, final) - local start, list = t.start or head, t.list + local start, list, subtype = t.start or head, t.list, t.subtype start = skip_white_nodes(start, true) - nodeslide(start) -- to get correct getprev. + if final then + nodeslide(start) -- to get correct getprev. + end curr = skip_white_nodes(curr) - if getnext(curr) then curr = getnext(curr) end + curr = getnext(curr) or curr local len = parent and rangedimensions(parent, start, curr) or dimensions(start, curr) -- it works?! if len and len ~= 0 then local g = nodenew(glueid) setglue(g, len) - g.subtype = xleaders + g.subtype = subtype g.leader = final and list or nodecopy(list) local k = nodenew(kernid) k.kern = -len @@ -1081,8 +1087,8 @@ local function draw_uline (head, curr, parent, t, final) return head end -local function process_uline (head, parent, ulitems, level) - local curr, ulitems, level = head, ulitems or {}, level or 0 +local function process_uline (head, parent, items, level) + local curr, items, level = head, items or {}, level or 0 while curr do local id = curr.id if id == whatsitid @@ -1091,31 +1097,36 @@ local function process_uline (head, parent, ulitems, level) local value = curr.value if curr.type == lua_value then - local count, list = value[1], value[2] - ulitems[count] = { start = curr, list = list, level = level } - elseif ulitems[value] then - head = draw_uline(head, curr, parent, ulitems[value], true) - ulitems[value] = nil + local count, list, subtype = tableunpack(value) + items[count] = { + start = curr, + list = list, + subtype = subtype, + level = level, + } + elseif items[value] then + head = draw_uline(head, curr, parent, items[value], true) + items[value] = nil end curr.user_id = no_uline_id -- avoid multiple run elseif id == hlistid then local list = curr.list if list then - curr.list, ulitems = process_uline(list, curr, ulitems, level+1) + curr.list, items = process_uline(list, curr, items, level+1) end end curr = getnext(curr) end curr = nodeslide(head) - for i, t in pairs(ulitems) do + for i, t in pairs(items) do if level == t.level then head = draw_uline(head, curr, parent, t) t.start = nil end end - return head, ulitems + return head, items end -- ruby @@ -1171,7 +1182,9 @@ local function process_ruby_post_linebreak (head) ruby.list = insert_before(list, list, k) end ruby.width = 0 - ruby.shift = -(curr.height + ruby_t[2]) -- rubysep + local _, f = ruby_char_font(curr) + local ascender = get_font_param(f, "ascender") or curr.height + ruby.shift = -ascender - ruby.depth - ruby_t[2] -- rubysep head = insert_before(head, curr, ruby) end ruby_t = nil @@ -1740,9 +1753,32 @@ local function activate (name) end luatexko.activate = activate --- default hangul font +-- aux functions local function current_has_hangul_chars (cnt) texcount[cnt] = char_in_font(fontcurrent(), 0xAC00) and 1 or 0 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 + table.insert(t, i) + end + end + return t +end +luatexko.get_charslots_of_gid = get_charslots_of_gid |