diff options
author | Karl Berry <karl@freefriends.org> | 2015-07-05 22:11:44 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-07-05 22:11:44 +0000 |
commit | 3ad37bd306bd38be21fe9082c369811140841075 (patch) | |
tree | 77565a4dc7ca4f67866507b4dbfed947c10d95fa /Master/texmf-dist/tex/luatex | |
parent | 4fd06219c5cd91090c46103f063bc227ea27aa84 (diff) |
luatexko
git-svn-id: svn://tug.org/texlive/trunk@37775 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
5 files changed, 675 insertions, 562 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty index ec3966dc026..e9b50ff2985 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-core.sty @@ -1,6 +1,7 @@ % luatexko-core.sty % % Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +% Soojin Nam <jsunam at gmail com> % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -16,7 +17,7 @@ \ifcsname ifpdf\endcsname\else \input ifpdf.sty \fi \catcode`@ = 11 \else - \ProvidesPackage{luatexko-core}[2015/05/10 v1.8 Typesetting Korean with LuaTeX] + \ProvidesPackage{luatexko-core}[2015/07/02 v1.9 Typesetting Korean with LuaTeX] \RequirePackage{luaotfload}[2013/05/23] \fi @@ -215,6 +216,39 @@ \maxdepth\z@ \luatexko@vertical} \fi +% horizontal box inside vertical typesetting +\protected\def\horizontal#1{% + \setbox\z@\vbox\bgroup + \ifnum\cjtypesetattr<\@ne + \unsetluatexattribute\cjtypesetattr + \spaceskip\fontdimen2\font + plus\fontdimen3\font + minus\fontdimen4\font + \fi + \hsize#1\relax + \everypar{}% + \leftskip\z@ + \rightskip\z@ + \parindent\z@ +} +\protected\def\endhorizontal{\egroup\luatexkounrotatebox\z@\box\z@} +\protected\def\luatexkounrotatebox#1{% + \leavevmode + \vbox to\wd#1\bgroup + \vfill + \hbox to\dimexpr\ht#1+\dp#1\bgroup + \wd#1\z@\ht#1\z@\dp#1\z@ + \luatexko@rotate@counterclockwise{\box#1}% + \hfill + \egroup + \egroup +} +\def\luatexko@rotate@counterclockwise#1{% + \ifpdf\pdfliteral{q 0 1 -1 0 0 0 cm}#1\pdfliteral{Q}% + \else \special{pdf:btrans rotate 90}#1\special{pdf:etrans}% + \fi +} + %% underline using post_linebreak_filter %% ulem doesn't work well with luatexko; %% especially linebreak does not occur inside cjk words. diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua index e705dc78bba..9cafe63c677 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-normalize.lua @@ -1,6 +1,7 @@ -- luatexko-normalize.lua -- --- Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +-- Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +-- Soojin Nam <jsunam at gmail com> -- -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.3c @@ -12,9 +13,9 @@ luatexbase.provides_module({ name = "luatexko-normalize", - version = 1.8, - date = "2015/04/13", - author = "Dohyun Kim", + version = 1.9, + date = "2015/07/02", + author = "Dohyun Kim, Soojin Nam", description = "Hangul normalization", license = "LPPL v1.3+", }) @@ -28,274 +29,276 @@ local jong = "[\225\134\168-\225\135\191\237\159\139-\237\159\187]" local ojong = "[\225\135\131-\225\135\191\237\159\139-\237\159\187]" local compathanja = "[\239\164\128-\239\168\139]" local chanjatohanja = { - [0xF900] = 0x8C48, - [0xF901] = 0x66F4, - [0xF902] = 0x8ECA, - [0xF903] = 0x8CC8, - [0xF904] = 0x6ED1, - [0xF905] = 0x4E32, - [0xF906] = 0x53E5, - [0xF907] = 0x9F9C, - [0xF908] = 0x9F9C, - [0xF909] = 0x5951, - [0xF90A] = 0x91D1, - [0xF90B] = 0x5587, - [0xF90C] = 0x5948, - [0xF90D] = 0x61F6, - [0xF90E] = 0x7669, - [0xF90F] = 0x7F85, - [0xF910] = 0x863F, - [0xF911] = 0x87BA, - [0xF912] = 0x88F8, - [0xF913] = 0x908F, - [0xF914] = 0x6A02, - [0xF915] = 0x6D1B, - [0xF916] = 0x70D9, - [0xF917] = 0x73DE, - [0xF918] = 0x843D, - [0xF919] = 0x916A, - [0xF91A] = 0x99F1, - [0xF91B] = 0x4E82, - [0xF91C] = 0x5375, - [0xF91D] = 0x6B04, - [0xF91E] = 0x721B, - [0xF91F] = 0x862D, - [0xF920] = 0x9E1E, - [0xF921] = 0x5D50, - [0xF922] = 0x6FEB, - [0xF923] = 0x85CD, - [0xF924] = 0x8964, - [0xF925] = 0x62C9, - [0xF926] = 0x81D8, - [0xF927] = 0x881F, - [0xF928] = 0x5ECA, - [0xF929] = 0x6717, - [0xF92A] = 0x6D6A, - [0xF92B] = 0x72FC, - [0xF92C] = 0x90DE, - [0xF92D] = 0x4F86, - [0xF92E] = 0x51B7, - [0xF92F] = 0x52DE, - [0xF930] = 0x64C4, - [0xF931] = 0x6AD3, - [0xF932] = 0x7210, - [0xF933] = 0x76E7, - [0xF934] = 0x8001, - [0xF935] = 0x8606, - [0xF936] = 0x865C, - [0xF937] = 0x8DEF, - [0xF938] = 0x9732, - [0xF939] = 0x9B6F, - [0xF93A] = 0x9DFA, - [0xF93B] = 0x788C, - [0xF93C] = 0x797F, - [0xF93D] = 0x7DA0, - [0xF93E] = 0x83C9, - [0xF93F] = 0x9304, - [0xF940] = 0x9E7F, - [0xF941] = 0x8AD6, - [0xF942] = 0x58DF, - [0xF943] = 0x5F04, - [0xF944] = 0x7C60, - [0xF945] = 0x807E, - [0xF946] = 0x7262, - [0xF947] = 0x78CA, - [0xF948] = 0x8CC2, - [0xF949] = 0x96F7, - [0xF94A] = 0x58D8, - [0xF94B] = 0x5C62, - [0xF94C] = 0x6A13, - [0xF94D] = 0x6DDA, - [0xF94E] = 0x6F0F, - [0xF94F] = 0x7D2F, - [0xF950] = 0x7E37, - [0xF951] = 0x964B, - [0xF952] = 0x52D2, - [0xF953] = 0x808B, - [0xF954] = 0x51DC, - [0xF955] = 0x51CC, - [0xF956] = 0x7A1C, - [0xF957] = 0x7DBE, - [0xF958] = 0x83F1, - [0xF959] = 0x9675, - [0xF95A] = 0x8B80, - [0xF95B] = 0x62CF, - [0xF95C] = 0x6A02, - [0xF95D] = 0x8AFE, - [0xF95E] = 0x4E39, - [0xF95F] = 0x5BE7, - [0xF960] = 0x6012, - [0xF961] = 0x7387, - [0xF962] = 0x7570, - [0xF963] = 0x5317, - [0xF964] = 0x78FB, - [0xF965] = 0x4FBF, - [0xF966] = 0x5FA9, - [0xF967] = 0x4E0D, - [0xF968] = 0x6CCC, - [0xF969] = 0x6578, - [0xF96A] = 0x7D22, - [0xF96B] = 0x53C3, - [0xF96C] = 0x585E, - [0xF96D] = 0x7701, - [0xF96E] = 0x8449, - [0xF96F] = 0x8AAA, - [0xF970] = 0x6BBA, - [0xF971] = 0x8FB0, - [0xF972] = 0x6C88, - [0xF973] = 0x62FE, - [0xF974] = 0x82E5, - [0xF975] = 0x63A0, - [0xF976] = 0x7565, - [0xF977] = 0x4EAE, - [0xF978] = 0x5169, - [0xF979] = 0x51C9, - [0xF97A] = 0x6881, - [0xF97B] = 0x7CE7, - [0xF97C] = 0x826F, - [0xF97D] = 0x8AD2, - [0xF97E] = 0x91CF, - [0xF97F] = 0x52F5, - [0xF980] = 0x5442, - [0xF981] = 0x5973, - [0xF982] = 0x5EEC, - [0xF983] = 0x65C5, - [0xF984] = 0x6FFE, - [0xF985] = 0x792A, - [0xF986] = 0x95AD, - [0xF987] = 0x9A6A, - [0xF988] = 0x9E97, - [0xF989] = 0x9ECE, - [0xF98A] = 0x529B, - [0xF98B] = 0x66C6, - [0xF98C] = 0x6B77, - [0xF98D] = 0x8F62, - [0xF98E] = 0x5E74, - [0xF98F] = 0x6190, - [0xF990] = 0x6200, - [0xF991] = 0x649A, - [0xF992] = 0x6F23, - [0xF993] = 0x7149, - [0xF994] = 0x7489, - [0xF995] = 0x79CA, - [0xF996] = 0x7DF4, - [0xF997] = 0x806F, - [0xF998] = 0x8F26, - [0xF999] = 0x84EE, - [0xF99A] = 0x9023, - [0xF99B] = 0x934A, - [0xF99C] = 0x5217, - [0xF99D] = 0x52A3, - [0xF99E] = 0x54BD, - [0xF99F] = 0x70C8, - [0xF9A0] = 0x88C2, - [0xF9A1] = 0x8AAA, - [0xF9A2] = 0x5EC9, - [0xF9A3] = 0x5FF5, - [0xF9A4] = 0x637B, - [0xF9A5] = 0x6BAE, - [0xF9A6] = 0x7C3E, - [0xF9A7] = 0x7375, - [0xF9A8] = 0x4EE4, - [0xF9A9] = 0x56F9, - [0xF9AA] = 0x5BE7, - [0xF9AB] = 0x5DBA, - [0xF9AC] = 0x601C, - [0xF9AD] = 0x73B2, - [0xF9AE] = 0x7469, - [0xF9AF] = 0x7F9A, - [0xF9B0] = 0x8046, - [0xF9B1] = 0x9234, - [0xF9B2] = 0x96F6, - [0xF9B3] = 0x9748, - [0xF9B4] = 0x9818, - [0xF9B5] = 0x4F8B, - [0xF9B6] = 0x79AE, - [0xF9B7] = 0x91B4, - [0xF9B8] = 0x96B7, - [0xF9B9] = 0x60E1, - [0xF9BA] = 0x4E86, - [0xF9BB] = 0x50DA, - [0xF9BC] = 0x5BEE, - [0xF9BD] = 0x5C3F, - [0xF9BE] = 0x6599, - [0xF9BF] = 0x6A02, - [0xF9C0] = 0x71CE, - [0xF9C1] = 0x7642, - [0xF9C2] = 0x84FC, - [0xF9C3] = 0x907C, - [0xF9C4] = 0x9F8D, - [0xF9C5] = 0x6688, - [0xF9C6] = 0x962E, - [0xF9C7] = 0x5289, - [0xF9C8] = 0x677B, - [0xF9C9] = 0x67F3, - [0xF9CA] = 0x6D41, - [0xF9CB] = 0x6E9C, - [0xF9CC] = 0x7409, - [0xF9CD] = 0x7559, - [0xF9CE] = 0x786B, - [0xF9CF] = 0x7D10, - [0xF9D0] = 0x985E, - [0xF9D1] = 0x516D, - [0xF9D2] = 0x622E, - [0xF9D3] = 0x9678, - [0xF9D4] = 0x502B, - [0xF9D5] = 0x5D19, - [0xF9D6] = 0x6DEA, - [0xF9D7] = 0x8F2A, - [0xF9D8] = 0x5F8B, - [0xF9D9] = 0x6144, - [0xF9DA] = 0x6817, - [0xF9DB] = 0x7387, - [0xF9DC] = 0x9686, - [0xF9DD] = 0x5229, - [0xF9DE] = 0x540F, - [0xF9DF] = 0x5C65, - [0xF9E0] = 0x6613, - [0xF9E1] = 0x674E, - [0xF9E2] = 0x68A8, - [0xF9E3] = 0x6CE5, - [0xF9E4] = 0x7406, - [0xF9E5] = 0x75E2, - [0xF9E6] = 0x7F79, - [0xF9E7] = 0x88CF, - [0xF9E8] = 0x88E1, - [0xF9E9] = 0x91CC, - [0xF9EA] = 0x96E2, - [0xF9EB] = 0x533F, - [0xF9EC] = 0x6EBA, - [0xF9ED] = 0x541D, - [0xF9EE] = 0x71D0, - [0xF9EF] = 0x7498, - [0xF9F0] = 0x85FA, - [0xF9F1] = 0x96A3, - [0xF9F2] = 0x9C57, - [0xF9F3] = 0x9E9F, - [0xF9F4] = 0x6797, - [0xF9F5] = 0x6DCB, - [0xF9F6] = 0x81E8, - [0xF9F7] = 0x7ACB, - [0xF9F8] = 0x7B20, - [0xF9F9] = 0x7C92, - [0xF9FA] = 0x72C0, - [0xF9FB] = 0x7099, - [0xF9FC] = 0x8B58, - [0xF9FD] = 0x4EC0, - [0xF9FE] = 0x8336, - [0xF9FF] = 0x523A, - [0xFA00] = 0x5207, - [0xFA01] = 0x5EA6, - [0xFA02] = 0x62D3, - [0xFA03] = 0x7CD6, - [0xFA04] = 0x5B85, - [0xFA05] = 0x6D1E, - [0xFA06] = 0x66B4, - [0xFA07] = 0x8F3B, - [0xFA08] = 0x884C, - [0xFA09] = 0x964D, - [0xFA0A] = 0x898B, - [0xFA0B] = 0x5ED3, + [0xF900] = {0x8C48, 0xFE00}, + [0xF901] = {0x66F4, 0xFE00}, + [0xF902] = {0x8ECA, 0xFE00}, + [0xF903] = {0x8CC8, 0xFE00}, + [0xF904] = {0x6ED1, 0xFE00}, + [0xF905] = {0x4E32, 0xFE00}, + [0xF906] = {0x53E5, 0xFE00}, + [0xF907] = {0x9F9C, 0xFE00}, + [0xF908] = {0x9F9C, 0xFE01}, + [0xF909] = {0x5951, 0xFE00}, + [0xF90A] = {0x91D1, 0xFE00}, + [0xF90B] = {0x5587, 0xFE00}, + [0xF90C] = {0x5948, 0xFE00}, + [0xF90D] = {0x61F6, 0xFE00}, + [0xF90E] = {0x7669, 0xFE00}, + [0xF90F] = {0x7F85, 0xFE00}, + [0xF910] = {0x863F, 0xFE00}, + [0xF911] = {0x87BA, 0xFE00}, + [0xF912] = {0x88F8, 0xFE00}, + [0xF913] = {0x908F, 0xFE00}, + [0xF914] = {0x6A02, 0xFE00}, + [0xF915] = {0x6D1B, 0xFE00}, + [0xF916] = {0x70D9, 0xFE00}, + [0xF917] = {0x73DE, 0xFE00}, + [0xF918] = {0x843D, 0xFE00}, + [0xF919] = {0x916A, 0xFE00}, + [0xF91A] = {0x99F1, 0xFE00}, + [0xF91B] = {0x4E82, 0xFE00}, + [0xF91C] = {0x5375, 0xFE00}, + [0xF91D] = {0x6B04, 0xFE00}, + [0xF91E] = {0x721B, 0xFE00}, + [0xF91F] = {0x862D, 0xFE00}, + [0xF920] = {0x9E1E, 0xFE00}, + [0xF921] = {0x5D50, 0xFE00}, + [0xF922] = {0x6FEB, 0xFE00}, + [0xF923] = {0x85CD, 0xFE00}, + [0xF924] = {0x8964, 0xFE00}, + [0xF925] = {0x62C9, 0xFE00}, + [0xF926] = {0x81D8, 0xFE00}, + [0xF927] = {0x881F, 0xFE00}, + [0xF928] = {0x5ECA, 0xFE00}, + [0xF929] = {0x6717, 0xFE00}, + [0xF92A] = {0x6D6A, 0xFE00}, + [0xF92B] = {0x72FC, 0xFE00}, + [0xF92C] = {0x90CE, 0xFE00}, + [0xF92D] = {0x4F86, 0xFE00}, + [0xF92E] = {0x51B7, 0xFE00}, + [0xF92F] = {0x52DE, 0xFE00}, + [0xF930] = {0x64C4, 0xFE00}, + [0xF931] = {0x6AD3, 0xFE00}, + [0xF932] = {0x7210, 0xFE00}, + [0xF933] = {0x76E7, 0xFE00}, + [0xF934] = {0x8001, 0xFE00}, + [0xF935] = {0x8606, 0xFE00}, + [0xF936] = {0x865C, 0xFE00}, + [0xF937] = {0x8DEF, 0xFE00}, + [0xF938] = {0x9732, 0xFE00}, + [0xF939] = {0x9B6F, 0xFE00}, + [0xF93A] = {0x9DFA, 0xFE00}, + [0xF93B] = {0x788C, 0xFE00}, + [0xF93C] = {0x797F, 0xFE00}, + [0xF93D] = {0x7DA0, 0xFE00}, + [0xF93E] = {0x83C9, 0xFE00}, + [0xF93F] = {0x9304, 0xFE00}, + [0xF940] = {0x9E7F, 0xFE00}, + [0xF941] = {0x8AD6, 0xFE00}, + [0xF942] = {0x58DF, 0xFE00}, + [0xF943] = {0x5F04, 0xFE00}, + [0xF944] = {0x7C60, 0xFE00}, + [0xF945] = {0x807E, 0xFE00}, + [0xF946] = {0x7262, 0xFE00}, + [0xF947] = {0x78CA, 0xFE00}, + [0xF948] = {0x8CC2, 0xFE00}, + [0xF949] = {0x96F7, 0xFE00}, + [0xF94A] = {0x58D8, 0xFE00}, + [0xF94B] = {0x5C62, 0xFE00}, + [0xF94C] = {0x6A13, 0xFE00}, + [0xF94D] = {0x6DDA, 0xFE00}, + [0xF94E] = {0x6F0F, 0xFE00}, + [0xF94F] = {0x7D2F, 0xFE00}, + [0xF950] = {0x7E37, 0xFE00}, + [0xF951] = {0x964B, 0xFE00}, + [0xF952] = {0x52D2, 0xFE00}, + [0xF953] = {0x808B, 0xFE00}, + [0xF954] = {0x51DC, 0xFE00}, + [0xF955] = {0x51CC, 0xFE00}, + [0xF956] = {0x7A1C, 0xFE00}, + [0xF957] = {0x7DBE, 0xFE00}, + [0xF958] = {0x83F1, 0xFE00}, + [0xF959] = {0x9675, 0xFE00}, + [0xF95A] = {0x8B80, 0xFE00}, + [0xF95B] = {0x62CF, 0xFE00}, + [0xF95C] = {0x6A02, 0xFE01}, + [0xF95D] = {0x8AFE, 0xFE00}, + [0xF95E] = {0x4E39, 0xFE00}, + [0xF95F] = {0x5BE7, 0xFE00}, + [0xF960] = {0x6012, 0xFE00}, + [0xF961] = {0x7387, 0xFE00}, + [0xF962] = {0x7570, 0xFE00}, + [0xF963] = {0x5317, 0xFE00}, + [0xF964] = {0x78FB, 0xFE00}, + [0xF965] = {0x4FBF, 0xFE00}, + [0xF966] = {0x5FA9, 0xFE00}, + [0xF967] = {0x4E0D, 0xFE00}, + [0xF968] = {0x6CCC, 0xFE00}, + [0xF969] = {0x6578, 0xFE00}, + [0xF96A] = {0x7D22, 0xFE00}, + [0xF96B] = {0x53C3, 0xFE00}, + [0xF96C] = {0x585E, 0xFE00}, + [0xF96D] = {0x7701, 0xFE00}, + [0xF96E] = {0x8449, 0xFE00}, + [0xF96F] = {0x8AAA, 0xFE00}, + [0xF970] = {0x6BBA, 0xFE00}, + [0xF971] = {0x8FB0, 0xFE00}, + [0xF972] = {0x6C88, 0xFE00}, + [0xF973] = {0x62FE, 0xFE00}, + [0xF974] = {0x82E5, 0xFE00}, + [0xF975] = {0x63A0, 0xFE00}, + [0xF976] = {0x7565, 0xFE00}, + [0xF977] = {0x4EAE, 0xFE00}, + [0xF978] = {0x5169, 0xFE00}, + [0xF979] = {0x51C9, 0xFE00}, + [0xF97A] = {0x6881, 0xFE00}, + [0xF97B] = {0x7CE7, 0xFE00}, + [0xF97C] = {0x826F, 0xFE00}, + [0xF97D] = {0x8AD2, 0xFE00}, + [0xF97E] = {0x91CF, 0xFE00}, + [0xF97F] = {0x52F5, 0xFE00}, + [0xF980] = {0x5442, 0xFE00}, + [0xF981] = {0x5973, 0xFE00}, + [0xF982] = {0x5EEC, 0xFE00}, + [0xF983] = {0x65C5, 0xFE00}, + [0xF984] = {0x6FFE, 0xFE00}, + [0xF985] = {0x792A, 0xFE00}, + [0xF986] = {0x95AD, 0xFE00}, + [0xF987] = {0x9A6A, 0xFE00}, + [0xF988] = {0x9E97, 0xFE00}, + [0xF989] = {0x9ECE, 0xFE00}, + [0xF98A] = {0x529B, 0xFE00}, + [0xF98B] = {0x66C6, 0xFE00}, + [0xF98C] = {0x6B77, 0xFE00}, + [0xF98D] = {0x8F62, 0xFE00}, + [0xF98E] = {0x5E74, 0xFE00}, + [0xF98F] = {0x6190, 0xFE00}, + [0xF990] = {0x6200, 0xFE00}, + [0xF991] = {0x649A, 0xFE00}, + [0xF992] = {0x6F23, 0xFE00}, + [0xF993] = {0x7149, 0xFE00}, + [0xF994] = {0x7489, 0xFE00}, + [0xF995] = {0x79CA, 0xFE00}, + [0xF996] = {0x7DF4, 0xFE00}, + [0xF997] = {0x806F, 0xFE00}, + [0xF998] = {0x8F26, 0xFE00}, + [0xF999] = {0x84EE, 0xFE00}, + [0xF99A] = {0x9023, 0xFE00}, + [0xF99B] = {0x934A, 0xFE00}, + [0xF99C] = {0x5217, 0xFE00}, + [0xF99D] = {0x52A3, 0xFE00}, + [0xF99E] = {0x54BD, 0xFE00}, + [0xF99F] = {0x70C8, 0xFE00}, + [0xF9A0] = {0x88C2, 0xFE00}, + [0xF9A1] = {0x8AAA, 0xFE01}, + [0xF9A2] = {0x5EC9, 0xFE00}, + [0xF9A3] = {0x5FF5, 0xFE00}, + [0xF9A4] = {0x637B, 0xFE00}, + [0xF9A5] = {0x6BAE, 0xFE00}, + [0xF9A6] = {0x7C3E, 0xFE00}, + [0xF9A7] = {0x7375, 0xFE00}, + [0xF9A8] = {0x4EE4, 0xFE00}, + [0xF9A9] = {0x56F9, 0xFE00}, + [0xF9AA] = {0x5BE7, 0xFE01}, + [0xF9AB] = {0x5DBA, 0xFE00}, + [0xF9AC] = {0x601C, 0xFE00}, + [0xF9AD] = {0x73B2, 0xFE00}, + [0xF9AE] = {0x7469, 0xFE00}, + [0xF9AF] = {0x7F9A, 0xFE00}, + [0xF9B0] = {0x8046, 0xFE00}, + [0xF9B1] = {0x9234, 0xFE00}, + [0xF9B2] = {0x96F6, 0xFE00}, + [0xF9B3] = {0x9748, 0xFE00}, + [0xF9B4] = {0x9818, 0xFE00}, + [0xF9B5] = {0x4F8B, 0xFE00}, + [0xF9B6] = {0x79AE, 0xFE00}, + [0xF9B7] = {0x91B4, 0xFE00}, + [0xF9B8] = {0x96B8, 0xFE00}, + [0xF9B9] = {0x60E1, 0xFE00}, + [0xF9BA] = {0x4E86, 0xFE00}, + [0xF9BB] = {0x50DA, 0xFE00}, + [0xF9BC] = {0x5BEE, 0xFE00}, + [0xF9BD] = {0x5C3F, 0xFE00}, + [0xF9BE] = {0x6599, 0xFE00}, + [0xF9BF] = {0x6A02, 0xFE02}, + [0xF9C0] = {0x71CE, 0xFE00}, + [0xF9C1] = {0x7642, 0xFE00}, + [0xF9C2] = {0x84FC, 0xFE00}, + [0xF9C3] = {0x907C, 0xFE00}, + [0xF9C4] = {0x9F8D, 0xFE00}, + [0xF9C5] = {0x6688, 0xFE00}, + [0xF9C6] = {0x962E, 0xFE00}, + [0xF9C7] = {0x5289, 0xFE00}, + [0xF9C8] = {0x677B, 0xFE00}, + [0xF9C9] = {0x67F3, 0xFE00}, + [0xF9CA] = {0x6D41, 0xFE00}, + [0xF9CB] = {0x6E9C, 0xFE00}, + [0xF9CC] = {0x7409, 0xFE00}, + [0xF9CD] = {0x7559, 0xFE00}, + [0xF9CE] = {0x786B, 0xFE00}, + [0xF9CF] = {0x7D10, 0xFE00}, + [0xF9D0] = {0x985E, 0xFE00}, + [0xF9D1] = {0x516D, 0xFE00}, + [0xF9D2] = {0x622E, 0xFE00}, + [0xF9D3] = {0x9678, 0xFE00}, + [0xF9D4] = {0x502B, 0xFE00}, + [0xF9D5] = {0x5D19, 0xFE00}, + [0xF9D6] = {0x6DEA, 0xFE00}, + [0xF9D7] = {0x8F2A, 0xFE00}, + [0xF9D8] = {0x5F8B, 0xFE00}, + [0xF9D9] = {0x6144, 0xFE00}, + [0xF9DA] = {0x6817, 0xFE00}, + [0xF9DB] = {0x7387, 0xFE01}, + [0xF9DC] = {0x9686, 0xFE00}, + [0xF9DD] = {0x5229, 0xFE00}, + [0xF9DE] = {0x540F, 0xFE00}, + [0xF9DF] = {0x5C65, 0xFE00}, + [0xF9E0] = {0x6613, 0xFE00}, + [0xF9E1] = {0x674E, 0xFE00}, + [0xF9E2] = {0x68A8, 0xFE00}, + [0xF9E3] = {0x6CE5, 0xFE00}, + [0xF9E4] = {0x7406, 0xFE00}, + [0xF9E5] = {0x75E2, 0xFE00}, + [0xF9E6] = {0x7F79, 0xFE00}, + [0xF9E7] = {0x88CF, 0xFE00}, + [0xF9E8] = {0x88E1, 0xFE00}, + [0xF9E9] = {0x91CC, 0xFE00}, + [0xF9EA] = {0x96E2, 0xFE00}, + [0xF9EB] = {0x533F, 0xFE00}, + [0xF9EC] = {0x6EBA, 0xFE00}, + [0xF9ED] = {0x541D, 0xFE00}, + [0xF9EE] = {0x71D0, 0xFE00}, + [0xF9EF] = {0x7498, 0xFE00}, + [0xF9F0] = {0x85FA, 0xFE00}, + [0xF9F1] = {0x96A3, 0xFE00}, + [0xF9F2] = {0x9C57, 0xFE00}, + [0xF9F3] = {0x9E9F, 0xFE00}, + [0xF9F4] = {0x6797, 0xFE00}, + [0xF9F5] = {0x6DCB, 0xFE00}, + [0xF9F6] = {0x81E8, 0xFE00}, + [0xF9F7] = {0x7ACB, 0xFE00}, + [0xF9F8] = {0x7B20, 0xFE00}, + [0xF9F9] = {0x7C92, 0xFE00}, + [0xF9FA] = {0x72C0, 0xFE00}, + [0xF9FB] = {0x7099, 0xFE00}, + [0xF9FC] = {0x8B58, 0xFE00}, + [0xF9FD] = {0x4EC0, 0xFE00}, + [0xF9FE] = {0x8336, 0xFE00}, + [0xF9FF] = {0x523A, 0xFE00}, + [0xFA00] = {0x5207, 0xFE00}, + [0xFA01] = {0x5EA6, 0xFE00}, + [0xFA02] = {0x62D3, 0xFE00}, + [0xFA03] = {0x7CD6, 0xFE00}, + [0xFA04] = {0x5B85, 0xFE00}, + [0xFA05] = {0x6D1E, 0xFE00}, + [0xFA06] = {0x66B4, 0xFE00}, + [0xFA07] = {0x8F3B, 0xFE00}, + [0xFA08] = {0x884C, 0xFE00}, + [0xFA09] = {0x964D, 0xFE00}, + [0xFA0A] = {0x898B, 0xFE00}, + [0xFA0B] = {0x5ED3, 0xFE00}, + [0xFA2E] = {0x90DE, 0xFE00}, + [0xFA2F] = {0x96B7, 0xFE00}, } local jamotocjamo = { ccho = { @@ -436,7 +439,7 @@ end local function hanjanormalize(c) local hanja = chanjatohanja[byte(c)] - hanja = hanja and char(hanja) + hanja = hanja and char(hanja[1], hanja[2]) return hanja end diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua index bacaf12c6d1..0a795c42350 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua @@ -1,6 +1,7 @@ -- luatexko-uhc2utf8.lua -- --- Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +-- Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +-- Soojin Nam <jsunam at gmail com> -- -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.3c @@ -12,9 +13,9 @@ luatexbase.provides_module({ name = "luatexko-uhc2utf8", - version = 1.8, - date = "2015/04/13", - author = "Dohyun Kim", + version = 1.9, + date = "2015/07/02", + author = "Dohyun Kim, Soojin Nam", description = "UHC (CP949) input encoding", license = "LPPL v1.3+", }) diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua index c17f2b8ef83..9a076f151c0 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua @@ -1,6 +1,7 @@ -- luatexko.lua -- --- Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +-- Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +-- Soojin Nam <jsunam at gmail com> -- -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.3c @@ -12,10 +13,10 @@ local err,warn,info,log = luatexbase.provides_module({ name = 'luatexko', - date = '2015/05/10', - version = 1.8, + date = '2015/07/02', + version = 1.9, description = 'Korean linebreaking and font-switching', - author = 'Dohyun Kim', + author = 'Dohyun Kim, Soojin Nam', license = 'LPPL v1.3+', }) @@ -28,12 +29,8 @@ luatexko.rubynode = rubynode luatexko.ulinebox = ulinebox local stringbyte = string.byte -local stringgsub = string.gsub local stringchar = string.char -local stringfind = string.find -local stringmatch = string.match local stringformat = string.format -local string_sub = string.sub local mathfloor = math.floor local tex_round = tex.round local tex_sp = tex.sp @@ -94,15 +91,9 @@ local d_remove_node = nodedirect.remove local d_nodenew = nodedirect.new local d_nodecount = nodedirect.count local d_end_of_math = nodedirect.end_of_math -local d_nodeslide = nodedirect.slide local d_nodetail = nodedirect.tail local d_nodedimensions = nodedirect.dimensions - -local d_new_glue = d_nodenew(gluenode) -local d_new_glue_spec = d_nodenew(gluespecnode) -local d_new_penalty = d_nodenew(penaltynode) -local d_new_kern = d_nodenew(kernnode,1) -local d_new_rule = d_nodenew(rulenode) +local d_nodefree = nodedirect.free local emsize = 655360 @@ -473,30 +464,35 @@ local josa_code = { -- else 2 } -local function d_get_gluenode (w,st,sh) - local g = d_copy_node(d_new_glue) - local s = d_copy_node(d_new_glue_spec) - d_setfield(s,"width", w or 0) - d_setfield(s,"stretch", st or 0) - d_setfield(s,"shrink", sh or 0) - d_setfield(g,"spec", s) +local function d_get_gluespec (w, st, sh) + local s = d_nodenew(gluespecnode) + d_setfield(s, "width", w or 0) + d_setfield(s, "stretch", st or 0) + d_setfield(s, "shrink", sh or 0) + return s +end + +local function d_get_gluenode (...) + local g = d_nodenew(gluenode) + local s = d_get_gluespec(...) + d_setfield(g, "spec", s) return g end local function d_get_penaltynode (n) - local p = d_copy_node(d_new_penalty) + local p = d_nodenew(penaltynode) d_setfield(p,"penalty", n or 0) return p end local function d_get_kernnode (n) - local k = d_copy_node(d_new_kern) + local k = d_nodenew(kernnode,1) d_setfield(k,"kern", n or 0) return k end local function d_get_rulenode (w,h,d) - local r = d_copy_node(d_new_rule) + local r = d_nodenew(rulenode) d_setfield(r,"width", w or 0) d_setfield(r,"height", h or 0) d_setfield(r,"depth", d or 0) @@ -620,7 +616,7 @@ local function d_get_unicode_char(curr) if uni < 0xE000 or (uni > 0xF8FF and uni < 0xF0000) then -- no pua local uchr = get_font_char(d_getfont(curr), uni) uchr = uchr and uchr.tounicode - uchr = uchr and string_sub(uchr,1,4) -- seems ok for old hangul + uchr = uchr and uchr:sub(1,4) -- seems ok for old hangul if uchr then return tonumber(uchr,16) end end local uatt = d_has_attribute(curr, luakounicodeattr) @@ -647,12 +643,12 @@ local function d_get_hlist_char_first (hlist) end local function d_get_hlist_char_last (hlist,prevchar,prevfont) - local curr = d_nodeslide(d_getlist(hlist)) + local curr = d_nodetail(d_getlist(hlist)) while curr do local currid = d_getid(curr) if currid == glyphnode then local c,f = d_get_unicode_char(curr), d_getfont(curr) - if c then return c,f end + if c and not is_unicode_vs(c) then return c,f end -- bypass VS elseif currid == hlistnode or currid == vlistnode then local c,f = d_get_hlist_char_last(curr) if c then return c,f end @@ -820,20 +816,25 @@ local function cjk_insert_nodes(head,curr,currchar,currfont,prevchar,prevfont,wa end local function cjk_spacing_linebreak (head) - local prevchar,prevfont,was_penalty = nil,nil,nil + local prevchar,prevfont,was_penalty,prevfine = nil,nil,nil,nil local curr = head while curr do - if d_has_attribute(curr,finemathattr) then + local currfine = d_has_attribute(curr,finemathattr) + if currfine then local currid = d_getid(curr) if currid == gluenode then - prevchar,prevfont = nil,nil + prevchar,prevfont,prevfine = nil,nil,nil d_unset_attribute(curr,finemathattr) elseif currid == glyphnode then local currfont = d_getfont(curr) emsize = get_font_emsize(currfont) local uni = d_get_unicode_char(curr) - if uni then + if uni and not is_unicode_vs(uni) then -- bypass VS + if prevfine and prevfine > 0 and currfine == 0 then + d_set_attribute(curr, finemathattr, 1) + end prevchar,prevfont = cjk_insert_nodes(head,curr,uni,currfont,prevchar,prevfont,was_penalty) + prevfine = currfine end d_unset_attribute(curr,finemathattr) elseif currid == mathnode then @@ -846,7 +847,7 @@ local function cjk_spacing_linebreak (head) cjk_insert_nodes(head,curr,currchar,nil,prevchar,prevfont,was_penalty) curr = d_end_of_math(curr) if not curr then break end - prevchar,prevfont = currchar,nil + prevchar,prevfont,prevfine = currchar,nil,nil end d_unset_attribute(curr,finemathattr) elseif currid == hlistnode or currid == vlistnode then @@ -855,11 +856,17 @@ local function cjk_spacing_linebreak (head) cjk_insert_nodes(head,curr,firstchr,firstfid,prevchar,prevfont,was_penalty) end prevchar,prevfont = d_get_hlist_char_last(curr,prevchar,prevfont) + if d_getlist(curr) then prevfine = nil end -- empty box preserves prevfine. d_unset_attribute(curr,finemathattr) end was_penalty = currid == penaltynode else - prevchar,prevfont = 0,nil -- treat \verb as latin character. + if d_getid(curr) == glyphnode and prevfine and prevfine > 0 then -- fitst glyph in verb + d_set_attribute(curr, finemathattr, 1) + cjk_insert_nodes(head,curr,0,nil,prevchar,prevfont,was_penalty) + d_unset_attribute(curr,finemathattr) + end + prevchar,prevfont,prevfine = 0,nil,nil -- treat \verb as latin character. end curr = d_nodenext(curr) end @@ -888,8 +895,9 @@ local function remove_cj_spaceskip (head) prv = d_nodeprev(prv) end if prvid == glyphnode then - prevclass = get_cjk_class(d_get_unicode_char(prv), cjattr) prevchar, prevfont = d_getchar(prv), d_getfont(prv) + if is_unicode_vs(prevchar) then prv = d_nodeprev(prv) end -- bypass VS + prevclass = get_cjk_class(d_get_unicode_char(prv), cjattr) end end if nxtid == glyphnode then @@ -901,6 +909,8 @@ local function remove_cj_spaceskip (head) local subtype = currsubtype if subtype == 13 then -- do not touch on xspaceskip for now d_remove_node(head,curr) + d_nodefree(curr) + curr = nxt elseif subtype == 0 then -- before \text?? spaceskip is replaced by glue type 0 local spec = d_getfield(curr,"spec") local csp = spec and d_getfield(spec,"width") @@ -920,6 +930,8 @@ local function remove_cj_spaceskip (head) end if sp == csp and st == cst and sh == csh then d_remove_node(head,curr) + d_nodefree(curr) + curr = nxt end end end @@ -935,63 +947,104 @@ end local function compress_fullwidth_punctuations (head) for curr in d_traverse_id(glyphnode,head) do local currfont, currchar = d_getfont(curr), d_getchar(curr) - if get_font_feature(currfont,'halt') or get_font_feature(currfont,'vhal') then - else - local uni = d_get_unicode_char(curr) - local class = uni and get_cjk_class(uni, d_has_attribute(curr, cjtypesetattr)) - local chr = get_font_char(currfont, currchar) - if chr and class and class >= 1 and class <= 4 then - local width = d_getfield(curr,"width") or 655360 - emsize = get_font_emsize(currfont) - local ensize = emsize/2 - local oneoften = emsize/10 - local bbox = get_char_boundingbox(currfont, currchar) - bbox = bbox or {ensize-oneoften, ensize-oneoften, ensize+oneoften, ensize+oneoften} - if class == 2 or class == 4 then - local wd - if get_font_feature(currfont,'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 + local cjtype = d_has_attribute(curr, cjtypesetattr) + local uni = d_get_unicode_char(curr) + local class = uni and get_cjk_class(uni, cjtype or 0) -- include U+201C ... + local chr = get_font_char(currfont, currchar) + if chr and class and class >= 1 and class <= 4 then + local halt_on = get_font_feature(currfont,'halt') or get_font_feature(currfont,'vhal') + local width = d_getfield(curr,"width") or 655360 + emsize = get_font_emsize(currfont) + local ensize = emsize/2 + local oneoften = emsize/10 + local bbox = get_char_boundingbox(currfont, currchar) + bbox = bbox or {ensize-oneoften, ensize-oneoften, ensize+oneoften, ensize+oneoften} + if class == 2 or class == 4 then + local wd + if get_font_feature(currfont,'vertical') then + wd = ensize<width and ensize-width or 0 + else + wd = (bbox[3] < ensize) and ensize-width or bbox[3]-width+oneoften + if not cjtype and wd > 0 then wd = 0 end + end + if chr.right_protruding then + -- kern is a breakpoint if followed by a glue + if not halt_on then d_insert_after(head, curr, d_get_kernnode(wd)) - else - d_insert_after(head, curr, d_get_rulenode(wd)) end - elseif class == 1 then - local wd - if get_font_feature(currfont,'vertical') then - wd = ensize<width and ensize-width or 0 - else - wd = (width-bbox[1] < ensize) and ensize-width or -bbox[1]+oneoften + else + if halt_on then + -- gluph halt_kern glue -> glyph halt_kern rule glue (kern is a breakpoint if followed by a glue) + local nn = d_nodenext(curr) + if nn and d_getid(nn) == kernnode then + wd = 0 + curr = nn + end end - if chr.left_protruding then + d_insert_after(head, curr, d_get_rulenode(wd)) + end + elseif class == 1 then + local wd + if get_font_feature(currfont,'vertical') then + wd = ensize<width and ensize-width or 0 + else + wd = (width-bbox[1] < ensize) and ensize-width or -bbox[1]+oneoften + if not cjtype and wd > 0 then wd = 0 end + end + if chr.left_protruding then + if not halt_on then head = d_insert_before(head, curr, d_get_kernnode(wd)) - else - head = d_insert_before(head, curr, d_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(currfont,'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] + else + if halt_on then + local pn = d_nodeprev(curr) + if pn and d_getid(pn) == kernnode then + -- glue halt_kern glyph -> glue rule halt_kern glyph + wd = 0 + curr = pn + elseif pn and d_getid(pn) == gluenode and d_getfield(d_getfield(pn,"spec"),"width") == 0 then + -- halt_kern glue glyph -> glue rule halt_kern glyph + local ppn = d_nodeprev(pn) + if ppn and d_getid(ppn) == kernnode then + wd = 0 + head = d_remove_node(head, ppn) + head, curr = d_insert_before(head, curr, ppn) + end + end end - if chr.left_protruding then + head = d_insert_before(head, curr, d_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(currfont,'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 + if not halt_on then head = d_insert_before(head, curr, d_get_kernnode(lwd)) - else - head = d_insert_before(head, curr, d_get_rulenode(lwd)) end - if chr.right_protruding then + else + if halt_on then lwd = 0 end -- there's already penalty 10000 + head = d_insert_before(head, curr, d_get_rulenode(lwd)) + end + if chr.right_protruding then + if not halt_on then d_insert_after (head, curr, d_get_kernnode(rwd)) - else - d_insert_after (head, curr, d_get_rulenode(rwd)) end + else + if halt_on then + local nn = d_nodenext(curr) + if nn and d_getid(nn) == kernnode then + rwd = 0 + curr = nn + end + end + d_insert_after (head, curr, d_get_rulenode(rwd)) end end end @@ -1003,6 +1056,7 @@ end -- ruby: pre-linebreak routine ------------------------------ local function spread_ruby_box(head,extrawidth) + local to_free = {} for curr in d_traverse_id(gluenode,head) do local currspec = d_getfield(curr,"spec") if currspec then @@ -1012,9 +1066,13 @@ local function spread_ruby_box(head,extrawidth) else head = d_insert_before(head,curr,d_get_kernnode(wd+extrawidth)) head = d_remove_node(head,curr) + to_free[#to_free + 1] = curr end end end + if #to_free > 0 then + for _,v in ipairs(to_free) do d_nodefree(v) end + end return head end @@ -1045,7 +1103,11 @@ local function get_ruby_side_width (basewidth,rubywidth,adjacent) local width,margin = (rubywidth-basewidth)/2, 0 if adjacent then if d_getid(adjacent) == glyphnode then - if not is_hanja(d_get_unicode_char(adjacent)) then + local uni = d_get_unicode_char(adjacent) + if is_unicode_vs(uni) then -- bypass VS + uni = d_get_unicode_char(d_nodeprev(adjacent)) + end + if not is_hanja(uni) then width = (rubywidth-basewidth-emsize)/2 if width > 0 then margin = emsize/2 @@ -1295,10 +1357,13 @@ local function get_hanja_hangul_table (table,file,init) return table end -local hanja2hangul = { } -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) +local hanja2hangul +local function initialize_hanja2hangul () + hanja2hangul = {} + 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) +end -- 1 : 리을, 2 : 중성, 3 : 종성 local function get_josacode (prevs) @@ -1311,6 +1376,7 @@ local function get_josacode (prevs) if is_jungjongsong(code) then return jamo2josacode(code) end if (code >= 0x3400 and code <= 0x9FA5) or (code >= 0xF900 and code <= 0xFA2D) then + if not hanja2hangul then initialize_hanja2hangul() end local _, _, T = syllable2jamo(hanja2hangul[code]) return jamo2josacode(T) end @@ -1345,6 +1411,7 @@ local function get_josaprevs(curr,josaprev,ignoreparens,halt) or inhibitxspcode[chr] or prebreakpenalty[chr] or postbreakpenalty[chr] + or is_unicode_vs(chr) -- bypass VS or chr == 0x302E -- tone mark or chr == 0x302F then -- tone mark --skip @@ -1352,7 +1419,7 @@ local function get_josaprevs(curr,josaprev,ignoreparens,halt) josaprev[#josaprev + 1] = chr end elseif currid == hlistnode or currid == vlistnode then - josaprev = get_josaprevs(d_nodeslide(d_getlist(curr)),josaprev,ignoreparens,halt) + josaprev = get_josaprevs(d_nodetail(d_getlist(curr)),josaprev,ignoreparens,halt) end if #josaprev == 3 then break end curr = d_nodeprev(curr) @@ -1361,6 +1428,7 @@ local function get_josaprevs(curr,josaprev,ignoreparens,halt) end local function korean_autojosa (head) + local to_free = {} for curr in d_traverse_id(glyphnode,head) do local josaattr = d_has_attribute(curr,autojosaattr) if josaattr and d_has_attribute(curr,finemathattr) then @@ -1380,7 +1448,13 @@ local function korean_autojosa (head) d_setfield(curr,"char", josa_list[thischar][josacode]) end end - if d_getchar(curr) < 0 then d_remove_node(head,curr) end + if d_getchar(curr) < 0 then + d_remove_node(head,curr) + to_free[#to_free + 1] = curr + end + end + if #to_free > 0 then + for _,v in ipairs(to_free) do d_nodefree(v) end end end @@ -1417,7 +1491,7 @@ local function nanumtype1font(curr) if series then series = series > 500 and "b" or "m" else - series = stringfind(fnt_t.name,"^cmb") and "b" or "m" + 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) @@ -1459,72 +1533,84 @@ local function font_substitute(head) while curr do local currid = d_getid(curr) if currid == mathnode and d_getsubtype(curr) == 0 then - curr = d_end_of_math(curr) + curr = d_end_of_math(curr) elseif currid == glyphnode then local currchar, currfont = d_getchar(curr), d_getfont(curr) - local eng = get_font_table(currfont) - local myfontchar = nil - if eng and eng.encodingbytes and eng.encodingbytes == 2 -- exclude type1 - and hangulpunctuations[currchar] - and d_has_attribute(curr, hangulpunctsattr) - and (d_has_attribute(curr, finemathattr) or 0) > 0 -- not ttfamily - and not get_font_char(currfont, 0xAC00) then -- exclude hangul font - else - myfontchar = get_font_char(currfont, currchar) - end - if currchar and not myfontchar then - local hangul = d_has_attribute(curr, hangulfntattr) - local hanja = d_has_attribute(curr, hanjafntattr) - local fallback = d_has_attribute(curr, fallbackfntattr) - local ftable = {hangul, hanja, fallback} - if luatexko.hanjafontforhanja then - local uni = d_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,3 do - local fid = ftable[i] - myfontchar = get_font_char(fid, currchar) - if myfontchar then - d_setfield(curr,"font",fid) - local nxt = d_nodenext(curr) - if eng and nxt then - local nxtid, nxtsubtype = d_getid(nxt), d_getsubtype(nxt) - -- adjust next glue by hangul font space - if nxtid == gluenode and nxtsubtype and nxtsubtype == 0 then - local nxtspec = d_getfield(nxt,"spec") - if nxtspec and d_getfield(nxtspec,"writable") and get_font_char(fid,32) then - local sp,st,sh = hangulspaceskip(eng, fid, nxtspec) - if sp and st and sh then - local hg = d_copy_node(nxtspec) - d_setfield(hg,"width", sp) - d_setfield(hg,"stretch",st) - d_setfield(hg,"shrink", sh) - d_setfield(nxt,"spec", hg) - end + if currchar then + if is_unicode_vs(currchar) then -- ideograph variation selectors + local prev = d_nodeprev(curr) + local prevfont = d_getid(prev) == glyphnode and d_getfont(prev) + if prevfont ~= currfont then + d_setfield(curr, "font", prevfont) -- sync font + end + else + local myfontchar + local eng = currfont and get_font_table(currfont) + if eng and eng.encodingbytes and eng.encodingbytes == 2 -- exclude type1 + and hangulpunctuations[currchar] and d_has_attribute(curr, hangulpunctsattr) + and (d_has_attribute(curr, finemathattr) or 0) > 0 -- not ttfamily + and not get_font_char(currfont, 0xAC00) then -- exclude hangul font + else + myfontchar = get_font_char(currfont, currchar) + end + if not myfontchar then + local hangul = d_has_attribute(curr, hangulfntattr) + local hanja = d_has_attribute(curr, hanjafntattr) + local fallback = d_has_attribute(curr, fallbackfntattr) + local ftable = {hangul, hanja, fallback} + if luatexko.hanjafontforhanja then + local uni = d_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,3 do + local 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 - -- adjust next italic correction kern - elseif nxtid == kernnode and nxtsubtype == 1 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) + --- + local nxt = d_nodenext(curr) + local nxtid = nxt and d_getid(nxt) + if nxtid == glyphnode and is_unicode_vs(d_getchar(nxt)) then + nxt = d_nodenext(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 and nxtsubtype == 0 then + local nxtspec = d_getfield(nxt,"spec") + if nxtspec and d_getfield(nxtspec,"writable") and get_font_char(fid,32) then + local sp,st,sh = hangulspaceskip(eng, fid, nxtspec) + if sp and st and sh then + local s = d_get_gluespec(sp, st, sh) + d_setfield(nxt, "spec", s) + d_nodefree(nxtspec) + end + end + -- adjust next italic correction kern + elseif nxtid == kernnode and nxtsubtype == 1 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 + end + break end end - --- 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) + if not myfontchar then + nanumtype1font(curr) end - --- - break end end - if not myfontchar then - nanumtype1font(curr) - end end end curr = d_nodenext(curr) @@ -1538,60 +1624,43 @@ local function assign_unicode_codevalue (head) for curr in d_traverse_id(glyphnode, head) do d_set_attribute(curr, luakounicodeattr, d_getchar(curr)) end - return head end ----------------------------- -- reorder hangul tone marks ----------------------------- local function reorderTM (head) - for curr in d_traverse_id(glyphnode, head) do - local uni = d_get_unicode_char(curr) - if uni and (uni == 0x302E or uni == 0x302F) then - local unichar = get_font_char(d_getfont(curr), uni) - if unichar and unichar.width > 0 then - local p = d_nodeprev(curr) - while p do - local pid = d_getid(p) - if pid == glyphnode then + local curr = d_nodetail(head) + while curr do + if d_getid(curr) == glyphnode then + local uni = d_get_unicode_char(curr) + if uni == 0x302E or uni == 0x302F then + local done = false + local unichar = get_font_char(d_getfont(curr), uni) + if unichar and unichar.width > 0 then + local p = d_nodeprev(curr) + while p and d_getid(p) == glyphnode do local pc = get_cjk_class(d_get_unicode_char(p)) - if pc == 7 or pc == 8 then - head = d_insert_before(head,p,d_copy_node(curr)) + if pc == 9 then + elseif pc == 7 or pc == 8 then head = d_remove_node(head,curr) + head, curr = d_insert_before(head,p,curr) + done = true + break + else break end - elseif unichar.commands and pid == kernnode then - -- kerns in vertical typesetting mode - else - break + p = d_nodeprev(p) end - p = d_nodeprev(p) end - end - end - end - return head -end - ------------------------------ --- ideographic variation selector ------------------------------ -local function hanja_vs_support (head) - for curr in d_traverse_id(glyphnode, head) do - local cc = d_getchar(curr) - if is_unicode_vs(cc) then - local prev = d_nodeprev(curr) - if prev and d_getid(prev) == glyphnode then - local f = get_font_table(d_getfont(prev)) - local ivs = f and f.resources and f.resources.variants - ivs = ivs and ivs[cc] and ivs[cc][d_getchar(prev)] - -- !!! ARRRG! the font table doesn't have variants for non-BMP chars. - if ivs then - d_setfield(prev,"char",ivs) - head = d_remove_node(head,curr) + if not done and get_font_char(d_getfont(curr), 0x25CC) then + local u_25CC = d_copy_node(curr) + d_setfield(u_25CC, "char", 0x25CC) + d_insert_after(head, curr, u_25CC) end end end + curr = d_nodeprev(curr) end return head end @@ -1605,7 +1674,6 @@ add_to_callback('hpack_filter', function(head) korean_autojosa(head) remove_cj_spaceskip(head) font_substitute(head) - head = hanja_vs_support(head) return d_tonode(head) end, 'luatexko.hpack_filter_first',1) @@ -1626,7 +1694,6 @@ add_to_callback('pre_linebreak_filter', function(head) korean_autojosa(head) remove_cj_spaceskip(head) font_substitute(head) - head = hanja_vs_support(head) return d_tonode(head) end, 'luatexko.pre_linebreak_filter_first',1) @@ -1636,7 +1703,7 @@ add_to_callback('pre_linebreak_filter', function(head) cjk_spacing_linebreak(head) if texcount["luakorubyattrcnt"]>0 then spread_ruby_base_box(head) end head = compress_fullwidth_punctuations(head) - discourage_char_widow(head, d_nodeslide(head)) + discourage_char_widow(head, d_nodetail(head)) if texcount["luakorubyattrcnt"]>0 then head = no_ruby_at_margin(head) end head = reorderTM(head) return d_tonode(head) @@ -1646,11 +1713,13 @@ end, 'luatexko.pre_linebreak_filter') -------------------------- -- dot emphasis (드러냄표) -------------------------- -local function after_linebreak_dotemph (head) +local function after_linebreak_dotemph (head, to_free) + local outer = not to_free + to_free = to_free or {} for curr in d_traverse(head) do local currid = d_getid(curr) if currid == hlistnode then -- hlist may be nested!!! - d_setfield(curr,"head", after_linebreak_dotemph(d_getlist(curr))) + d_setfield(curr,"head", after_linebreak_dotemph(d_getlist(curr), to_free)) elseif currid == glyphnode then local attr = d_has_attribute(curr,dotemphattr) if attr and attr > 0 then @@ -1671,18 +1740,23 @@ local function after_linebreak_dotemph (head) nn = d_nodenext(nn) end end - local d = d_copy_node(d_todirect(dotemphnode[attr])) + local dbox = d_todirect(dotemphnode[attr]) + local d = d_copy_node(dbox) local dwidth = d_getfield(d,"width") local dot = d_get_kernnode(basewd/2-dwidth/2) d_setfield(dot,"next", d_getlist(d)) d_setfield(d,"head", dot) d_setfield(d,"width", 0) head = d_insert_before(head,curr,d) + to_free[dbox] = true end d_unset_attribute(curr,dotemphattr) end end end + if outer then + for k in pairs(to_free) do d_nodefree(k) end + end return head end @@ -1723,10 +1797,9 @@ end --------------------- -- underline emphasis --------------------- -local function draw_underline(head,curr,width,ulinenum,ulstart) +local function draw_underline(head,curr,width,ubox,ulstart) if width and width > 0 then local glue = d_get_gluenode(width) - local ubox = d_todirect(ulinebox[ulinenum]) d_setfield(glue,"subtype", 101) -- cleaders d_setfield(glue,"leader", d_copy_node(ubox)) head = d_insert_before(head, ulstart, glue) @@ -1735,8 +1808,9 @@ local function draw_underline(head,curr,width,ulinenum,ulstart) for _,nd in ipairs({ulstart,curr}) do if d_getid(nd) == whatsitnode and d_getsubtype(nd) == whatsitspecial then local nddata = d_getfield(nd,"data") - if nddata and stringfind(nddata,"luako:uline") then + if nddata and nddata:find("luako:uline") then head = d_remove_node(head,nd) + d_nodefree(nd) end end end @@ -1762,21 +1836,23 @@ local function after_linebreak_underline(head,glueorder,glueset,gluesign,ulinenu elseif currid == whatsitnode and d_getsubtype(curr) == whatsitspecial then local currdata = d_getfield(curr,"data") if currdata then - if stringfind(currdata,"luako:ulinebegin=") then - ulinenum = tonumber(stringmatch(currdata,"(%d+)")) + if currdata:find("luako:ulinebegin=") then + ulinenum = tonumber(currdata:match("(%d+)")) ulstart = curr - elseif ulstart and ulinenum - and stringfind(currdata,'luako:ulineend') then + elseif ulstart and ulinenum and currdata:find('luako:ulineend') then + local ubox = d_todirect(ulinebox[ulinenum]) local wd = d_nodedimensions(glueset,gluesign,glueorder,ulstart,curr) - head = draw_underline(head,curr,wd,ulinenum,ulstart) + head = draw_underline(head,curr,wd,ubox,ulstart) + d_nodefree(ubox) ulinebox[ulinenum] = nil ulinenum = nil end end end if ulstart and ulinenum and curr == d_nodetail(head) then + local ubox = d_todirect(ulinebox[ulinenum]) local wd = d_nodedimensions(glueset,gluesign,glueorder,ulstart,curr) - head = draw_underline(head,curr,wd,ulinenum,ulstart) + head = draw_underline(head,curr,wd,ubox,ulstart) end end return head, ulinenum @@ -1805,34 +1881,34 @@ end, 'luatexko.post_linebreak_filter') ------------------------------------ -- vertical typesetting: EXPERIMENTAL ------------------------------------ -local tsbtable, mytime, currtime, cachedir, lfsattributes, lfstouch +local tsbtable, mytime, currtime, cachedir, fontloader, lfs, lfsattributes, lfstouch local function get_vwidth_tsb_table (filename,fontname) if tsbtable[fontname] then return tsbtable[fontname] end local cachefile = stringformat("%s/luatexko_vertical_metrics_%s.lua", - cachedir,stringgsub(fontname,"%W","_")) + cachedir,fontname:gsub("%W","_")) local cattr = lfs.isfile(cachefile) and lfsattributes(cachefile) local fonttime = lfsattributes(filename,"modification") if cattr and cattr.access > mytime and cattr.modification == fonttime then tsbtable[fontname] = dofile(cachefile) return tsbtable[fontname] end - local metrics = nil - local font = fontloader.open(filename,fontname) - if font then - metrics = fontloader.to_table(font) - fontloader.close(font) - local glyph_t = {} - if metrics.subfonts then - for _,v in ipairs(metrics.subfonts) do - for ii,vv in pairs(v.glyphs) do - glyph_t[ii] = { ht = vv.vwidth, tsb = vv.tsidebearing } + local fnt = fontloader.open(filename,fontname) + if fnt then + local fnt_t = fontloader.to_table(fnt) -- for tsidebearing + fontloader.close(fnt) + local glyph_t = {} + local subfonts = fnt_t.subfonts or {fnt_t} + for _,subfont in ipairs(subfonts) do + local glyphs = subfont.glyphs or {} + for i, gl in pairs(glyphs) do + local id = gl.orig_pos or i + local name = gl.name + if name then + glyph_t[id] = { ht = gl.vwidth, tsb = gl.tsidebearing, vk = gl.vkerns } + glyph_t[name] = id end end - else - for i,v in ipairs(metrics.glyphs) do - glyph_t[i] = { ht = v.vwidth, tsb = v.tsidebearing } - end end if lfstouch then table.tofile(cachefile,glyph_t,"return") @@ -1851,59 +1927,74 @@ local function cjk_vertical_font (vf) if not vf.shared.features["vertical"] then return end if vf.type == "virtual" then return end - -- load font (again) local tsbtable = get_vwidth_tsb_table(vf.filename,vf.fontname) if not tsbtable then return end - local tmp = table.copy(vf) -- fastcopy takes time too long. - local id = fontdefine(tmp) + local id = fontdefine(table.copy(vf)) -- fastcopy takes time too long. vf.type = 'virtual' vf.fonts = {{ id = id }} - local quad = vf.parameters and vf.parameters.quad or 655360 - local descriptions = vf.shared and vf.shared.rawdata and vf.shared.rawdata.descriptions - local ascender = vf.parameters and vf.parameters.ascender or quad*0.8 - local factor = vf.parameters and vf.parameters.factor or 655.36 - local xheight = vf.parameters and vf.parameters.x_height or quad/2 - local goffset = xheight/2 - quad/2 + local params = vf.parameters or {} + local shared = vf.shared or {} + local quad = params.quad or 655360 + local ascender = params.ascender or quad*0.8 + local factor = params.factor or 655.36 + local xheight = params.x_height or quad/2 + local goffset = xheight/2 - quad/2 + local descriptions = shared.rawdata and shared.rawdata.descriptions + local vkrn_tab, id2uni_tab = {}, {} for i,v in pairs(vf.characters) do - local dsc = descriptions[i] - local gl = v.index - -- from loaded font - local vw = tsbtable and tsbtable[gl] and tsbtable[gl].ht - vw = vw and vw * factor or quad - local tsb = tsbtable and tsbtable[gl] and tsbtable[gl].tsb - local bb4 = dsc and dsc.boundingbox and dsc.boundingbox[4] - local asc = bb4 and tsb and (bb4+tsb)*factor or ascender - local hw = v.width or quad - local offset = hw/2 + goffset - local vh = hw > 0 and hw/2 or nil + local dsc = descriptions[i] + local gl = v.index + local tsb_gl = tsbtable and tsbtable[gl] + local vw = tsb_gl and tsb_gl.ht; vw = vw and vw * factor or quad + local tsb = tsb_gl and tsb_gl.tsb + local bb4 = dsc and dsc.boundingbox and dsc.boundingbox[4] + local asc = bb4 and tsb and (bb4+tsb)*factor or ascender + local hw = v.width or quad + local offset = hw/2 + goffset + local vh = hw > 0 and hw/2 or nil v.commands = { - {'right', asc}, -- bbox4 + top_side_bearing - {'down', offset}, + {'right', asc}, -- bbox4 + top_side_bearing + {'down', offset}, {'special', 'pdf: q 0 1 -1 0 0 0 cm'}, {'push'}, - {'char', i}, + {'char', i}, {'pop'}, {'special', 'pdf: Q'}, } - v.width = vw - v.height = vh - v.depth = vh - v.italic = nil + v.width = vw + v.height = vh + v.depth = vh + v.italic = nil + -- for vkrn + local t = id2uni_tab[gl] or {} + t[#t + 1] = i + id2uni_tab[gl] = t + local vk = tsb_gl.vk + if vk then + for _,vv in ipairs(vk) do + local index, off = vv.char, vv.off + index = index and tsbtable and tsbtable[index] + if index and off then + vkrn_tab[i] = vkrn_tab[i] or {} + vkrn_tab[i][index] = off + end + end + end end --- vertical gpos local res = vf.resources or {} if res.verticalgposhack then return vf -- avoid multiple running end - local fea = vf.shared and vf.shared.features or {} + local fea = shared.features or {} fea.kern = nil -- only for horizontal typesetting fea.vert = true -- should be activated by default local vposkeys = {} local seq = res.sequences or {} for _,v in ipairs(seq) do - if v.type == "gpos_single" and v.subtables then -- todo: gpos_pair... + if (v.type == "gpos_single" or v.type == "gpos_pair") and v.subtables then local feature = v.features or {} if feature.vhal or feature.vkrn or feature.valt or feature.vpal or feature.vert then for _,vv in ipairs(v.subtables) do @@ -1921,6 +2012,20 @@ local function cjk_vertical_font (vf) vp[i] = { -vv[2], vv[1], vv[4], vv[3] } end end + else -- vkrn + local t = {} + for first,idofftab in pairs(vkrn_tab) do + for id,off in pairs(idofftab) do + local unis = id2uni_tab[id] + if unis then + for _,second in ipairs(unis) do + t[first] = t[first] or {} + t[first][second] = off + end + end + end + end + lookups[v] = t end end res.verticalgposhack = true @@ -1928,11 +2033,9 @@ local function cjk_vertical_font (vf) end local function activate_vertical_virtual (tfmdata,value) - local loaded = luatexbase.priority_in_callback("luaotfload.patch_font", - "luatexko.vertical_virtual_font") - if value and not loaded then - require "fontloader" - require "lfs" + if value and not tsbtable then + fontloader = require "fontloader" + lfs = require "lfs" lfstouch = lfs.touch lfsattributes = lfs.attributes tsbtable = {} @@ -1941,8 +2044,8 @@ local function activate_vertical_virtual (tfmdata,value) mytime = mytime and lfsattributes(mytime,"modification") cachedir = caches.getwritablepath("..","luatexko") add_to_callback("luaotfload.patch_font", - cjk_vertical_font, - "luatexko.vertical_virtual_font") + cjk_vertical_font, + "luatexko.vertical_virtual_font") end end @@ -1991,36 +2094,7 @@ local function fakeslant_itlc (tfmdata) end end ------------------------------------- --- tounicode for old hangul ------------------------------------- -local function tounicode_oldhangul (tfmdata) - local script = tfmdata.properties and tfmdata.properties.script - if script ~= "hang" then return end - local desc = tfmdata.shared and tfmdata.shared.rawdata and tfmdata.shared.rawdata.descriptions - local chrs = tfmdata.characters - if not desc or not chrs then return end - if not chrs[0x1100] then return end - for _,v in ipairs({{0x1100,0x11FF},{0xA960,0xA97C},{0xD7B0,0xD7FB}}) do - for i = v[1],v[2] do - local ds = desc[i] and desc[i].slookups - if ds then - for _,s in pairs(ds) do - if type(s) == "number" and s >= 0xF0000 and chrs[s] and not chrs[s].tounicode then - chrs[s].tounicode = stringformat("%04X",i) - end - end - end - end - end -end - -add_to_callback("luaotfload.patch_font", - function(tfmdata) - fakeslant_itlc(tfmdata) - tounicode_oldhangul(tfmdata) - end, "luatexko.font_patches") - +add_to_callback("luaotfload.patch_font", fakeslant_itlc, "luatexko.fakeslant_itlc") ------------------------------------ -- Actual Text diff --git a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty index 356cfbc3aba..9dec1eb9639 100644 --- a/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty +++ b/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty @@ -1,6 +1,7 @@ % luatexko.sty % % Copyright (c) 2013-2015 Dohyun Kim <nomos at ktug org> +% Soojin Nam <jsunam at gmail com> % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -22,7 +23,7 @@ \expandafter\endinput \fi -\ProvidesPackage{luatexko}[2015/04/13 v1.8 Typesetting Korean with LuaLaTeX] +\ProvidesPackage{luatexko}[2015/07/02 v1.9 Typesetting Korean with LuaLaTeX] %% package options \newif\if@hangul |