diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luatexko/luatexko.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luatexko/luatexko.lua | 488 |
1 files changed, 230 insertions, 258 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua index 0888aec134a..48d70f5e809 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua @@ -1,6 +1,6 @@ -- luatexko.lua -- --- Copyright (c) 2013-2016 Dohyun Kim <nomos at ktug org> +-- Copyright (c) 2013-2017 Dohyun Kim <nomos at ktug org> -- Soojin Nam <jsunam at gmail com> -- -- This work may be distributed and/or modified under the @@ -13,8 +13,8 @@ luatexbase.provides_module { name = 'luatexko', - date = '2016/05/14', - version = '1.15', + date = '2017/02/06', + version = '1.16', description = 'Korean linebreaking and font-switching', author = 'Dohyun Kim, Soojin Nam', license = 'LPPL v1.3+', @@ -129,135 +129,112 @@ local emsize = 655360 local cjkclass = { [0x2018] = 1, -- ‘ [0x201C] = 1, -- “ - [0xFF08] = 1, -- ( - [0xFE35] = 1, -- ( vert - [0x3014] = 1, -- 〔 - [0xFE39] = 1, -- 〔 vert - [0xFF3B] = 1, -- [ - [0xFE47] = 1, -- [ vert - [0xFF5B] = 1, -- { - [0xFE37] = 1, -- { vert + [0x2329] = 1, -- 〈 [0x3008] = 1, -- 〈 - [0xFE3F] = 1, -- 〈 vert [0x300A] = 1, -- 《 - [0xFE3D] = 1, -- 《 vert [0x300C] = 1, -- 「 - [0xFE41] = 1, -- 「 vert [0x300E] = 1, -- 『 - [0xFE43] = 1, -- 『 vert [0x3010] = 1, -- 【 - [0xFE3B] = 1, -- 【 vert - [0x3001] = 2, -- 、 - [0xFE11] = 2, -- 、 vert - [0xFF0C] = 2, -- , - [0xFE10] = 2, -- , vert + [0x3014] = 1, -- 〔 + [0x3016] = 1, -- 〖 + [0x3018] = 1, -- 〘 + [0x301A] = 1, -- 〚 + [0x301D] = 1, -- 〝 + [0xFE17] = 1, -- ︗ + [0xFE35] = 1, -- ︵ + [0xFE37] = 1, -- ︷ + [0xFE39] = 1, -- ︹ + [0xFE3B] = 1, -- ︻ + [0xFE3D] = 1, -- ︽ + [0xFE3F] = 1, -- ︿ + [0xFE41] = 1, -- ﹁ + [0xFE43] = 1, -- ﹃ + [0xFE47] = 1, -- ﹇ + [0xFF08] = 1, -- ( + [0xFF3B] = 1, -- [ + [0xFF5B] = 1, -- { + [0xFF5F] = 1, -- ⦅ + [0xFF62] = 1, -- 「 half [0x2019] = 2, -- ’ [0x201D] = 2, -- ” - [0xFF09] = 2, -- ) - [0xFE36] = 2, -- ) vert - [0x3015] = 2, -- 〕 - [0xFE3A] = 2, -- 〕 vert - [0xFF3D] = 2, -- ] - [0xFE48] = 2, -- ] vert - [0xFF5D] = 2, -- } - [0xFE38] = 2, -- } vert + [0x232A] = 2, -- 〉 + [0x3001] = 2, -- 、 [0x3009] = 2, -- 〉 - [0xFE40] = 2, -- 〉 vert [0x300B] = 2, -- 》 - [0xFE3E] = 2, -- 》 vert [0x300D] = 2, -- 」 - [0xFE42] = 2, -- 」 vert [0x300F] = 2, -- 』 - [0xFE44] = 2, -- 』 vert [0x3011] = 2, -- 】 - [0xFE3C] = 2, -- 】 vert + [0x3015] = 2, -- 〕 + [0x3017] = 2, -- 〗 + [0x3019] = 2, -- 〙 + [0x301B] = 2, -- 〛 + [0x301E] = 2, -- 〞 + [0x301F] = 2, -- 〟 + [0xFE10] = 2, -- ︐ + [0xFE11] = 2, -- ︑ + [0xFE18] = 2, -- ︘ + [0xFE36] = 2, -- ︶ + [0xFE38] = 2, -- ︸ + [0xFE3A] = 2, -- ︺ + [0xFE3C] = 2, -- ︼ + [0xFE3E] = 2, -- ︾ + [0xFE40] = 2, -- ﹀ + [0xFE42] = 2, -- ﹂ + [0xFE44] = 2, -- ﹄ + [0xFE48] = 2, -- ﹈ + [0xFF09] = 2, -- ) + [0xFF0C] = 2, -- , + [0xFF3D] = 2, -- ] + [0xFF5D] = 2, -- } + [0xFF60] = 2, -- ⦆ + [0xFF63] = 2, -- 」 half + [0xFF64] = 2, -- 、 half [0x00B7] = 3, -- · [0x30FB] = 3, -- ・ [0xFF1A] = 3, -- : --- [0xFE13] = 3, -- : vert [0xFF1B] = 3, -- ; --- [0xFE14] = 3, -- ; vert + [0xFF65] = 3, -- ・ half [0x3002] = 4, -- 。 - [0xFE12] = 4, -- 。 vert + [0xFE12] = 4, -- ︒ [0xFF0E] = 4, -- . - [0x2015] = 5, -- ― - [0x2026] = 5, -- … - [0xFE19] = 5, -- … vert + [0xFF61] = 4, -- 。 half + [0x2015] = 5, -- ― [0x2025] = 5, -- ‥ - [0xFE30] = 5, -- ‥ vert - [0xFE31] = 5, -- ︱ vert - [0xFF1F] = 6, -- ? + [0x2026] = 5, -- … + [0xFE19] = 5, -- ︙ + [0xFE30] = 5, -- ︰ + [0xFE31] = 5, -- ︱ + [0xFE15] = 6, -- ︕ + [0xFE16] = 6, -- ︖ [0xFF01] = 6, -- ! - [0xFE16] = 6, -- ︖ vert - [0xFE15] = 6, -- ︕ vert + [0xFF1F] = 6, -- ? } -local inhibitxspcode = { +local inhibitxspcode = setmetatable({ [0x002D] = 0, -- - hyphen minus [0x003C] = 0, -- < [0x003E] = 1, -- > - [0x00B0] = 1, - [0x2015] = 0, - [0x2018] = 2, - [0x2019] = 1, - [0x201C] = 2, - [0x201D] = 1, - [0x2026] = 0, - [0xFE19] = 0, - [0x2032] = 1, - [0x2033] = 1, - [0x3001] = 1, - [0xFE11] = 1, - [0x3002] = 1, - [0xFE12] = 1, - [0x3008] = 2, - [0xFE3F] = 2, - [0x3009] = 1, - [0xFE40] = 1, - [0x300A] = 2, - [0xFE3D] = 2, - [0x300B] = 1, - [0xFE3E] = 1, - [0x300C] = 2, - [0xFE41] = 2, - [0x300D] = 1, - [0xFE42] = 1, - [0x300E] = 2, - [0xFE43] = 2, - [0x300F] = 1, - [0xFE44] = 1, - [0x3010] = 2, - [0xFE3B] = 2, - [0x3011] = 1, - [0xFE3C] = 1, + [0x00B0] = 1, -- ° + [0x2032] = 1, -- ′ + [0x2033] = 1, -- ″ [0x3012] = 2, -- 〒 - [0x3014] = 2, - [0xFE39] = 2, - [0x3015] = 1, - [0xFE3A] = 1, - [0x301C] = 0, - [0xFF08] = 2, - [0xFE35] = 2, - [0xFF09] = 1, - [0xFE36] = 1, - [0xFF0C] = 1, - [0xFE10] = 1, - [0xFF0E] = 1, - [0xFF1B] = 1, - [0xFE14] = 1, - [0xFF1F] = 1, - [0xFF3B] = 2, - [0xFE47] = 2, - [0xFF3D] = 1, - [0xFE48] = 1, - [0xFF5B] = 2, - [0xFE37] = 2, - [0xFF5D] = 1, - [0xFE38] = 1, - [0xFFE5] = 0, -} + [0x301C] = 0, -- 〜 + [0xFE14] = 1, -- ︔ + [0xFF1B] = 1, -- ; + [0xFFE5] = 0, -- ¥ +},{ + __index = function (_,c) + if cjkclass[c] == 1 then + return 2 + elseif cjkclass[c] == 2 or cjkclass[c] == 4 or cjkclass[c] == 6 then + return 1 + elseif cjkclass[c] == 5 then + return 0 + end + end +}) -local postbreakpenalty = { +local postbreakpenalty = setmetatable({ [0x0023] = 500, [0x0024] = 500, [0x0025] = 500, @@ -266,37 +243,24 @@ local postbreakpenalty = { [0x003C] = 10000, -- < [0x005B] = 10000, [0x0060] = 10000, + [0x007B] = 10000, -- { + [0x00AB] = 10000, -- « [0x2013] = 50, -- en-dash [0x2014] = 50, -- em-dash - [0x2018] = 10000, - [0x201C] = 10000, - [0x3008] = 10000, - [0xFE3F] = 10000, - [0x300A] = 10000, - [0xFE3D] = 10000, - [0x300C] = 10000, - [0xFE41] = 10000, - [0x300E] = 10000, - [0xFE43] = 10000, - [0x3010] = 10000, - [0xFE3B] = 10000, - [0x3014] = 10000, - [0xFE39] = 10000, [0xFF03] = 200, [0xFF04] = 200, [0xFF05] = 200, [0xFF06] = 200, - [0xFF08] = 10000, - [0xFE35] = 10000, - [0xFF3B] = 10000, - [0xFE47] = 10000, - [0xFF40] = 10000, - [0xFF5B] = 10000, - [0xFE37] = 10000, - [0xFF62] = 10000, -- 「 -} + [0xFF40] = 10000, -- ` +},{ + __index = function (_,c) + if cjkclass[c] == 1 then + return 10000 + end + end +}) -local prebreakpenalty = { +local prebreakpenalty = setmetatable({ [0x0021] = 10000, [0x0022] = 10000, [0x0027] = 10000, @@ -312,35 +276,18 @@ local prebreakpenalty = { [0x003E] = 10000, -- > [0x003F] = 10000, [0x005D] = 10000, - [0x00B4] = 10000, - [0x00B7] = 10000, -- · + [0x007D] = 10000, -- } + [0x00B4] = 10000, -- ´ + [0x00BB] = 10000, -- » [0x2013] = 10000, -- – [0x2014] = 10000, -- — - [0x2015] = 10000, - [0x2019] = 10000, - [0x201D] = 10000, [0x2025] = 5000, -- 250, -- ‥ - [0xFE30] = 5000, -- 250, -- ︰ [0x2026] = 5000, -- 250, -- … - [0xFE19] = 5000, -- 250, -- ︙ [0x2212] = 5000, -- 200, -- − minus sign - [0x3001] = 10000, - [0xFE11] = 10000, - [0x3002] = 10000, - [0xFE12] = 10000, - [0x3005] = 10000, - [0x3009] = 10000, - [0xFE40] = 10000, - [0x300B] = 10000, - [0xFE3E] = 10000, - [0x300D] = 10000, - [0xFE42] = 10000, - [0x300F] = 10000, - [0xFE44] = 10000, - [0x3011] = 10000, - [0xFE3C] = 10000, - [0x3015] = 10000, - [0xFE3A] = 10000, + [0x3005] = 10000, -- 々 + [0x301C] = 10000, -- 〜 + [0x3035] = 10000, -- 〵 + [0x303B] = 10000, -- 〻 [0x3041] = 150, [0x3043] = 150, [0x3045] = 150, @@ -351,8 +298,13 @@ local prebreakpenalty = { [0x3085] = 150, [0x3087] = 150, [0x308E] = 150, - [0x309B] = 10000, - [0x309C] = 10000, + [0x3095] = 150, + [0x3096] = 150, + [0x309B] = 10000, -- ゛ + [0x309C] = 10000, -- ゜ + [0x309D] = 10000, -- ゝ + [0x309E] = 10000, -- ゞ + [0x30A0] = 10000, -- ゠ [0x30A1] = 150, [0x30A3] = 150, [0x30A5] = 150, @@ -365,27 +317,25 @@ local prebreakpenalty = { [0x30EE] = 150, [0x30F5] = 150, [0x30F6] = 150, - [0x30FB] = 10000, - [0x30FC] = 10000, - [0xFF01] = 10000, - [0xFF09] = 10000, - [0xFE36] = 10000, + [0x30FC] = 10000, -- ー + [0x30FD] = 10000, -- ヽ + [0x30FE] = 10000, -- ヾ + [0xFE13] = 10000, -- ︓ + [0xFE14] = 10000, -- ︔ + [0xFE19] = 5000, -- 250, -- ︙ + [0xFE30] = 5000, -- 250, -- ︰ + [0xFE32] = 10000, -- ︲ [0xFF0B] = 5000, -- 200, -- + - [0xFF0C] = 10000, - [0xFE10] = 10000, - [0xFF0E] = 10000, - [0xFF1A] = 10000, - [0xFE13] = 10000, - [0xFF1B] = 10000, - [0xFE14] = 10000, [0xFF1D] = 5000, -- 200, -- = - [0xFF1F] = 10000, - [0xFF3D] = 10000, - [0xFE48] = 10000, - [0xFF5D] = 10000, - [0xFE38] = 10000, - [0xFF63] = 10000, -- 」 -} + [0xFF9E] = 10000, -- ゙ + [0xFF9F] = 10000, -- ゚ +},{ + __index = function (_,c) + if cjkclass[c] and cjkclass[c] > 1 then + return 10000 + end + end +}) local xspcode = { [0x0027] = 2, @@ -593,10 +543,14 @@ local function get_cjk_class (ch, cjtype) end end +local type1fonts = {} + local function get_font_table (fid) if fid then if fontdata[fid] then return fontdata[fid] + elseif type1fonts[fid] then + return type1fonts[fid] else return font.fonts[fid] end @@ -1479,11 +1433,37 @@ local function hangulspaceskip (engfont, hfontid, glue) esh = esh and tex_round(esh) if esp == gsp and est == gst and esh == gsh then else return end local hf = get_font_table(hfontid) - if hf and hf.encodingbytes == 2 then else return end +-- if hf and hf.encodingbytes == 2 then else return end return gsp, hf end -local type1fonts = {} -- due to too verbose log +local function virtual_unifont (prefix,size) + local data = { + name = prefix.."vf", + type = "virtual", + fonts = {}, + characters = {}, + } + local fonts = data.fonts + local chars = data.characters + for index = 0, 255 do + local name = string.format(prefix.."%02x", index) + if kpse_find_file(name,"tfm") then + local tfm = font.read_tfm(name, size) + data.parameters = data.parameters or tfm.parameters + fonts[#fonts+1] = { name=name, size=size } + local fid = #fonts + local zro = 256 * index + for i,v in pairs(tfm.characters) do + local slot = zro + i + chars[slot] = v + chars[slot].commands = { { "slot", fid, i } } + end + end + end + return data +end + local function nanumtype1font(curr) local currchar, currfont = d_getchar(curr), d_getfont(curr) if currchar > 0xFFFF then return end @@ -1500,38 +1480,21 @@ local function nanumtype1font(curr) series = fnt_t.name:find("^cmb") and "b" or "m" end local shape = fnt_t.parameters.slant > 0 and "o" or "" - local subfnt = stringformat("%s%s%s%02x",family,series,shape,currchar/256) + local prefix = stringformat("%s%s%s",family,series,shape) local fsize = fnt_t.size or 655360 - local fspec = stringformat("%s@%d",subfnt,fsize) - local newfnt = type1fonts[fspec] - if newfnt == false then return end - local newchr = currchar % 256 - local function ital_corr (curr,chr_t) - if shape ~= "o" then return end - local nxt = d_getnext(curr) - if nxt and d_getid(nxt) == kernnode and d_getsubtype(nxt) == kern_type_itlc and d_getfield(nxt,"kern") == 0 then - d_setfield(nxt,"kern", chr_t.italic or 0) - end - end - if newfnt then - local fntchr = get_font_char(newfnt,newchr) - if fntchr then - d_setfield(curr,"font", newfnt) - d_setchar(curr, newchr) - ital_corr(curr,fntchr) - end - elseif kpse_find_file(subfnt,"tfm") then - local ft, id = fonts.constructors.readanddefine(subfnt,fsize) - local fntchr = ft and ft.characters[newchr] - if id and fntchr then - type1fonts[fspec] = id - d_setfield(curr,"font", id) - d_setchar(curr, newchr) - ital_corr(curr,fntchr) + local fspec = stringformat("%s@%d",prefix,fsize) + local fontid = type1fonts[fspec] + if fontid == nil then -- bypass false + local fontdata = virtual_unifont(prefix, fsize) + fontid = fontdata and fontdefine(fontdata) + if fontid then + type1fonts[fspec] = fontid + type1fonts[fontid] = fontdata + else + type1fonts[fspec] = false end - else - type1fonts[fspec] = false end + return fontid end local function font_substitute(head) @@ -1569,58 +1532,60 @@ local function font_substitute(head) uni = uni and get_cjk_class(uni) if uni and uni < 7 then ftable = {hanja, hangul, fallback} end end + local fid for i = 1,3 do - local fid = ftable[i] + fid = ftable[i] myfontchar = fid and get_font_char(fid, currchar) - if myfontchar then - d_setfield(curr,"font",fid) - --- charraise option charraise - local charraise = get_font_feature(fid, "charraise") - if charraise then - charraise = tex_sp(charraise) - local curryoffset = d_getfield(curr,"yoffset") or 0 - d_setfield(curr,"yoffset", charraise + curryoffset) - end - --- - local nxt = d_getnext(curr) - local nxtid = nxt and d_getid(nxt) - if nxtid == glyphnode and is_unicode_vs(d_getchar(nxt)) then - nxt = d_getnext(nxt) - nxtid = nxt and d_getid(nxt) - end - if eng and nxtid then - local nxtsubtype = d_getsubtype(nxt) - -- adjust next glue by hangul font space - if nxtid == gluenode and nxtsubtype == glue_type_space and get_font_char(fid,32) then - local oldwd, ft = hangulspaceskip(eng, fid, nxt) - if oldwd and ft then - local newwd = ft.space_char_width - if not newwd then - local newsp = d_tonode(d_copy_node(curr)) - newsp.char = 32 - newsp = nodes.simple_font_handler(newsp) - newwd = newsp and newsp.width - ft.space_char_width = newwd - node.free(newsp) - end - if newwd and oldwd ~= newwd then - d_setglue(nxt, newwd, newwd/2, newwd/3) - end + if myfontchar then break end + end + if not myfontchar and not hangulpunctuations[currchar] then + fid = nanumtype1font(curr) + myfontchar = fid and get_font_char(fid, currchar) + end + if myfontchar then + d_setfield(curr,"font",fid) + --- charraise option charraise + local charraise = get_font_feature(fid, "charraise") + if charraise then + charraise = tex_sp(charraise) + local curryoffset = d_getfield(curr,"yoffset") or 0 + d_setfield(curr,"yoffset", charraise + curryoffset) + end + --- + local nxt = d_getnext(curr) + local nxtid = nxt and d_getid(nxt) + if nxtid == glyphnode and is_unicode_vs(d_getchar(nxt)) then + nxt = d_getnext(nxt) + nxtid = nxt and d_getid(nxt) + end + if eng and nxtid then + local nxtsubtype = d_getsubtype(nxt) + -- adjust next glue by hangul font space + if nxtid == gluenode and nxtsubtype == glue_type_space and get_font_char(fid,32) then + local oldwd, ft = hangulspaceskip(eng, fid, nxt) + if oldwd and ft then + local newwd = ft.space_char_width + if not newwd then + local newsp = d_tonode(d_copy_node(curr)) + newsp.char = 32 + newsp = nodes.simple_font_handler(newsp) + newwd = newsp and newsp.width + ft.space_char_width = newwd + node.free(newsp) end - -- adjust next italic correction kern - elseif nxtid == kernnode and nxtsubtype == kern_type_itlc and d_getfield(nxt,"kern") == 0 then - local ksl = get_font_table(fid).parameters.slant - if ksl and ksl > 0 then - d_setfield(nxt,"kern", myfontchar.italic or 0) + if newwd and oldwd ~= newwd then + d_setglue(nxt, newwd, newwd/2, newwd/3) end end + -- adjust next italic correction kern + elseif nxtid == kernnode and nxtsubtype == kern_type_itlc and d_getfield(nxt,"kern") == 0 then + local ksl = get_font_table(fid).parameters.slant + if ksl and ksl > 0 then + d_setfield(nxt,"kern", myfontchar.italic or 0) + end end - break end end - if not myfontchar then - nanumtype1font(curr) - end end end end @@ -1824,9 +1789,22 @@ local function uline_boundary (num, list) end luatexko.uline_boundary = uline_boundary +local skippable = { + [gluenode ] = true, + [penaltynode] = true, + [kernnode ] = true, + [whatsitnode] = true, +} local function draw_underline(head,curr,glueset,gluesign,glueorder,ubox,start) - if not start then - start = d_getid(head) == gluenode and d_getsubtype(head) < 100 and d_getnext(head) or head + start = start or head + while start do + if not skippable[d_getid(start)] then break end + start = d_getnext(start) + end + while curr do + local p = d_getprev(curr) + if not skippable[d_getid(p)] then break end + curr = p end local width = d_nodedimensions(glueset,gluesign,glueorder,start,curr) if width and width > 0 then @@ -2085,7 +2063,7 @@ local function cjk_vertical_font (vf) --- vertical gpos local res = vf.resources or {} if res.verticalgposhack then - return vf -- avoid multiple running + return -- avoid multiple running end local fea = shared.features or {} fea.kern = nil -- only for horizontal typesetting @@ -2120,7 +2098,6 @@ local function cjk_vertical_font (vf) end end res.verticalgposhack = true - return vf end local otffeatures = fonts.constructors.newfeatures("otf") @@ -2159,11 +2136,6 @@ otffeatures.register { -- italic correction for fake-slant font ------------------------------------ local function fakeslant_itlc (tfmdata) - --[[ should be removed - if tfmdata.format == "unknown" then - tfmdata.name = tfmdata.name:gsub("^\"(.-)\"$","%1") - end - --]] local slfactor = tfmdata.parameters.slantfactor if slfactor and slfactor > 0 then else return end tfmdata.parameters.slant = slfactor * 65536 |