summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luatexko/luatexko.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luatexko/luatexko.lua347
1 files changed, 217 insertions, 130 deletions
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