ソースコードの管理場所
リビジョン | d25ef489b2fd1567768e297517fcc9ebf9c9f991 (tree) |
---|---|
日時 | 2014-10-30 17:08:12 |
作者 | Hironori Kitagawa <h_kitagawa2001@yaho...> |
コミッター | Hironori Kitagawa |
'vkrn' should work now
@@ -1,158 +0,0 @@ | ||
1 | --- | |
2 | --- luatexja/ltj-pretreat.lua | |
3 | --- | |
4 | - | |
5 | -luatexja.load_module('base'); local ltjb = luatexja.base | |
6 | -luatexja.load_module('charrange'); local ltjc = luatexja.charrange | |
7 | -luatexja.load_module('stack'); local ltjs = luatexja.stack | |
8 | -luatexja.load_module('jfont'); local ltjf = luatexja.jfont | |
9 | -luatexja.load_module('direction'); local ltjd = luatexja.direction | |
10 | - | |
11 | -local Dnode = node.direct or node | |
12 | - | |
13 | -local nullfunc = function(n) return n end | |
14 | -local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc | |
15 | -local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc | |
16 | - | |
17 | -local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end | |
18 | -local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end | |
19 | -local getfont = (Dnode ~= node) and Dnode.getfont or function(n) return n.font end | |
20 | -local getchar = (Dnode ~= node) and Dnode.getchar or function(n) return n.char end | |
21 | -local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end | |
22 | -local getsubtype = (Dnode ~= node) and Dnode.getsubtype or function(n) return n.subtype end | |
23 | - | |
24 | -local pairs = pairs | |
25 | -local floor = math.floor | |
26 | -local has_attr = Dnode.has_attribute | |
27 | -local set_attr = Dnode.set_attribute | |
28 | -local node_traverse = Dnode.traverse | |
29 | -local node_remove = Dnode.remove | |
30 | -local node_next = (Dnode ~= node) and Dnode.getnext or node.next | |
31 | -local node_free = Dnode.free | |
32 | -local node_end_of_math = Dnode.end_of_math | |
33 | -local tex_getcount = tex.getcount | |
34 | - | |
35 | -local id_glyph = node.id('glyph') | |
36 | -local id_math = node.id('math') | |
37 | -local id_whatsit = node.id('whatsit') | |
38 | -local sid_user = node.subtype('user_defined') | |
39 | - | |
40 | -local attr_dir = luatexbase.attributes['ltj@dir'] | |
41 | -local attr_curjfnt = luatexbase.attributes['ltj@curjfnt'] | |
42 | -local attr_curtfnt = luatexbase.attributes['ltj@curtfnt'] | |
43 | -local attr_icflag = luatexbase.attributes['ltj@icflag'] | |
44 | - | |
45 | -local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct | |
46 | -local ltjf_get_vert_glyph = ltjf.get_vert_glyph | |
47 | -local ltjf_replace_altfont = ltjf.replace_altfont | |
48 | -local attr_orig_char = luatexbase.attributes['ltj@origchar'] | |
49 | -local STCK = luatexja.userid_table.STCK | |
50 | -local DIR = luatexja.userid_table.DIR | |
51 | -local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG | |
52 | - | |
53 | -local dir_tate = luatexja.dir_table.dir_tate | |
54 | -local lang_ja = token.create('ltj@@japanese')[2] | |
55 | ------------------------------------------------------------------------- | |
56 | --- MAIN PROCESS STEP 1: replace fonts | |
57 | ------------------------------------------------------------------------- | |
58 | -local wt, wtd = {}, {} | |
59 | -do | |
60 | - local ltjd_get_dir_count = ltjd.get_dir_count | |
61 | - local start_time_measure, stop_time_measure | |
62 | - = ltjb.start_time_measure, ltjb.stop_time_measure | |
63 | - local head | |
64 | - local is_dir_tate | |
65 | - local suppress_hyphenate_ja_aux = {} | |
66 | - suppress_hyphenate_ja_aux[id_glyph] = function(p) | |
67 | - if (has_attr(p, attr_icflag) or 0)<=0 and is_ucs_in_japanese_char(p) then | |
68 | - local pc = getchar(p) | |
69 | - local pf = ltjf_replace_altfont(has_attr(p, attr_curjfnt) or getfont(p), pc) | |
70 | - setfield(p, 'font', pf); set_attr(p, attr_curjfnt, pf) | |
71 | - setfield(p, 'lang', lang_ja) | |
72 | - set_attr(p, attr_orig_char, pc) | |
73 | - end | |
74 | - return p | |
75 | - end | |
76 | - suppress_hyphenate_ja_aux[id_math] = function(p) | |
77 | - return node_end_of_math(node_next(p)) end | |
78 | - suppress_hyphenate_ja_aux[50] = function(p) return p end | |
79 | - suppress_hyphenate_ja_aux[id_whatsit] = function(p) | |
80 | - if getsubtype(p)==sid_user then | |
81 | - local uid = getfield(p, 'user_id') | |
82 | - if uid==STCK then | |
83 | - wt[#wt+1] = p; node_remove(head, p) | |
84 | - elseif uid==DIR then | |
85 | - if has_attr(p, attr_icflag)<PROCESSED_BEGIN_FLAG then | |
86 | - ltjs.list_dir = has_attr(p, attr_dir) | |
87 | - else | |
88 | - wtd[#wtd+1] = p; node_remove(head, p) | |
89 | - end | |
90 | - end | |
91 | - end | |
92 | - return p | |
93 | - end | |
94 | - | |
95 | - local function suppress_hyphenate_ja (h,t) | |
96 | - start_time_measure('ltj_hyphenate') | |
97 | - head = to_direct(h) | |
98 | - local p = head | |
99 | - for i = 1,#wt do wt[i]=nil end | |
100 | - for i = 1,#wtd do wtd[i]=nil end | |
101 | - ltjs.list_dir=ltjd_get_dir_count() | |
102 | - while p and p~=t do | |
103 | - local pfunc = suppress_hyphenate_ja_aux[getid(p)] | |
104 | - p = node_next(pfunc and pfunc(p) or p) | |
105 | - end | |
106 | - stop_time_measure('ltj_hyphenate'); start_time_measure('tex_hyphenate') | |
107 | - lang.hyphenate(h, t) | |
108 | - stop_time_measure('tex_hyphenate') | |
109 | - return h | |
110 | - end | |
111 | - | |
112 | - luatexbase.add_to_callback('hyphenate', | |
113 | - function (head,tail) | |
114 | - return suppress_hyphenate_ja(head) | |
115 | - end,'ltj.hyphenate') | |
116 | -end | |
117 | - | |
118 | --- mode: true iff this function is called from hpack_filter | |
119 | -local ltjs_report_stack_level = ltjs.report_stack_level | |
120 | -local function set_box_stack_level(head, mode) | |
121 | - local box_set, cl = 0, tex.currentgrouplevel + 1 | |
122 | - for _,p in pairs(wt) do | |
123 | - if mode and getfield(p, 'value')==cl then box_set = 1 end; node_free(p) | |
124 | - end | |
125 | - ltjs_report_stack_level(tex_getcount('ltj@@stack') + box_set) | |
126 | - for _,p in pairs(wtd) do | |
127 | - node_free(p) | |
128 | - end | |
129 | - is_dir_tate = ltjs.list_dir == dir_tate | |
130 | - if is_dir_tate then | |
131 | - for p in Dnode.traverse_id(id_glyph,to_direct(head)) do | |
132 | - if (has_attr(p, attr_icflag) or 0)<=0 and has_attr(p, attr_curjfnt)==getfont(p) then | |
133 | - local pfn = has_attr(p, attr_curtfnt) or getfont(p) | |
134 | - local pc = getchar(p) | |
135 | - local pf = ltjf_replace_altfont(pfn, pc) | |
136 | - set_attr(p, attr_dir, pc) | |
137 | - pc = ltjf_get_vert_glyph(pf, pc) or pc | |
138 | - setfield(p, 'char', pc); set_attr(p, attr_orig_char, pc) | |
139 | - setfield(p, 'font', pf); set_attr(p, attr_curjfnt, pf) | |
140 | - end | |
141 | - end | |
142 | - end | |
143 | - return head | |
144 | -end | |
145 | - | |
146 | --- CALLBACKS | |
147 | -luatexbase.add_to_callback('hpack_filter', | |
148 | - function (head) | |
149 | - return set_box_stack_level(head, true) | |
150 | - end,'ltj.hpack_filter_pre',1) | |
151 | -luatexbase.add_to_callback('pre_linebreak_filter', | |
152 | - function (head) | |
153 | - return set_box_stack_level(head, false) | |
154 | - end,'ltj.pre_linebreak_filter_pre',1) | |
155 | - | |
156 | -luatexja.pretreat = { | |
157 | - set_box_stack_level = set_box_stack_level, | |
158 | -} |
@@ -671,8 +671,8 @@ do | ||
671 | 671 | end |
672 | 672 | return dest |
673 | 673 | end |
674 | - prepare_fl_data = function (dest, id, fname) | |
675 | - local fl = fontloader.open(fname) | |
674 | + prepare_fl_data = function (dest, id) | |
675 | + local fl = fontloader.open(id.filename) | |
676 | 676 | local unicodes = id.resources.unicodes |
677 | 677 | if fl.glyphs then |
678 | 678 | dest = add_fl_table(dest, fl.glyphs, id.resources.unicodes, fl.glyphmax, |
@@ -687,24 +687,20 @@ do | ||
687 | 687 | fontloader.close(fl) |
688 | 688 | return dest |
689 | 689 | end |
690 | - -- supply vkern table: TODO | |
691 | - supply_vkern_table = function(id) | |
692 | - -- if not id then return end | |
693 | - -- local fname = id.filename | |
694 | - -- if not fname then return end | |
695 | - -- local bx = font_extra_basename[file.basename(fname)].vkerns | |
696 | - -- local desc = id.shared.rawdata.descriptions | |
697 | - -- if bx then | |
698 | - -- for i,v in pairs(bx) do | |
699 | - -- print(i) | |
700 | - -- id.shared.rawdata.resources.lookuphash[i] | |
701 | - -- =id.shared.rawdata.resources.lookuphash[i] or v | |
702 | - -- for j,w in pairs(v) do | |
703 | - -- desc[j].kerns = desc[j].kerns or {} | |
704 | - -- desc[j].kerns[i] = w | |
705 | - -- end | |
706 | - -- end | |
707 | - -- end | |
690 | + -- supply vkern table | |
691 | + supply_vkern_table = function(id, bname) | |
692 | + local bx = font_extra_basename[bname].vkerns | |
693 | + local lookuphash = id.resources.lookuphash | |
694 | + local desc = id.shared.rawdata.descriptions | |
695 | + if bx then | |
696 | + for i,v in pairs(bx) do | |
697 | + lookuphash[i] = lookuphash[i] or v | |
698 | + for j,w in pairs(v) do | |
699 | + desc[j].kerns = desc[j].kerns or {} | |
700 | + desc[j].kerns[i] = w | |
701 | + end | |
702 | + end | |
703 | + end | |
708 | 704 | end |
709 | 705 | end |
710 | 706 |
@@ -748,48 +744,56 @@ do | ||
748 | 744 | local cache_ver = 3 |
749 | 745 | local checksum = file.checksum |
750 | 746 | |
751 | - local function prepare_extra_data(n, id) | |
752 | - -- test if already loaded | |
753 | - if (not id) or font_extra_info[n] then return | |
754 | - end | |
755 | - local fname = id.filename | |
756 | - local bname = file.basename(fname) | |
757 | - if not fname then | |
758 | - font_extra_info[n] = {}; return | |
759 | - elseif font_extra_basename[bname] then | |
760 | - font_extra_info[n] = font_extra_basename[bname]; return | |
761 | - end | |
762 | - -- if the cache is present, read it | |
763 | - local newsum = checksum(fname) -- MD5 checksum of the fontfile | |
764 | - local v = "extra_" .. string.lower(file.nameonly(fname)) | |
765 | - local dat = ltjb.load_cache(v, | |
766 | - function (t) return (t.version~=cache_ver) or (t.chksum~=newsum) end | |
767 | - ) | |
768 | - -- if the cache is not found or outdated, save the cache | |
769 | - if dat then | |
770 | - font_extra_basename[bname] = dat[1] or {} | |
771 | - else | |
772 | - local dat = nil | |
773 | - dat = prepare_vert_data(dat, id) | |
774 | - dat = prepare_fl_data(dat, id, fname) | |
775 | - font_extra_basename[bname] = dat or {} | |
776 | - ltjb.save_cache( v, | |
777 | - { | |
778 | - chksum = checksum(fname), | |
779 | - version = cache_ver, | |
780 | - dat, | |
781 | - }) | |
782 | - end | |
783 | - font_extra_info[n] = font_extra_basename[bname] | |
784 | - end | |
785 | - luatexbase.add_to_callback('luatexja.define_font', | |
786 | - function (res, name, size, id) | |
787 | - if type(res)~='number' then | |
788 | - prepare_extra_data(id, res) | |
789 | - supply_vkern_table(res) | |
790 | - end | |
791 | - end, | |
792 | - 'ltj.prepare_extra_data', 1) | |
747 | + local function prepare_extra_data_base(id) | |
748 | + if not id or not id.resources then return end | |
749 | + local bname = file.nameonly(id.filename or '') | |
750 | + print(bname, font_extra_basename[bname]) | |
751 | + if bname and not font_extra_basename[bname] then | |
752 | + -- if the cache is present, read it | |
753 | + local newsum = checksum(id.filename) -- MD5 checksum of the fontfile | |
754 | + local v = "extra_" .. string.lower(file.nameonly(id.filename)) | |
755 | + print(v) | |
756 | + local dat = ltjb.load_cache( | |
757 | + v, | |
758 | + function (t) return (t.version~=cache_ver) or (t.chksum~=newsum) end | |
759 | + ) | |
760 | + -- if the cache is not found or outdated, save the cache | |
761 | + if dat then | |
762 | + font_extra_basename[bname] = dat[1] or {} | |
763 | + else | |
764 | + local dat = nil | |
765 | + dat = prepare_vert_data(dat, id) | |
766 | + dat = prepare_fl_data(dat, id) | |
767 | + font_extra_basename[bname] = dat or {} | |
768 | + ltjb.save_cache( v, | |
769 | + { | |
770 | + chksum = checksum(fname), | |
771 | + version = cache_ver, | |
772 | + dat, | |
773 | + }) | |
774 | + end | |
775 | + return bname | |
776 | + end | |
777 | + end | |
778 | + local function prepare_extra_data_font(id, res) | |
779 | + if type(res)=='table' and res.filename then | |
780 | + font_extra_info[id] = font_extra_basename[file.nameonly(res.filename)] | |
781 | + end | |
782 | + end | |
783 | + luatexbase.add_to_callback( | |
784 | + 'luaotfload.patch_font', | |
785 | + function (tfmdata) | |
786 | + -- these function is executed one time per one fontfile | |
787 | + local bname = prepare_extra_data_base(tfmdata) | |
788 | + if bname then supply_vkern_table(tfmdata, bname) end | |
789 | + end, | |
790 | + 'ltj.prepare_extra_data', 1) | |
791 | + luatexbase.add_to_callback( | |
792 | + 'luatexja.define_font', | |
793 | + function (res, name, size, id) | |
794 | + prepare_extra_data_font(id, res) | |
795 | + end, | |
796 | + 'ltj.prepare_extra_data', 1) | |
793 | 797 | |
794 | 798 | local function a (n, dat) font_extra_info[n] = dat end |
795 | 799 | ltjr.vert_addfunc = a |
@@ -797,8 +801,8 @@ do | ||
797 | 801 | local identifiers = fonts.hashes.identifiers |
798 | 802 | for i=1,font.nextid()-1 do |
799 | 803 | if identifiers[i] then |
800 | - prepare_extra_data(i, identifiers[i]) | |
801 | - supply_vkern_table(identifiers[i]) | |
804 | + prepare_extra_data_base(identifiers[i]) | |
805 | + prepare_extra_data_font(i,identifiers[i]) | |
802 | 806 | end |
803 | 807 | end |
804 | 808 | end |
@@ -335,7 +335,9 @@ local function font_callback(name, size, id, fallback) | ||
335 | 335 | end |
336 | 336 | return mk_rml(basename, size, id) |
337 | 337 | else |
338 | - return fallback(name, size, id) | |
338 | + local tfmdata=fallback(name, size, id) | |
339 | + luatexbase.call_callback ("luaotfload.patch_font", tfmdata, name) | |
340 | + return tfmdata | |
339 | 341 | end |
340 | 342 | end |
341 | 343 |
@@ -156,7 +156,6 @@ local function capsule_glyph_tate(p, met, class, head, dir) | ||
156 | 156 | and ltjf_font_extra_info[pf][pc].vwidth |
157 | 157 | and ltjf_font_extra_info[pf][pc].vwidth * met.size or (ascent+descent) |
158 | 158 | pwidth = pwidth + (met.v_advance and met.v_advance[pc] or 0) |
159 | - print(pc, met.v_advance[pc], getfield(p, 'yoffset')) | |
160 | 159 | end |
161 | 160 | fwidth = (fwidth ~= 'prop') and fwidth or pwidth |
162 | 161 | fshift.down = char_data.down; fshift.left = char_data.left |