diff options
author | Karl Berry <karl@freefriends.org> | 2013-12-06 22:14:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-12-06 22:14:25 +0000 |
commit | 7e784ae2dff9b04aa5830bc1c60753ad9beee4b9 (patch) | |
tree | 80172c916282fd841d85e583fad6a4a6457bebc6 /Master/texmf-dist/tex/luatex | |
parent | 12667237913177a3776303787aaea92ded17cdd0 (diff) |
luatexko (6dec13)
git-svn-id: svn://tug.org/texlive/trunk@32343 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
5 files changed, 699 insertions, 587 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty index 6984b79d460..871a4a29cab 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty @@ -14,7 +14,7 @@ \input luaotfload.sty \catcode`@ = 11 \else - \ProvidesPackage{luatexko-core}[2013/07/03 v1.2 Typesetting Korean with LuaTeX] + \ProvidesPackage{luatexko-core}[2013/12/06 v1.3 Typesetting Korean with LuaTeX] \RequirePackage{luaotfload}[2013/05/23] \fi @@ -26,6 +26,8 @@ \newluatexattribute\luakorubyattr \chardef\luakorubyattrnum\the\allocationnumber \newluatexattribute\hangfntattr \newluatexattribute\hanjfntattr +\newluatexattribute\fallbackfntattr +\newluatexattribute\hangulpunctsattr %% load lua modules \RequireLuaModule{luatexko} @@ -48,20 +50,28 @@ plus \fontdimen\thr@@\the\font minus \fontdimen4\the\font} %% auto josa -\protected\def\은{{\autojosaattr\@ne 은}} +\def\josaignoreparens{\afterassignment\josa@ignore@parens\count@} +\def\josa@ignore@parens{% + \ifnum\count@>\z@ \chardef\josa@attr@level\tw@ + \else \chardef\josa@attr@level\@ne + \fi +} +\josaignoreparens=\z@ + +\protected\def\은{{\autojosaattr\josa@attr@level 은}} \let\는\은 -\protected\def\을{{\autojosaattr\@ne 을}} +\protected\def\을{{\autojosaattr\josa@attr@level 을}} \let\를\을 -\protected\def\와{{\autojosaattr\@ne 와}} +\protected\def\와{{\autojosaattr\josa@attr@level 와}} \let\과\와 -\protected\def\가{{\autojosaattr\@ne 가}} -\protected\def\이{{\autojosaattr\@ne 이}} +\protected\def\가{{\autojosaattr\josa@attr@level 가}} +\protected\def\이{{\autojosaattr\josa@attr@level 이}} \protected\def\라{\이라} -\protected\def\으{{\autojosaattr\@ne 으}} +\protected\def\으{{\autojosaattr\josa@attr@level 으}} \protected\def\로{\으로} %% dot-emphasis @@ -101,13 +111,13 @@ \fontsize\dimen@\dimen@\selectfont \else \ifdefined\rubyfont \else - \luatexko@resize@font\font\resized@font\font\rubysize - \ifdefined\hangul@font - \luatexko@resize@font\hangulfont{}\hangul@font\rubysize - \fi - \ifdefined\hanja@font - \luatexko@resize@font\hanjafont{}\hanja@font\rubysize - \fi + \luatexko@resize@font\font\resized@font\font\rubysize + \ifdefined\hangul@font + \luatexko@resize@font\hangulfont{}\hangul@font\rubysize + \fi + \ifdefined\hanja@font + \luatexko@resize@font\hanjafont{}\hanja@font\rubysize + \fi \fi \fi #2}\ht\tw@\z@\dp\tw@\z@ \directlua{% @@ -124,9 +134,9 @@ \expandafter\dimen@\pdffontsize#3\relax \edef\luatexko@tmp@fontname{% \directlua{ - local f = [===[\fontname#3]===] - f = string.gsub(f," at .+","") - tex.sprint(f) }}% + local f = [===[\fontname#3]===] + f = string.gsub(f," at .+","") + tex.sprint(f) }}% #1#2=\luatexko@tmp@fontname\space at #4\dimen@ #2} \fi @@ -218,6 +228,7 @@ \begingroup \let\luatexko@hangul@selectfont\relax \let\luatexko@hanja@selectfont\relax + \let\luatexko@fallback@selectfont\relax \check@hangul@family \ifdefined\hangul@font \hangul@font \fi \expandafter\expandafter\expandafter @@ -228,20 +239,36 @@ \begingroup \let\luatexko@hangul@selectfont\relax \let\luatexko@hanja@selectfont\relax + \let\luatexko@fallback@selectfont\relax \check@hanja@family \ifdefined\hanja@font \hanja@font \fi \expandafter\expandafter\expandafter \endgroup \expandafter\hanjfntattr\luatexfontid\font\relax - \ifnum\cjtypesetattr>\z@\luatexkolatinspaceskip\fi +% \ifnum\cjtypesetattr>\z@\luatexkolatinspaceskip\fi +} +\def\luatexko@fallback@selectfont{% + \begingroup + \let\luatexko@hangul@selectfont\relax + \let\luatexko@hanja@selectfont\relax + \let\luatexko@fallback@selectfont\relax + \check@fallback@family + \ifdefined\fallback@font \fallback@font \fi + \expandafter\expandafter\expandafter + \endgroup + \expandafter\fallbackfntattr\luatexfontid\font\relax +% \ifnum\cjtypesetattr>\z@\luatexkolatinspaceskip\fi } \let\check@hangul@family\relax \let\check@hanja@family \relax +\let\check@fallback@family\relax % user interface for plain tex \protected\def\hangulfont {\afterassignment\luatexko@hangul@selectfont\font\hangul@font} \protected\def\hanjafont {\afterassignment\luatexko@hanja@selectfont \font\hanja@font } +\protected\def\fallbackfont + {\afterassignment\luatexko@fallback@selectfont\font\fallback@font} %% hangul in math mode -- general \def\setmathhangulblock#1#2{% @@ -309,10 +336,38 @@ \directlua{ luatexko.hanjafontforhanja = false }% \fi} +% latin punctuations typeset with hangul fonts +\def\hangulpunctuations{\afterassignment\h@ngulpunctu@tions\count@} +\def\h@ngulpunctu@tions{% + \ifnum\count@>\z@ + \hangulpunctsattr\@ne + \else + \unsetluatexattribute\hangulpunctsattr + \fi +} +\def\registerpunctuations#1{\registerpunctu@tions#1,*,} +\def\registerpunctu@tions#1,{% + \ifx\empty#1\empty + \expandafter\registerpunctu@tions + \else\ifx*#1\else + \directlua{ luatexko.hangulpunctuations[\number#1]=true } + \expandafter\expandafter\expandafter\registerpunctu@tions + \fi\fi +} +\def\unregisterpunctuations#1{\unregisterpunctu@tions#1,*,} +\def\unregisterpunctu@tions#1,{% + \ifx\empty#1\empty + \expandafter\unregisterpunctu@tions + \else\ifx*#1\else + \directlua{ luatexko.hangulpunctuations[\number#1]=nil } + \expandafter\expandafter\expandafter\unregisterpunctu@tions + \fi\fi +} + %% frenchspacing is default \frenchspacing %% 말줄임표 -\def\hellipsis{^^^^2026\kern-.1em ^^^^2026} +\def\hellipsis{^^^^2026^^^^2026} \endinput diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua index 2b8d33bd521..8c6e0bc3d98 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua @@ -11,9 +11,9 @@ -- version 2006/05/20 or later. luatexbase.provides_module({ - name = "luatexko-normalize", + name = "luatexko-normalize", version = 1.2, - date = "2013/06/10", + date = "2013/06/10", author = "Dohyun Kim", 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 595af6b1530..2afdad38532 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua @@ -45,11 +45,11 @@ local function get_uhc_uni_table() if not line then break end local _,_,ea,eb,uni = find(line,"<(%x+)>%s+<(%x+)>%s+<(%x+)>") if ea and eb and uni then - ea, eb, uni = tonumber(ea,16),tonumber(eb,16),tonumber(uni,16) - for i=ea,eb do - t_uhc2ucs[i] = uni - uni = uni + 1 - end + ea, eb, uni = tonumber(ea,16),tonumber(eb,16),tonumber(uni,16) + for i=ea,eb do + t_uhc2ucs[i] = uni + uni = uni + 1 + end end end file:close() diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua index b85cb734817..3d24259379d 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua @@ -11,84 +11,84 @@ -- version 2006/05/20 or later. local err,warn,info,log = luatexbase.provides_module({ - name = 'luatexko', - date = '2013/07/03', - version = 1.2, + name = 'luatexko', + date = '2013/12/06', + version = 1.3, description = 'Korean linebreaking and font-switching', author = 'Dohyun Kim', license = 'LPPL v1.3+', }) -luatexko = luatexko or {} -local luatexko = luatexko +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 -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 remove_node = node.remove -local insert_before = node.insert_before -local insert_after = node.insert_after -local copy_node = node.copy -local traverse_id = node.traverse_id -local traverse = node.traverse -local has_attribute = node.has_attribute -local unset_attribute = node.unset_attribute -local set_attribute = node.set_attribute -local nodecount = node.count -local nodeslide = node.slide -local nodedimensions = node.dimensions -local nodetail = node.tail - -local finemathattr = luatexbase.attributes.finemathattr -local cjtypesetattr = luatexbase.attributes.cjtypesetattr -local dotemphattr = luatexbase.attributes.dotemphattr -local autojosaattr = luatexbase.attributes.autojosaattr -local luakorubyattr = luatexbase.attributes.luakorubyattr -local hangfntattr = luatexbase.attributes.hangfntattr -local hanjfntattr = luatexbase.attributes.hanjfntattr -local luakoglueattr = luatexbase.new_attribute("luakoglueattr") -local luakounicodeattr = luatexbase.new_attribute("luakounicodeattr") -local quoteraiseattr = luatexbase.new_attribute("quoteraiseattr") - -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 mathnode = node.id("math") -local hlistnode = node.id("hlist") -local vlistnode = node.id("vlist") -local kernnode = node.id("kern") -local penaltynode = node.id("penalty") -local rulenode = node.id("rule") -local whatsitnode = node.id("whatsit") -local whatsitspecial = node.subtype("special") - -local new_glue = node.new(gluenode) -local new_glue_spec = node.new(gluespecnode) -local new_penalty = node.new(penaltynode) -local new_kern = node.new(kernnode,1) -local new_rule = node.new(rulenode) +luatexko.dotemphnode = dotemphnode +luatexko.rubynode = rubynode +luatexko.ulinebox = ulinebox +luatexko.hanjafontforhanja = luatexko.hanjafontforhanja or false + +local stringbyte = string.byte +local stringgsub = string.gsub +local stringchar = string.char +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 remove_node = node.remove +local insert_before = node.insert_before +local insert_after = node.insert_after +local copy_node = node.copy +local traverse_id = node.traverse_id +local traverse = node.traverse +local has_attribute = node.has_attribute +local unset_attribute = node.unset_attribute +local set_attribute = node.set_attribute +local nodecount = node.count +local nodeslide = node.slide +local nodedimensions = node.dimensions +local nodetail = node.tail + +local finemathattr = luatexbase.attributes.finemathattr +local cjtypesetattr = luatexbase.attributes.cjtypesetattr +local dotemphattr = luatexbase.attributes.dotemphattr +local autojosaattr = luatexbase.attributes.autojosaattr +local luakorubyattr = luatexbase.attributes.luakorubyattr +local hangfntattr = luatexbase.attributes.hangfntattr +local hanjfntattr = luatexbase.attributes.hanjfntattr +local fallbackfntattr = luatexbase.attributes.fallbackfntattr +local hangulpunctsattr = luatexbase.attributes.hangulpunctsattr +local luakoglueattr = luatexbase.new_attribute("luakoglueattr") +local luakounicodeattr = luatexbase.new_attribute("luakounicodeattr") + +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 mathnode = node.id("math") +local hlistnode = node.id("hlist") +local vlistnode = node.id("vlist") +local kernnode = node.id("kern") +local penaltynode = node.id("penalty") +local rulenode = node.id("rule") +local whatsitnode = node.id("whatsit") +local whatsitspecial = node.subtype("special") + +local new_glue = node.new(gluenode) +local new_glue_spec = node.new(gluespecnode) +local new_penalty = node.new(penaltynode) +local new_kern = node.new(kernnode,1) +local new_rule = node.new(rulenode) local emsize = 655360 @@ -361,77 +361,101 @@ local xspcode = { } local cjk_glue_spec = { [0] = --- 한자 ( ) · . — ? 한글 초성 중종성 latin -{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --한자 -{[0] = nil, nil, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, -- ( -{[0] = {.5,.5}, {.5,.5}, nil, {.25,.25},nil, {.5,.5}, {.5,.5}, {.25,.25},{.25,.25},{.25,.25},{.5,.5}, }, -- ) -{[0] = {.25,.25},{.25,.25},{.25,.25},{.5,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},}, -- · -{[0] = {.5,0}, {.5,0}, nil, {.75,.25},nil, {.5,0}, {.5,0}, {.5,0}, {.5,0}, {.5,0}, {.5,0}, }, -- . -{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, -- — -{[0] = {.5,.5}, {.5,.5}, nil, {.25,.25},nil, nil, nil, {.5,.5}, {.5,.5}, {.5,.5}, {.5,.5}, }, -- ? +-- 한자 ( ) · . — ? 한글 초성 중종성 latin +{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --한자 +{[0] = nil, nil, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, -- ( +{[0] = {.5,.5}, {.5,.5}, nil, {.25,.25},nil, {.5,.5}, {.5,.5}, {.25,.25},{.25,.25},{.25,.25},{.5,.5}, }, -- ) +{[0] = {.25,.25},{.25,.25},{.25,.25},{.5,.25}, {.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},{.25,.25},}, -- · +{[0] = {.5,0}, {.5,0}, nil, {.75,.25},nil, {.5,0}, {.5,0}, {.5,0}, {.5,0}, {.5,0}, {.5,0}, }, -- . +{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, -- — +{[0] = {.5,.5}, {.5,.5}, nil, {.25,.25},nil, nil, nil, {.5,.5}, {.5,.5}, {.5,.5}, {.5,.5}, }, -- ? -- -{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --한글 -{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --초성 -{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --중종성 -{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --latin +{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --한글 +{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --초성 +{[0] = nil, {.25,.25},nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --중종성 +{[0] = nil, {.5,.5}, nil, {.25,.25},nil, nil, nil, nil, nil, nil, nil, }, --latin } local latin_fullstop = { - [0x2e] = 1, - [0x21] = 2, - [0x3f] = 2, - [0x2026] = 1, -- \ldots + [0x2e] = 1, -- . + -- [0x21] = 2, -- ! + -- [0x2c] = 2, -- , + -- [0x3f] = 2, -- ? + -- [0x2026] = 1, -- \ldots } -local latin_quotes = { - [0x0028] = 0x0029, -- ( ) - [0x003C] = 0x003E, -- < > - [0x2018] = 0x2019, -- ‘ ’ - [0x201C] = 0x201D, -- “ ” +local hangulpunctuations = luatexko.hangulpunctuations or { + [0x21] = true, -- ! + [0x27] = true, -- ' + [0x28] = true, -- ( + [0x29] = true, -- ) + [0x2C] = true, -- , + -- [0x2D] = true, -- - + [0x2E] = true, -- . + [0x3A] = true, -- : + [0x3B] = true, -- ; + [0x3C] = true, -- < + [0x3E] = true, -- > + [0x3F] = true, -- ? + [0x5B] = true, -- [ + [0x5D] = true, -- ] + [0x60] = true, -- ` + [0x7B] = true, -- { + [0x7D] = true, -- } + [0xB7] = true, -- periodcentered + -- [0x2014] = true, -- emdash + -- [0x2015] = true, -- horizontal bar + [0x2018] = true, -- quoteleft + [0x2019] = true, -- quoteright + [0x201C] = true, -- quotedblleft + [0x201D] = true, -- quotedblright + [0x2026] = true, -- ellipsis + [0x203B] = true, -- ※ } - -local josa_list = { -- automatic josa selection - -- 리을, 중성, 종성 - [0xAC00] = {0xC774, 0xAC00, 0xC774}, -- 가 = 이, 가, 이 - [0xC740] = {0xC740, 0xB294, 0xC740}, -- 은 = 은, 는, 은 - [0xC744] = {0xC744, 0xB97C, 0xC744}, -- 을 = 을, 를, 을 - [0xC640] = {0xACFC, 0xC640, 0xACFC}, -- 와 = 과, 와, 과 - [0xC73C] = {-1, -1, 0xC73C}, -- 으(로) = , , 으 - [0xC774] = {0xC774, -1, 0xC774}, -- 이(라) = 이, , 이 +luatexko.hangulpunctuations = hangulpunctuations + +local josa_list = { + -- 리을, 중성, 종성 + [0xAC00] = {0xC774, 0xAC00, 0xC774}, -- 가 = 이, 가, 이 + [0xC740] = {0xC740, 0xB294, 0xC740}, -- 은 = 은, 는, 은 + [0xC744] = {0xC744, 0xB97C, 0xC744}, -- 을 = 을, 를, 을 + [0xC640] = {0xACFC, 0xC640, 0xACFC}, -- 와 = 과, 와, 과 + [0xC73C] = {-1, -1, 0xC73C}, -- 으(로) = , , 으 + [0xC774] = {0xC774, -1, 0xC774}, -- 이(라) = 이, , 이 } local josa_code = { - [0x30] = 3, -- 0 - [0x31] = 1, -- 1 - [0x33] = 3, -- 3 - [0x36] = 3, -- 6 - [0x37] = 1, -- 7 - [0x38] = 1, -- 8 - [0x4C] = 1, -- L - [0x4D] = 3, -- M - [0x4E] = 3, -- N - [0x6C] = 1, -- l - [0x6D] = 3, -- m - [0x6E] = 3, -- n - [0xFB02] = 1, -- fl - [0xFB04] = 1, -- ffl - ng = 3, - ap = 3, - up = 3, - at = 3, - et = 3, - it = 3, - ot = 3, - ut = 3, - ok = 3, - ic = 3, - le = 1, - ime = 3, - ine = 3, - ack = 3, - ick = 3, - oat = 2, - TEX = 3, + [0x30] = 3, -- 0 + [0x31] = 1, -- 1 + [0x33] = 3, -- 3 + [0x36] = 3, -- 6 + [0x37] = 1, -- 7 + [0x38] = 1, -- 8 + [0x4C] = 1, -- L + [0x4D] = 3, -- M + [0x4E] = 3, -- N + [0x6C] = 1, -- l + [0x6D] = 3, -- m + [0x6E] = 3, -- n + [0xFB02] = 1, -- fl + [0xFB04] = 1, -- ffl + ng = 3, + ap = 3, + up = 3, + at = 3, + et = 3, + it = 3, + ot = 3, + ut = 3, + ok = 3, + ic = 3, + le = 1, + ime = 3, + ine = 3, + ack = 3, + ick = 3, + oat = 2, + TEX = 3, -- else 2 } @@ -476,8 +500,8 @@ local function is_cjk_k (c) or (c >= 0x20000 and c <= 0x2A6DF) or (c >= 0x2F800 and c <= 0x2FA1F) or c == 0x00B0 or c == 0x2015 - -- or c == 0x2018 or c == 0x2019 - -- or c == 0x201C or c == 0x201D + -- or c == 0x2018 or c == 0x2019 + -- or c == 0x201C or c == 0x201D or c == 0x2026 or c == 0x2032 or c == 0x2033 end @@ -506,19 +530,19 @@ end local function get_cjk_class (ch, cjtype) if ch then - if is_hangul(ch) then return 7 end -- hangul = 7 - if is_chosong(ch) then return 8 end -- jamo LC = 8 + if is_hangul(ch) then return 7 end -- hangul = 7 + if is_chosong(ch) then return 8 end -- jamo LC = 8 if is_jungjongsong(ch) then return 9 end -- jamo VL, TC, TM = 9 - local c = is_cjk_k(ch) and 0 or 10 -- hanja = 0; latin = 10 + local c = is_cjk_k(ch) and 0 or 10 -- hanja = 0; latin = 10 if cjkclass[ch] then c = cjkclass[ch] end -- cjkclass 1 .. 6 if cjtype then if cjtype == 2 and - (ch == 0xFF1F or ch == 0xFF01 or ch == 0xFF1A or ch == 0xFF1B) then - c = 4 -- simplified chinese ? ! + (ch == 0xFF1F or ch == 0xFF01 or ch == 0xFF1A or ch == 0xFF1B) then + c = 4 -- simplified chinese ? ! end else if ch == 0x2018 or ch == 0x2019 or ch == 0x201C or ch == 0x201D then - c = 10 -- korean “ ” ‘ ’ + c = 10 -- korean “ ” ‘ ’ end end return c @@ -567,12 +591,12 @@ local function get_char_boundingbox(fid, chr) end local function get_unicode_char(curr) - if (curr.char > 0 and curr.char < 0xE000) -- no pua - or (curr.char > 0xF8FF and curr.char < 0xF0000) then - return curr.char + local uni = curr.char + if (uni > 0 and uni < 0xE000) or (uni > 0xF8FF and uni < 0xF0000) then + return uni -- no pua end - -- tounicode is not reliable. backend bug - local uni = get_font_char(curr.font, curr.char) + -- tounicode is now reliable. backend is fixed + 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 @@ -671,57 +695,23 @@ local function cjk_insert_nodes(head,curr,currchar,currfont,prevchar,prevfont) local p = get_cjk_class(prevchar, currentcjtype) local c = get_cjk_class(currchar, currentcjtype) ---[[raise latin puncts - if curr.id == glyphnode and has_attribute(curr,finemathattr) == 1 then -- not ttfamily - if c < 10 then -- not ttfamily - local nn, raise = curr.next, nil - while nn do - if nn.id == glyphnode and currfont ~= nn.font and latin_fullstop[nn.char] then - if not raise then - raise = get_font_feature(currfont, "punctraise") - raise = raise and tex_sp(raise) - end - if raise then - nn.yoffset = nn.yoffset or 0 - nn.yoffset = nn.yoffset + raise - end - nn = nn.next - elseif nn.id == kernnode then - nn = nn.next - else - break - end - end - elseif latin_quotes[currchar] and not has_attribute(curr,quoteraiseattr) then - local nn, raise, cjkfont, depth, todotbl = curr.next, nil, nil, 1, {curr} - while nn do - if nn.id == glyphnode then - if latin_quotes[nn.char] == latin_quotes[currchar] then - depth = depth + 1 - todotbl[#todotbl + 1] = nn - elseif nn.char == latin_quotes[currchar] then - depth = depth - 1 - todotbl[#todotbl + 1] = nn - if depth == 0 then - if raise and nn.font == currfont and cjkfont ~= currfont then - for _,n in ipairs(todotbl) do - n.yoffset = n.yoffset or 0 - n.yoffset = n.yoffset + raise - end - end - for _,n in ipairs(todotbl) do - set_attribute(n, quoteraiseattr, 1) - end - break - end - elseif not raise then - if get_cjk_class(get_unicode_char(nn)) < 10 then - raise = get_font_feature(nn.font, "quoteraise") - raise = raise and tex_sp(raise) - if raise then cjkfont = nn.font end - end - end - end - nn = nn.next + if curr.id == glyphnode and has_attribute(curr,finemathattr) == 1 and c < 10 then -- not ttfamily + local nn, raise = curr.next, nil + while nn do + if nn.id == glyphnode and latin_fullstop[nn.char] then + if not raise then + raise = get_font_feature(currfont, "punctraise") + raise = raise and tex_sp(raise) + end + if raise then + nn.yoffset = nn.yoffset or 0 + nn.yoffset = nn.yoffset + raise + end + nn = nn.next + elseif nn.id == kernnode then + nn = nn.next + else + break end end end @@ -739,60 +729,60 @@ local function cjk_insert_nodes(head,curr,currchar,currfont,prevchar,prevfont) if p and c then if currentcjtype then if cjk_glue_spec[p] and cjk_glue_spec[p][c] then - local width = emsize * cjk_glue_spec[p][c][1] - local stretch = 0 - local shrink = emsize * cjk_glue_spec[p][c][2] - insert_before(head,curr,make_luako_glue(width, stretch, shrink)) + local width = emsize * cjk_glue_spec[p][c][1] + 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 < 9 then -- break between chosong and chosong - kanjiskip(head,curr) + kanjiskip(head,curr) elseif (p < 10 and c == 10) or (p == 10 and c < 10) then - if xspcode[currchar] then - if xspcode[currchar] % 2 == 1 then - xkanjiskip(head,curr) - end - elseif xspcode[prevchar] then - if xspcode[prevchar] > 1 then - xkanjiskip(head,curr) - end - elseif inhibitxspcode[currchar] then -- 3, 2 - if inhibitxspcode[currchar] > 1 then - xkanjiskip(head,curr) - end - elseif inhibitxspcode[prevchar] then -- 3, 1 - if inhibitxspcode[prevchar] % 2 == 1 then - xkanjiskip(head,curr) - end - else - xkanjiskip(head,curr) - end + if xspcode[currchar] then + if xspcode[currchar] % 2 == 1 then + xkanjiskip(head,curr) + end + elseif xspcode[prevchar] then + if xspcode[prevchar] > 1 then + xkanjiskip(head,curr) + end + elseif inhibitxspcode[currchar] then -- 3, 2 + if inhibitxspcode[currchar] > 1 then + xkanjiskip(head,curr) + end + elseif inhibitxspcode[prevchar] then -- 3, 1 + if inhibitxspcode[prevchar] % 2 == 1 then + xkanjiskip(head,curr) + end + else + xkanjiskip(head,curr) + end end else if (p < 10 and c == 10) or (p == 10 and c < 10) then - if xspcode[currchar] then - if xspcode[currchar] % 2 == 1 then - koreanlatinskip(head,curr,currfont,prevfont,was_penalty) - end - elseif xspcode[prevchar] then - if xspcode[prevchar] > 1 then - koreanlatinskip(head,curr,currfont,prevfont,was_penalty) - end - elseif inhibitxspcode[currchar] then -- 3, 2 - if inhibitxspcode[currchar] > 1 then - koreanlatinskip(head,curr,currfont,prevfont,was_penalty) - end - elseif inhibitxspcode[prevchar] then -- 3, 1 - if inhibitxspcode[prevchar] % 2 == 1 then - koreanlatinskip(head,curr,currfont,prevfont,was_penalty) - end - else - koreanlatinskip(head,curr,currfont,prevfont,was_penalty) - end + if xspcode[currchar] then + if xspcode[currchar] % 2 == 1 then + koreanlatinskip(head,curr,currfont,prevfont,was_penalty) + end + elseif xspcode[prevchar] then + if xspcode[prevchar] > 1 then + koreanlatinskip(head,curr,currfont,prevfont,was_penalty) + end + elseif inhibitxspcode[currchar] then -- 3, 2 + if inhibitxspcode[currchar] > 1 then + koreanlatinskip(head,curr,currfont,prevfont,was_penalty) + end + elseif inhibitxspcode[prevchar] then -- 3, 1 + if inhibitxspcode[prevchar] % 2 == 1 then + koreanlatinskip(head,curr,currfont,prevfont,was_penalty) + end + else + koreanlatinskip(head,curr,currfont,prevfont,was_penalty) + end elseif cjk_glue_spec[p] and cjk_glue_spec[p][c] then - koreanlatinskip(head,curr,currfont,prevfont,was_penalty) + koreanlatinskip(head,curr,currfont,prevfont,was_penalty) elseif p == 7 and c == 7 then - interhangulskip(head,curr,currfont,prevfont,was_penalty) + interhangulskip(head,curr,currfont,prevfont,was_penalty) elseif p < 10 and c < 9 then -- break between chosong and chosong - interhanjaskip(head,curr,was_penalty) + interhanjaskip(head,curr,was_penalty) end end end @@ -804,34 +794,34 @@ local function cjk_spacing_linebreak (head) for curr in traverse(head) do if has_attribute(curr,finemathattr) then if curr.id == gluenode then - prevchar,prevfont = nil,nil - unset_attribute(curr,finemathattr) + prevchar,prevfont = nil,nil + unset_attribute(curr,finemathattr) elseif curr.id == glyphnode then - emsize = get_font_emsize(curr.font) - local uni = get_unicode_char(curr) - if uni then - prevchar,prevfont = cjk_insert_nodes(head,curr,uni,curr.font,prevchar,prevfont) - end - unset_attribute(curr,finemathattr) + emsize = get_font_emsize(curr.font) + local uni = get_unicode_char(curr) + if uni then + prevchar,prevfont = cjk_insert_nodes(head,curr,uni,curr.font,prevchar,prevfont) + end + unset_attribute(curr,finemathattr) elseif curr.id == mathnode then - local currchar = 0 - if curr.surround and curr.surround > 0 then - currchar = 0x4E00 - end - if curr.subtype == 0 then - cjk_insert_nodes(head,curr,currchar,nil,prevchar,prevfont) - prevchar,prevfont = nil,nil - else - prevchar,prevfont = currchar,nil - end - unset_attribute(curr,finemathattr) + local currchar = 0 + if curr.surround and curr.surround > 0 then + currchar = 0x4E00 + end + if curr.subtype == 0 then + cjk_insert_nodes(head,curr,currchar,nil,prevchar,prevfont) + prevchar,prevfont = nil,nil + else + prevchar,prevfont = currchar,nil + end + unset_attribute(curr,finemathattr) elseif curr.id == hlistnode or curr.id == vlistnode then - local firstchr, firstfid = get_hlist_class_first(curr) - if firstchr then - cjk_insert_nodes(head,curr,firstchr,firstfid,prevchar,prevfont) - end - prevchar,prevfont = get_hlist_class_last(curr,prevchar,prevfont) - unset_attribute(curr,finemathattr) + local firstchr, firstfid = get_hlist_class_first(curr) + if firstchr then + cjk_insert_nodes(head,curr,firstchr,firstfid,prevchar,prevfont) + end + prevchar,prevfont = get_hlist_class_last(curr,prevchar,prevfont) + unset_attribute(curr,finemathattr) end else prevchar,prevfont = 0,nil -- treat \verb as latin character. @@ -849,47 +839,47 @@ local function remove_cj_spaceskip (head) if cjattr and cjattr > 0 and prv and nxt then local prevclass, prevchar, prevfont, nextclass if prv.id == hlistnode or prv.id == vlistnode then - prevclass = get_hlist_class_last(prv) + prevclass = get_hlist_class_last(prv) else - -- what is this strange kern before \text?? - if prv.id == kernnode and prv.kern == 0 then - prv = prv.prev - end - if prv.id == glyphnode then - prevclass = get_cjk_class(get_unicode_char(prv), cjattr) - prevchar, prevfont = prv.char, prv.font - end + -- what is this strange kern before \text?? + if prv.id == kernnode and prv.kern == 0 then + prv = prv.prev + end + if prv.id == glyphnode then + prevclass = get_cjk_class(get_unicode_char(prv), cjattr) + prevchar, prevfont = prv.char, prv.font + end end if nxt.id == glyphnode then - nextclass = get_cjk_class(get_unicode_char(nxt), cjattr) + nextclass = get_cjk_class(get_unicode_char(nxt), cjattr) elseif nxt.id == hlistnode or nxt.id == vlistnode then - nextclass = get_hlist_class_first(nxt) + nextclass = get_hlist_class_first(nxt) end if (prevclass and prevclass < 10) or (nextclass and nextclass < 10) then - local subtype = curr.subtype - if subtype == 13 then -- do not touch on xspaceskip for now - remove_node(head,curr) - else -- before \text?? spaceskip is replaced by glue type 0 - local spec = curr.spec - local csp = spec and spec.width - local cst = spec and spec.stretch - local csh = spec and spec.shrink - local fp = get_font_table(prevfont) - fp = fp and fp.parameters - local sp = fp and fp.space - local st = fp and fp.space_stretch - local sh = fp and fp.space_shrink - sp = sp and tex_round(sp) - st = st and tex_round(st) - sh = sh and tex_round(sh) - if prevchar and prevchar >= 65 and prevchar <= 90 then - st = st and mathfloor(st*(999/1000)) - sh = sh and mathfloor(sh*(1001/1000)) - end - if sp == csp and st == cst and sh == csh then - remove_node(head,curr) - end - end + local subtype = curr.subtype + if subtype == 13 then -- do not touch on xspaceskip for now + remove_node(head,curr) + else -- before \text?? spaceskip is replaced by glue type 0 + local spec = curr.spec + local csp = spec and spec.width + local cst = spec and spec.stretch + local csh = spec and spec.shrink + local fp = get_font_table(prevfont) + fp = fp and fp.parameters + local sp = fp and fp.space + local st = fp and fp.space_stretch + local sh = fp and fp.space_shrink + sp = sp and tex_round(sp) + st = st and tex_round(st) + sh = sh and tex_round(sh) + if prevchar and prevchar >= 65 and prevchar <= 90 then + st = st and mathfloor(st*(999/1000)) + sh = sh and mathfloor(sh*(1001/1000)) + end + if sp == csp and st == cst and sh == csh then + remove_node(head,curr) + end + end end end end @@ -911,50 +901,50 @@ local function compress_fullwidth_punctuations (head) local bbox = get_char_boundingbox(curr.font, curr.char) if not bbox then return head end -- if class == 2 or class == 4 then - local wd - if get_font_feature(curr.font,'vertical') then - wd = ensize<width and ensize-width or 0 - else - wd = (bbox[3] < ensize) and ensize-width or bbox[3]-width+oneoften - end - if chr.right_protruding then - -- kern is a breakpoint if followed by a glue - insert_after(head, curr, get_kernnode(wd)) - else - insert_after(head, curr, get_rulenode(wd)) - end + local wd + if get_font_feature(curr.font,'vertical') then + wd = ensize<width and ensize-width or 0 + else + wd = (bbox[3] < ensize) and ensize-width or bbox[3]-width+oneoften + end + if chr.right_protruding then + -- kern is a breakpoint if followed by a glue + insert_after(head, curr, get_kernnode(wd)) + else + insert_after(head, curr, get_rulenode(wd)) + end elseif class == 1 then - local wd - if get_font_feature(curr.font,'vertical') then - wd = ensize<width and ensize-width or 0 - else - wd = (width-bbox[1] < ensize) and ensize-width or -bbox[1]+oneoften - end - if chr.left_protruding then - head = insert_before(head, curr, get_kernnode(wd)) - else - head = insert_before(head, curr, get_rulenode(wd)) - end + local wd + if get_font_feature(curr.font,'vertical') then + wd = ensize<width and ensize-width or 0 + else + wd = (width-bbox[1] < ensize) and ensize-width or -bbox[1]+oneoften + end + if chr.left_protruding then + head = insert_before(head, curr, get_kernnode(wd)) + else + head = insert_before(head, curr, get_rulenode(wd)) + end elseif class == 3 then - local lwd, rwd - local quarter, thirdquarter, halfwd = ensize/2, ensize*1.5, width/2 - if get_font_feature(curr.font,'vertical') then - rwd = quarter<halfwd and quarter-halfwd or 0 - lwd = rwd - else - rwd = (bbox[3] < thirdquarter) and quarter-halfwd or bbox[3]-width - lwd = (width-bbox[1] < thirdquarter) and quarter-halfwd or -bbox[1] - end - if chr.left_protruding then - head = insert_before(head, curr, get_kernnode(lwd)) - else - head = insert_before(head, curr, get_rulenode(lwd)) - end - if chr.right_protruding then - insert_after (head, curr, get_kernnode(rwd)) - else - insert_after (head, curr, get_rulenode(rwd)) - end + local lwd, rwd + local quarter, thirdquarter, halfwd = ensize/2, ensize*1.5, width/2 + if get_font_feature(curr.font,'vertical') then + rwd = quarter<halfwd and quarter-halfwd or 0 + lwd = rwd + else + rwd = (bbox[3] < thirdquarter) and quarter-halfwd or bbox[3]-width + lwd = (width-bbox[1] < thirdquarter) and quarter-halfwd or -bbox[1] + end + if chr.left_protruding then + head = insert_before(head, curr, get_kernnode(lwd)) + else + head = insert_before(head, curr, get_rulenode(lwd)) + end + if chr.right_protruding then + insert_after (head, curr, get_kernnode(rwd)) + else + insert_after (head, curr, get_rulenode(rwd)) + end end end end @@ -968,10 +958,10 @@ local function spread_ruby_box(head,extrawidth) for curr in traverse_id(gluenode,head) do if curr.spec then if has_attribute(curr,luakoglueattr) then - curr.spec.width = curr.spec.width + extrawidth + curr.spec.width = curr.spec.width + extrawidth else - head = insert_before(head,curr,get_kernnode(curr.spec.width+extrawidth)) - head = remove_node(head,curr) + head = insert_before(head,curr,get_kernnode(curr.spec.width+extrawidth)) + head = remove_node(head,curr) end end end @@ -985,16 +975,16 @@ local function spread_ruby_base_box (head) if attr and not rubyoverlap then local ruby = rubynode[attr][1] if ruby and ruby.width > curr.width then - local basehead = curr.head - local numofglues = nodecount(gluenode,basehead) - local extrawidth = (ruby.width - curr.width)/(numofglues + 1) - if numofglues > 0 then - basehead = spread_ruby_box(basehead,extrawidth) - end - local leading = get_kernnode(extrawidth/2) - curr.width = ruby.width - leading.next = basehead - curr.head = leading + local basehead = curr.head + local numofglues = nodecount(gluenode,basehead) + local extrawidth = (ruby.width - curr.width)/(numofglues + 1) + if numofglues > 0 then + basehead = spread_ruby_box(basehead,extrawidth) + end + local leading = get_kernnode(extrawidth/2) + curr.width = ruby.width + leading.next = basehead + curr.head = leading end end end @@ -1005,12 +995,12 @@ local function get_ruby_side_width (basewidth,rubywidth,adjacent) if adjacent then if adjacent.id == glyphnode then if not is_hanja(get_unicode_char(adjacent)) then - width = (rubywidth-basewidth-emsize)/2 - if width > 0 then - margin = emsize/2 - else - width,margin = 0,(rubywidth-basewidth)/2 - end + width = (rubywidth-basewidth-emsize)/2 + if width > 0 then + margin = emsize/2 + else + width,margin = 0,(rubywidth-basewidth)/2 + end end end end @@ -1025,34 +1015,34 @@ local function get_ruby_side_kern (head) local basewidth = curr.width local rubywidth = rubynode[attr][1].width if curr.width < rubywidth then - local _,fid = get_hlist_class_first(curr) - emsize = get_font_emsize(fid) - local leftwidth,leftmargin = get_ruby_side_width(basewidth,rubywidth,curr.prev) - if leftwidth > 0 then - curr.width = curr.width + leftwidth - end - if leftmargin > 0 then - rubynode[attr].leftmargin = leftmargin - end - local rightwidth,rightmargin = get_ruby_side_width(basewidth,rubywidth,curr.next) - if rightwidth > 0 then - curr.width = curr.width + rightwidth - end - if rightmargin > 0 then - rubynode[attr].rightmargin = rightmargin - end - rubynode[attr].rightshift = rightwidth - leftwidth - local totalspace = leftwidth+rightwidth - if totalspace > 0 then - local numofglues = nodecount(gluenode,curr.head) - local extrawidth = totalspace/(numofglues + 1) - if numofglues > 0 then - curr.head = spread_ruby_box(curr.head,extrawidth) - end - local leading = get_kernnode(extrawidth*(leftwidth/totalspace)) - leading.next = curr.head - curr.head = leading - end + local _,fid = get_hlist_class_first(curr) + emsize = get_font_emsize(fid) + local leftwidth,leftmargin = get_ruby_side_width(basewidth,rubywidth,curr.prev) + if leftwidth > 0 then + curr.width = curr.width + leftwidth + end + if leftmargin > 0 then + rubynode[attr].leftmargin = leftmargin + end + local rightwidth,rightmargin = get_ruby_side_width(basewidth,rubywidth,curr.next) + if rightwidth > 0 then + curr.width = curr.width + rightwidth + end + if rightmargin > 0 then + rubynode[attr].rightmargin = rightmargin + end + rubynode[attr].rightshift = rightwidth - leftwidth + local totalspace = leftwidth+rightwidth + if totalspace > 0 then + local numofglues = nodecount(gluenode,curr.head) + local extrawidth = totalspace/(numofglues + 1) + if numofglues > 0 then + curr.head = spread_ruby_box(curr.head,extrawidth) + end + local leading = get_kernnode(extrawidth*(leftwidth/totalspace)) + leading.next = curr.head + curr.head = leading + end end end end @@ -1075,23 +1065,23 @@ local function no_ruby_at_margin(head) if attr then local margin = rubynode[attr].leftmargin if margin then - head = insert_before(head,curr,get_kernnode(-margin)) - head = zero_width_rule_with_dir(head,curr,true) -- before - head = insert_before(head,curr,get_kernnode(margin)) + head = insert_before(head,curr,get_kernnode(-margin)) + head = zero_width_rule_with_dir(head,curr,true) -- before + head = insert_before(head,curr,get_kernnode(margin)) end margin = rubynode[attr].rightmargin if margin then - if curr.next then - if curr.next.id == gluenode then - insert_after(head,curr,get_kernnode(-margin)) - head = zero_width_rule_with_dir(head,curr) - insert_after(head,curr,get_kernnode(margin)) - elseif curr.next.id == penaltynode and curr.next.penalty < 10000 then - insert_after(head,curr.next,get_kernnode(-margin)) - head = zero_width_rule_with_dir(head,curr) - insert_after(head,curr,get_kernnode(margin)) - end - end + if curr.next then + if curr.next.id == gluenode then + insert_after(head,curr,get_kernnode(-margin)) + head = zero_width_rule_with_dir(head,curr) + insert_after(head,curr,get_kernnode(margin)) + elseif curr.next.id == penaltynode and curr.next.penalty < 10000 then + insert_after(head,curr.next,get_kernnode(-margin)) + head = zero_width_rule_with_dir(head,curr) + insert_after(head,curr,get_kernnode(margin)) + end + end end end end @@ -1101,50 +1091,48 @@ end ------------------------------ -- discourage character orphan ------------------------------ -local function inject_char_widow_penalty (head,curr,uni,pv,cjattr) +local function inject_char_widow_penalty (head,curr,uni,cjattr) if uni and prebreakpenalty[uni] ~= 10000 then local class = get_cjk_class(uni, cjattr) if class and class < 9 then + local pv = cjattr and 500 or 5000 if curr.prev and curr.prev.id == rulenode then - curr = curr.prev + curr = curr.prev end if curr.prev and curr.prev.id == gluenode then - curr = curr.prev + curr = curr.prev end if curr.prev and curr.prev.id == penaltynode then - if curr.prev.penalty < pv then - curr.prev.penalty = pv - end - else - insert_before(head,curr,get_penaltynode(pv)) + curr = curr.prev + if curr.penalty < pv then + curr.penalty = pv + end + elseif curr and curr.id == gluenode then + head, curr = insert_before(head,curr,get_penaltynode(pv)) end - return true end end + return curr end local function discourage_char_widow (head,curr) while curr do - local cjattr = has_attribute(curr,cjtypesetattr) - local pv = cjattr and 500 or 5000 + if curr == head then return end if curr.id == glyphnode then emsize = get_font_emsize(curr.font) - local width = curr.width or 0 - if width >= 2*emsize then return end + local remwd = node.dimensions(curr) + if remwd > 2*emsize then return end + local cjattr = has_attribute(curr,cjtypesetattr) local uni = get_unicode_char(curr) - if inject_char_widow_penalty(head,curr,uni,pv,cjattr) then - return true - end + curr = inject_char_widow_penalty(head,curr,uni,cjattr) elseif curr.id == hlistnode and curr.id == vlistnode then - local width = curr.width or 0 + local remwd = node.dimensions(curr) local uni,fid = get_hlist_class_first(curr) emsize = get_font_emsize(fid) - if width >= 2*emsize then return end - if inject_char_widow_penalty(head,curr,uni,pv,cjattr) then - return true - end + if remwd > 2*emsize then return end + local cjattr = has_attribute(curr,cjtypesetattr) + curr = inject_char_widow_penalty(head,curr,uni,cjattr) end - if not curr.prev then return end curr = curr.prev end end @@ -1251,7 +1239,7 @@ hanja2hangul = get_hanja_hangul_table(hanja2hangul,"hanja_hangul.tab",0x4E00) hanja2hangul = get_hanja_hangul_table(hanja2hangul,"hanjaexa_hangul.tab",0x3400) hanja2hangul = get_hanja_hangul_table(hanja2hangul,"hanjacom_hangul.tab",0xF900) --- 1 : 리을, 2 : 중성, 3 : 종성 +-- 1 : 리을, 2 : 중성, 3 : 종성 local function get_josacode (prevs) local code = prevs[1] -- last char if not code then return 2 end @@ -1281,22 +1269,28 @@ local function get_josacode (prevs) return 2 end -local function get_josaprevs(curr,josaprev) +local function get_josaprevs(curr,josaprev,ignoreparens,halt) + if type(halt) ~= "number" then halt = 0 end while curr do if curr.id == glyphnode then local chr = get_unicode_char(curr) - if xspcode[chr] - or inhibitxspcode[chr] - or prebreakpenalty[chr] - or postbreakpenalty[chr] - or chr == 0x302E -- tone mark - or chr == 0x302F then -- tone mark - --skip - else - josaprev[#josaprev + 1] = chr + -- ignore chars inside parentheses (KTS workshop 2013.11.09) + if ignoreparens and chr == 0x29 then -- right parenthesis + halt = halt + 1 + elseif ignoreparens and chr == 0x28 then -- left parenthesis + halt = halt - 1 + elseif xspcode[chr] + or inhibitxspcode[chr] + or prebreakpenalty[chr] + or postbreakpenalty[chr] + or chr == 0x302E -- tone mark + or chr == 0x302F then -- tone mark + --skip + elseif halt <= 0 then + josaprev[#josaprev + 1] = chr end elseif curr.id == hlistnode or curr.id == vlistnode then - josaprev = get_josaprevs(nodeslide(curr.head),josaprev) + josaprev = get_josaprevs(nodeslide(curr.head),josaprev,ignoreparens,halt) end if #josaprev == 3 then break end curr = curr.prev @@ -1307,20 +1301,21 @@ end local function korean_autojosa (head) for curr in traverse_id(glyphnode,head) do if has_attribute(curr,autojosaattr) and has_attribute(curr,finemathattr) then + local ignoreparens = has_attribute(curr,autojosaattr) > 1 and true or false local josaprev = {} - josaprev = get_josaprevs(curr.prev,josaprev) + josaprev = get_josaprevs(curr.prev,josaprev,ignoreparens) local josacode = get_josacode(josaprev) local thischar = get_unicode_char(curr) if thischar == 0xC774 then - if curr.next - and curr.next.id == glyphnode - and get_unicode_char(curr.next) == 0xB77C then - curr.char = josa_list[0xC774][josacode] - else - curr.char = josa_list[0xAC00][josacode] - end + if curr.next + and curr.next.id == glyphnode + and get_unicode_char(curr.next) == 0xB77C then + curr.char = josa_list[0xC774][josacode] + else + curr.char = josa_list[0xAC00][josacode] + end elseif thischar and josa_list[thischar] then - curr.char = josa_list[thischar][josacode] + curr.char = josa_list[thischar][josacode] end end if curr.char < 0 then remove_node(head,curr) end @@ -1330,11 +1325,11 @@ end ------------------------------ -- switch to hangul/hanja font ------------------------------ -local function hangulspaceskip (engfont, hfontid, nglue) +local function hangulspaceskip (engfont, hfontid, spec) local eng = engfont.parameters if not eng then return end - local spec = nglue.spec if not spec then return end + if spec.stretch_order ~= 0 or spec.shrink_order ~= 0 then return end local gsp, gst, gsh = spec.width, spec.stretch, spec.shrink local esp, est, esh = eng.space, eng.space_stretch, eng.space_shrink esp = esp and tex_round(esp) @@ -1351,51 +1346,71 @@ local function hangulspaceskip (engfont, hfontid, nglue) end 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 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 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 + local noinmath = true + for curr in traverse(head) do + if curr.id == mathnode then + if curr.subtype == 0 then + noinmath = false + else + noinmath = true end - for i=1,#ftable do - local fid = ftable[i] - if fid then - local c = get_font_char(fid, curr.char) - if c then - korid = true - curr.font = fid - -- adjust next glue by hangul font space - local nxt = curr.next - 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 - nxt.spec.stretch = st - nxt.spec.shrink = sh - end - end - --- charraise option charraise - local charraise = get_font_feature(fid, "charraise") - if charraise then - charraise = tex_sp(charraise) - curr.yoffset = curr.yoffset and (curr.yoffset + charraise) or charraise - end - --- - break - end - end + elseif noinmath and curr.id == glyphnode then + local eng = get_font_table(curr.font) + local engfontchar = nil + if eng and eng.encodingbytes and eng.encodingbytes == 2 -- exclude type1 + and hangulpunctuations[curr.char] + and has_attribute(curr, hangulpunctsattr) + and has_attribute(curr, finemathattr) == 1 + and not get_font_char(curr.font, 0xAC00) then -- exclude hangul font + else + engfontchar = get_font_char(curr.font, curr.char) end - if not korid then - warn("!Missing character: %s U+%04X", utf8char(curr.char),curr.char) + if curr.char and not engfontchar then + local korid = false + local hangul = has_attribute(curr, hangfntattr) + local hanja = has_attribute(curr, hanjfntattr) + local fallback = has_attribute(curr,fallbackfntattr) + local ftable = {hangul, hanja, fallback} + 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, fallback} end + end + for i=1,#ftable do + local fid = ftable[i] + if fid then + local c = get_font_char(fid, curr.char) + if c then + korid = true + curr.font = fid + -- adjust next glue by hangul font space + local nxt = curr.next + if eng + and nxt and nxt.id == gluenode + and nxt.subtype and nxt.subtype == 0 + and nxt.spec and nxt.spec.writable + and get_font_char(fid,32) then + local sp,st,sh = hangulspaceskip(eng, fid, nxt.spec) + if sp and st and sh then + local hg = copy_node(nxt.spec) + hg.width, hg.stretch, hg.shrink = sp, st, sh + nxt.spec = hg + end + end + --- charraise option charraise + local charraise = get_font_feature(fid, "charraise") + if charraise then + charraise = tex_sp(charraise) + curr.yoffset = curr.yoffset and (curr.yoffset + charraise) or charraise + end + --- + break + end + end + end + if not korid then + warn("!Missing character: %s U+%04X", utf8char(curr.char),curr.char) + end end end end @@ -1547,17 +1562,17 @@ local function reorderTM (head) 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 + 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 @@ -1615,31 +1630,31 @@ local function after_linebreak_dotemph (head) elseif curr.id == glyphnode then local attr = has_attribute(curr,dotemphattr) if attr and attr > 0 then - 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) + 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 @@ -1656,21 +1671,21 @@ local function after_linebreak_ruby (head) if attr then local ruby = rubynode[attr][1] if ruby then - if ruby.width < curr.width then - local rubyhead = ruby.head - local numofglues = nodecount(gluenode,rubyhead) - local extrawidth = (curr.width - ruby.width)/(numofglues + 1) - ruby.width = curr.width - extrawidth/2 - if numofglues > 0 then - ruby.head = spread_ruby_box(rubyhead,extrawidth) - end - else - local right = rubynode[attr].rightshift or 0 - ruby.width = curr.width + (ruby.width-curr.width+right)/2 - end - ruby.shift = -curr.height-rubynode[attr][2] - insert_after(head,curr,ruby) - insert_after(head,curr,get_kernnode(-ruby.width)) + if ruby.width < curr.width then + local rubyhead = ruby.head + local numofglues = nodecount(gluenode,rubyhead) + local extrawidth = (curr.width - ruby.width)/(numofglues + 1) + ruby.width = curr.width - extrawidth/2 + if numofglues > 0 then + ruby.head = spread_ruby_box(rubyhead,extrawidth) + end + else + local right = rubynode[attr].rightshift or 0 + ruby.width = curr.width + (ruby.width-curr.width+right)/2 + end + ruby.shift = -curr.height-rubynode[attr][2] + insert_after(head,curr,ruby) + insert_after(head,curr,get_kernnode(-ruby.width)) end rubynode[attr] = nil unset_attribute(curr,luakorubyattr) @@ -1709,14 +1724,14 @@ local function after_linebreak_underline(head,glueorder,glueset,gluesign,ulinenu elseif curr.id == whatsitnode and curr.subtype == whatsitspecial and curr.data then if stringfind(curr.data,"luako:ulinebegin=") then - ulinenum = tonumber(stringmatch(curr.data,"(%d+)")) - ulstart = curr + ulinenum = tonumber(stringmatch(curr.data,"(%d+)")) + ulstart = curr elseif ulstart and ulinenum - and stringfind(curr.data,'luako:ulineend') then - local wd = nodedimensions(glueset,gluesign,glueorder,ulstart,curr) - head = draw_underline(head,curr,wd,ulinenum,ulstart) - ulinebox[ulinenum] = nil - ulinenum = nil + and stringfind(curr.data,'luako:ulineend') then + local wd = nodedimensions(glueset,gluesign,glueorder,ulstart,curr) + head = draw_underline(head,curr,wd,ulinenum,ulstart) + ulinebox[ulinenum] = nil + ulinenum = nil end end if ulstart and ulinenum and curr == nodetail(head) then diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty index f419146c580..454fd857e1c 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty @@ -22,7 +22,7 @@ \expandafter\endinput \fi -\ProvidesPackage{luatexko}[2013/07/03 v1.2 Typesetting Korean with LuaLaTeX] +\ProvidesPackage{luatexko}[2013/11/22 v1.3 Typesetting Korean with LuaLaTeX] \RequirePackage{fontspec} \RequirePackage{luatexko-core} @@ -34,11 +34,11 @@ \fontspec_define_font_feature:n {#1} \keys_define:nn {fontspec} { - #1 .default:n = {#3} , - #1 / unknown .code:n = { - \fontspec_update_fontid:n {#2:##1} - \fontspec_update_featstr:n {#2=##1}#4 - } + #1 .default:n = {#3} , + #1 / unknown .code:n = { + \fontspec_update_fontid:n {#2:##1} + \fontspec_update_featstr:n {#2=##1}#4 + } } } @@ -61,7 +61,6 @@ \newhangulfontfeature{InterHangul}{interhangul}{0}{} \newhangulfontfeature{InterLatinCJK}{interlatincjk}{0}{} \newhangulfontfeature{PunctRaise}{punctraise}{0}{} -\newhangulfontfeature{QuoteRaise}{quoteraise}{0}{} \newhangulfontfeature{CharRaise}{charraise}{0}{} \newhangulfontfeature{Protrusion}{protrusion}{default}{\aftergroup\pdfprotrudechars\aftergroup\tw@} \newhangulfontfeature{Expansion}{expansion}{default}{\aftergroup\pdfadjustspacing\aftergroup\tw@} @@ -69,10 +68,13 @@ %% macros for Korean fonts \protected\def\setmainhangulfont{\newfontfamily\serifhangul@font} \protected\def\setmainhanjafont {\newfontfamily\serifhanja@font} +\protected\def\setmainfallbackfont{\newfontfamily\seriffallback@font} \protected\def\setsanshangulfont{\newfontfamily\sanshangul@font} \protected\def\setsanshanjafont {\newfontfamily\sanshanja@font} +\protected\def\setsansfallbackfont{\newfontfamily\sansfallback@font} \protected\def\setmonohangulfont{\newfontfamily\monohangul@font} \protected\def\setmonohanjafont {\newfontfamily\monohanja@font} +\protected\def\setmonofallbackfont{\newfontfamily\monofallback@font} \protected\def\newhangulfontfamily#1{% \protected\def#1{\expandafter\let\expandafter\hangul@font @@ -84,6 +86,11 @@ \csname luatexko@\string#1\endcsname \luatexko@hanja@selectfont}\expandafter\newfontfamily \csname luatexko@\string#1\endcsname} +\protected\def\newfallbackfontfamily#1{% + \protected\def#1{\expandafter\let\expandafter\fallback@font + \csname luatexko@\string#1\endcsname + \luatexko@fallback@selectfont}\expandafter\newfontfamily + \csname luatexko@\string#1\endcsname} \protected\def\newhangulfontface#1{% \protected\def#1{\expandafter\let\expandafter\hangul@font @@ -95,6 +102,11 @@ \csname luatexko@\string#1\endcsname \luatexko@hanja@selectfont}\expandafter\newfontface \csname luatexko@\string#1\endcsname} +\protected\def\newfallbackfontface#1{% + \protected\def#1{\expandafter\let\expandafter\fallback@font + \csname luatexko@\string#1\endcsname + \luatexko@fallback@selectfont}\expandafter\newfontface + \csname luatexko@\string#1\endcsname} \protected\def\hangulfontspec#1#{% \def\luatexko@fontspec@temp{#1}\hangulfontspec@} @@ -108,6 +120,12 @@ \expandafter\newfontfamily\expandafter\hanja@font\luatexko@fontspec@temp{#1}% \luatexko@hanja@selectfont\ignorespaces} \let\adhochanjafont\hanjafontspec +\protected\def\fallbackfontspec#1#{% + \def\luatexko@fontspec@temp{#1}\fallbackfontspec@} +\def\fallbackfontspec@#1{% + \expandafter\newfontfamily\expandafter\fallback@font\luatexko@fontspec@temp{#1}% + \luatexko@fallback@selectfont\ignorespaces} +\let\adhocfallbackfont\fallbackfontspec % add{hangul/hanja}fontfeature \protected\def\addhangulfontfeature#1{% @@ -128,6 +146,15 @@ \def\hanja@font{\fontfamily\luatexko@fontspec@temp \luatexko@orig@selectfont}\luatexko@hanja@selectfont \ignorespaces} \let\addhanjafontfeatures\addhanjafontfeature +\protected\def\addfallbackfontfeature#1{% + \begingroup + \check@fallback@family + \ifdefined\fallback@font\fallback@font\fi\addfontfeature{#1}\global + \let\luatexko@fontspec@temp\f@family + \endgroup + \def\fallback@font{\fontfamily\luatexko@fontspec@temp + \luatexko@orig@selectfont}\luatexko@fallback@selectfont \ignorespaces} +\let\addfallbackfontfeatures\addfallbackfontfeature % check hangul/hanja family \def\check@hangul@family{% @@ -144,14 +171,27 @@ \else \let\hanja@font\serifhanja@font \fi\fi\fi } +\def\check@fallback@family{% + \unless\ifdefined\fallback@font + \ifx\f@family\sfdefault \let\fallback@font\sansfallback@font + \else\ifx\f@family\ttdefault \let\fallback@font\monofallback@font + \else \let\fallback@font\seriffallback@font + \fi\fi\fi +} \let\luatexko@orig@selectfont\selectfont \protected\def\selectfont{\luatexko@orig@selectfont - \luatexko@hangul@selectfont\luatexko@hanja@selectfont} + \luatexko@hangul@selectfont + \luatexko@hanja@selectfont + \luatexko@fallback@selectfont +} % don't forget to redefine \normalfont \protected\edef\normalfont{\unexpanded{% - \let\hangul@font\luatexko@undefined\let\hanja@font\luatexko@undefined}% + \let\hangul@font\luatexko@undefined + \let\hanja@font\luatexko@undefined + \let\fallback@font\luatexko@undefined + }% \unexpanded\expandafter{\normalfont}} \let\reset@font\normalfont @@ -177,6 +217,7 @@ InterHangul=-0.04em, InterLatinCJK=0.125em, PunctRaise=-0.125em, + Ligatures=TeX, SlantedFont=*, SlantedFeatures={FakeSlant=0.2}, ItalicFont=*, ItalicFeatures={FakeSlant=0.2}, BoldSlantedFont=*Bold, BoldSlantedFeatures={FakeSlant=0.2}, @@ -185,6 +226,7 @@ \setsanshangulfont[ InterLatinCJK=0.125em, PunctRaise=-0.125em, + Ligatures=TeX, SlantedFont=*, SlantedFeatures={FakeSlant=0.2}, ItalicFont=*, ItalicFeatures={FakeSlant=0.2}, BoldSlantedFont=*Bold, BoldSlantedFeatures={FakeSlant=0.2}, @@ -254,7 +296,7 @@ \linespread{1.3888} \footnotesep=1.3888\footnotesep \skip\footins=1.3888\skip\footins plus6pt minus3pt - \directlua{luatexko.hangulmain = true} + \hangulpunctuations=1 \fi \endinput |