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.lua162
1 files changed, 104 insertions, 58 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
index 1165d706bd7..b85cb734817 100644
--- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
+++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
@@ -10,17 +10,25 @@
-- and version 1.3c or later is part of all distributions of LaTeX
-- version 2006/05/20 or later.
-module('luatexko', package.seeall)
-
local err,warn,info,log = luatexbase.provides_module({
name = 'luatexko',
- date = '2013/05/19',
- version = '1.1',
+ date = '2013/07/03',
+ version = 1.2,
description = 'Korean linebreaking and font-switching',
author = 'Dohyun Kim',
license = 'LPPL v1.3+',
})
+luatexko = luatexko or {}
+local luatexko = luatexko
+
+local dotemphnode,rubynode,ulinebox = {},{},{}
+luatexko.dotemphnode = dotemphnode
+luatexko.rubynode = rubynode
+luatexko.ulinebox = ulinebox
+luatexko.hangulmain = luatexko.hangulmain or false
+luatexko.hanjafontforhanja = luatexko.hanjafontforhanja or false
+
local stringbyte = string.byte
local stringgsub = string.gsub
local stringchar = string.char
@@ -28,14 +36,14 @@ local stringfind = string.find
local stringmatch = string.match
local stringgmatch = string.gmatch
local stringformat = string.format
+local string_sub = string.sub
local mathfloor = math.floor
local tex_round = tex.round
local tex_sp = tex.sp
local fontdefine = font.define
+local utf8char = unicode.utf8.char
local fontdata = fonts.hashes.identifiers
-local font_define_func = callback.find("define_font")
-local utf8char = unicode.utf8.char
local remove_node = node.remove
local insert_before = node.insert_before
@@ -67,7 +75,6 @@ local add_to_callback = luatexbase.add_to_callback
local gluenode = node.id("glue")
local gluespecnode = node.id("glue_spec")
local glyphnode = node.id("glyph")
-local discnode = node.id("disc")
local mathnode = node.id("math")
local hlistnode = node.id("hlist")
local vlistnode = node.id("vlist")
@@ -85,11 +92,6 @@ local new_rule = node.new(rulenode)
local emsize = 655360
-dotemphnode = {}
-rubynode = {}
-ulinebox = {}
-hanjafontforhanja = false
-
local cjkclass = {
[0x2018] = 1, -- ‘
[0x201C] = 1, -- “
@@ -383,6 +385,7 @@ local latin_fullstop = {
local latin_quotes = {
[0x0028] = 0x0029, -- ( )
+ [0x003C] = 0x003E, -- < >
[0x2018] = 0x2019, -- ‘ ’
[0x201C] = 0x201D, -- “ ”
}
@@ -528,7 +531,7 @@ local function get_font_table (fid)
if fontdata[fid] then
return fontdata[fid]
else
- return font.getfont(fid)
+ return font.fonts[fid]
end
end
end
@@ -564,15 +567,20 @@ local function get_char_boundingbox(fid, chr)
end
local function get_unicode_char(curr)
- if curr.char > 0 and curr.char < 0xF0000 then return curr.char end
- local uni = has_attribute(curr, luakounicodeattr)
+ if (curr.char > 0 and curr.char < 0xE000) -- no pua
+ or (curr.char > 0xF8FF and curr.char < 0xF0000) then
+ return curr.char
+ end
+ -- tounicode is not reliable. backend bug
+ local uni = get_font_char(curr.font, curr.char)
+ uni = uni and uni.tounicode
+ uni = uni and string_sub(uni,1,4) -- seems ok for old hangul
+ if uni then return tonumber(uni,16) end
+ uni = has_attribute(curr, luakounicodeattr)
if uni then return uni end
return curr.char
end
-----------------------------
--- cjk linebreak and spacing
-----------------------------
local function get_hlist_class_first (hlist)
local curr = hlist.head
while curr do
@@ -606,6 +614,9 @@ local function get_hlist_class_last (hlist,prevchar,prevfont)
return prevchar, prevfont
end
+----------------------------
+-- cjk linebreak and spacing
+----------------------------
local function kanjiskip (head,curr)
insert_before(head,curr,make_luako_glue(0, emsize*0.1, emsize*0.02))
end
@@ -732,7 +743,7 @@ local function cjk_insert_nodes(head,curr,currchar,currfont,prevchar,prevfont)
local stretch = 0
local shrink = emsize * cjk_glue_spec[p][c][2]
insert_before(head,curr,make_luako_glue(width, stretch, shrink))
- elseif p < 10 and c < 10 and p ~= 8 and c ~= 9 then
+ elseif p < 10 and c < 9 then -- break between chosong and chosong
kanjiskip(head,curr)
elseif (p < 10 and c == 10) or (p == 10 and c < 10) then
if xspcode[currchar] then
@@ -780,20 +791,11 @@ local function cjk_insert_nodes(head,curr,currchar,currfont,prevchar,prevfont)
koreanlatinskip(head,curr,currfont,prevfont,was_penalty)
elseif p == 7 and c == 7 then
interhangulskip(head,curr,currfont,prevfont,was_penalty)
- elseif p < 10 and c < 10 and p ~= 8 and c ~= 9 then
+ elseif p < 10 and c < 9 then -- break between chosong and chosong
interhanjaskip(head,curr,was_penalty)
end
end
end
- -- for dot emphasis
- if has_attribute(curr,dotemphattr)
- and c ~= 0
- and c ~= 7
- and p ~= 8
- and c ~= 8 then
- unset_attribute(curr,dotemphattr)
- end
-
return currchar,currfont
end
@@ -1348,26 +1350,22 @@ local function hangulspaceskip (engfont, hfontid, nglue)
return tex_round(hsp), tex_round(hst), tex_round(hsh)
end
-local hangulfontlist = {}
-
local function font_substitute(head)
for curr in traverse_id(glyphnode, head) do
local eng = get_font_table(curr.font)
local engfontchar = get_font_char(curr.font, curr.char)
- if not eng then -- no font table of plain tex cm font
- engfontchar = get_cjk_class(curr.char) == 10
- end
if curr.char and not engfontchar then
local korid = false
local hangul = has_attribute(curr, hangfntattr)
local hanja = has_attribute(curr, hanjfntattr)
local ftable = {hangul, hanja}
- if hanjafontforhanja then
+ if luatexko.hanjafontforhanja then
local uni = get_unicode_char(curr)
uni = uni and get_cjk_class(uni)
if uni and uni < 7 then ftable = {hanja, hangul} end
end
- for _,fid in ipairs(ftable) do
+ for i=1,#ftable do
+ local fid = ftable[i]
if fid then
local c = get_font_char(fid, curr.char)
if c then
@@ -1375,7 +1373,9 @@ local function font_substitute(head)
curr.font = fid
-- adjust next glue by hangul font space
local nxt = curr.next
- if hangulmain and nxt and nxt.id == gluenode and nxt.subtype and nxt.subtype == 0 then
+ local hangulmain = eng and nxt and luatexko.hangulmain
+ hangulmain = hangulmain and get_font_char(fid, 32)
+ if hangulmain and nxt.id == gluenode and nxt.subtype and nxt.subtype == 0 then
local sp,st,sh = hangulspaceskip(eng, fid, nxt)
if sp and st and sh then
nxt.spec.width = sp
@@ -1414,7 +1414,7 @@ end
------------------------------------
--- vetical typesetting: EXPERIMENTAL -- don't use this
+-- vertical typesetting: EXPERIMENTAL -- don't use this
------------------------------------
---[[no vwidth in luaotfload v2
local tsbtable = {}
@@ -1523,10 +1523,12 @@ local function cjk_vertical_font (vf)
end
local function activate_vertical_virtual (tfmdata,value)
- if value then
+ local loaded = luatexbase.priority_in_callback("luaotfload.patch_font",
+ "luatexko.vertical_virtual_font")
+ if value and not loaded then
add_to_callback("luaotfload.patch_font",
cjk_vertical_font,
- "luatexko.vetical_virtual_font")
+ "luatexko.vertical_virtual_font")
end
end
@@ -1540,6 +1542,28 @@ otffeatures.register {
}
--no vwidth in luaotfload v2]]
+local function reorderTM (head)
+ for curr in traverse_id(glyphnode, head) do
+ if curr.width > 0 then -- old hangul vertical typesetting is broken?
+ local uni = get_unicode_char(curr)
+ if uni and (uni == 0x302E or uni == 0x302F) then
+ local p = curr.prev
+ while p do
+ if p.id ~= glyphnode then break end
+ local pc = get_cjk_class(get_unicode_char(p))
+ if pc == 7 or pc == 8 then
+ head = insert_before(head,p,copy_node(curr))
+ head = remove_node(head,curr)
+ break
+ end
+ p = p.prev
+ end
+ end
+ end
+ end
+ return head
+end
+
----------------------------------
-- add to callback : pre-linebreak
----------------------------------
@@ -1557,6 +1581,7 @@ add_to_callback('hpack_filter', function(head)
spread_ruby_base_box(head)
head = compress_fullwidth_punctuations(head)
-- head = no_ruby_at_margin(head)
+ head = reorderTM(head)
return head
end, 'luatexko.hpack_filter')
@@ -1575,6 +1600,7 @@ add_to_callback('pre_linebreak_filter', function(head)
head = compress_fullwidth_punctuations(head)
discourage_char_widow(head, nodeslide(head))
head = no_ruby_at_margin(head)
+ head = reorderTM(head)
return head
end, 'luatexko.pre_linebreak_filter')
@@ -1585,20 +1611,39 @@ end, 'luatexko.pre_linebreak_filter')
local function after_linebreak_dotemph (head)
for curr in traverse(head) do
if curr.id == hlistnode then -- hlist may be nested!!!
- after_linebreak_dotemph(curr.head)
+ curr.head = after_linebreak_dotemph(curr.head)
elseif curr.id == glyphnode then
local attr = has_attribute(curr,dotemphattr)
if attr and attr > 0 then
- local d = copy_node(dotemphnode[attr])
- local dot = d.head
- d.head = get_kernnode(-curr.width/2-d.width/2)
- d.head.next = dot
- d.width = 0
- insert_after(head,curr,d)
+ local cc = get_cjk_class(get_unicode_char(curr))
+ if cc and (cc == 0 or cc == 7 or cc == 8) then
+ local basewd = curr.width or 0
+ if cc == 8 then -- check next char for old hangul jung/jongseong
+ local nn = curr.next
+ while nn do
+ if nn.id ~= glyphnode then break end
+ local uni = get_unicode_char(nn)
+ local nc = get_cjk_class(uni)
+ if nc and nc == 9 and uni ~= 0x302E and uni ~= 0x302F then
+ basewd = basewd + (nn.width or 0)
+ else
+ break
+ end
+ nn = nn.next
+ end
+ end
+ local d = copy_node(dotemphnode[attr])
+ local dot = d.head
+ d.head = get_kernnode(basewd/2-d.width/2)
+ d.head.next = dot
+ d.width = 0
+ head = insert_before(head,curr,d)
+ end
unset_attribute(curr,dotemphattr)
end
end
end
+ return head
end
-------------------------------
@@ -1649,9 +1694,10 @@ local function draw_underline(head,curr,width,ulinenum,ulstart)
and nd.subtype == whatsitspecial
and nd.data
and stringfind(nd.data,"luako:uline") then
- remove_node(head,nd)
+ head = remove_node(head,nd)
end
end
+ return head
end
local function after_linebreak_underline(head,glueorder,glueset,gluesign,ulinenum)
@@ -1659,7 +1705,7 @@ local function after_linebreak_underline(head,glueorder,glueset,gluesign,ulinenu
if ulstart and ulstart.id == gluenode then ulstart = ulstart.next end
for curr in traverse(head) do
if curr.id == hlistnode then
- ulinenum = after_linebreak_underline(curr.head,curr.glue_order,curr.glue_set,curr.glue_sign,ulinenum)
+ curr.head,ulinenum = after_linebreak_underline(curr.head,curr.glue_order,curr.glue_set,curr.glue_sign,ulinenum)
elseif curr.id == whatsitnode and curr.subtype == whatsitspecial
and curr.data then
if stringfind(curr.data,"luako:ulinebegin=") then
@@ -1668,33 +1714,33 @@ local function after_linebreak_underline(head,glueorder,glueset,gluesign,ulinenu
elseif ulstart and ulinenum
and stringfind(curr.data,'luako:ulineend') then
local wd = nodedimensions(glueset,gluesign,glueorder,ulstart,curr)
- draw_underline(head,curr,wd,ulinenum,ulstart)
+ head = draw_underline(head,curr,wd,ulinenum,ulstart)
ulinebox[ulinenum] = nil
ulinenum = nil
end
end
if ulstart and ulinenum and curr == nodetail(head) then
local wd = nodedimensions(glueset,gluesign,glueorder,ulstart,curr)
- draw_underline(head,curr,wd,ulinenum,ulstart)
+ head = draw_underline(head,curr,wd,ulinenum,ulstart)
end
end
- return ulinenum
+ return head, ulinenum
end
-----------------------------------
-- add to callback : post-linebreak
-----------------------------------
add_to_callback('vpack_filter', function(head)
- after_linebreak_dotemph(head)
+ head = after_linebreak_dotemph(head)
after_linebreak_ruby(head)
- after_linebreak_underline(head)
- return true
+ head = after_linebreak_underline(head)
+ return head
end, 'luatexko.vpack_filter')
add_to_callback("post_linebreak_filter", function(head)
- after_linebreak_dotemph(head)
+ head = after_linebreak_dotemph(head)
after_linebreak_ruby(head)
- after_linebreak_underline(head)
- return true
+ head = after_linebreak_underline(head)
+ return head
end, 'luatexko.post_linebreak_filter')