ソースコードの管理場所
Révision | 5a135960d843aa5b8363c84f7fcf194061902bcf (tree) |
---|---|
l'heure | 2014-10-30 15:25:41 |
Auteur | Hironori Kitagawa <h_kitagawa2001@yaho...> |
Commiter | Hironori Kitagawa |
ltj-jfont.lua: support modification of vertical advance (e.g. 'vpal' feature)
@@ -607,22 +607,24 @@ end | ||
607 | 607 | ------------------------------------------------------------------------ |
608 | 608 | font_extra_info = {} |
609 | 609 | local font_extra_info = font_extra_info -- key: fontnumber |
610 | +local font_extra_basename = {} -- key: basename | |
610 | 611 | |
611 | 612 | -- IVS and vertical metrics |
612 | 613 | local prepare_fl_data |
614 | +local supply_vkern_table | |
613 | 615 | do |
614 | - | |
615 | 616 | local fields = fontloader.fields |
616 | 617 | local function glyph_vmetric(glyph) |
617 | 618 | local flds = fields(glyph) |
618 | - local vw, tsb = nil, nil | |
619 | + local vw, tsb, vk = nil, nil, nil | |
619 | 620 | for _,i in ipairs(flds) do |
620 | 621 | if i=='vwidth' then vw = glyph.vwidth end |
621 | 622 | if i=='tsidebearing' then tsb = glyph.tsidebearing end |
623 | + if i=='vkerns' then vk = glyph.vkerns end | |
622 | 624 | end |
623 | - return vw, tsb | |
625 | + return vw, tsb, vk | |
624 | 626 | end |
625 | - | |
627 | + | |
626 | 628 | local sort = table.sort |
627 | 629 | local function add_fl_table(dest, tg, unitable, glyphmax, asc_des, units) |
628 | 630 | for i = 0, glyphmax-1 do |
@@ -644,15 +646,27 @@ do | ||
644 | 646 | end |
645 | 647 | end |
646 | 648 | end |
647 | - local vw, tsb = glyph_vmetric(gv) | |
648 | - if vw and vw~=asc_des then | |
649 | + -- vertical metric | |
650 | + local vw, tsb, vk = glyph_vmetric(gv) | |
649 | 651 | local gi = unitable[gv.name] |
650 | - -- We do not use tsidebearing, since fontloader does not read | |
651 | - -- VORG table. We assume that vertical origin == ascender | |
652 | + if vw and vw~=asc_des then | |
653 | + -- We do not use tsidebearing, since (1) fontloader does not read VORG table | |
654 | + -- and (2) 'tsidebearing' doea not appear in the returned table by fontloader.fields. | |
655 | + -- Hence, we assume that vertical origin == ascender | |
652 | 656 | -- (see capsule_glyph_tate in ltj-setwidth.lua) |
653 | 657 | dest = dest or {}; dest[gi] = dest[gi] or {} |
654 | 658 | dest[gi].vwidth = vw/units |
655 | 659 | end |
660 | + -- vertical kern | |
661 | + if vk then | |
662 | + dest = dest or {}; | |
663 | + local dest_vk = dest.vkerns or {}; dest.vkerns = dest_vk | |
664 | + for _,v in pairs(vk) do | |
665 | + dest_vk[v.lookup] = dest_vk[v.lookup] or {} | |
666 | + dest_vk[v.lookup][gi] = dest_vk[v.lookup][gi] or {} | |
667 | + dest_vk[v.lookup][gi][unitable[v.char]] = v.off | |
668 | + end | |
669 | + end | |
656 | 670 | end |
657 | 671 | end |
658 | 672 | return dest |
@@ -673,6 +687,25 @@ do | ||
673 | 687 | fontloader.close(fl) |
674 | 688 | return dest |
675 | 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 | |
708 | + end | |
676 | 709 | end |
677 | 710 | |
678 | 711 | -- 縦書き用字形への変換テーブル |
@@ -683,8 +716,8 @@ do | ||
683 | 716 | if type(v.slookups)=='table' then |
684 | 717 | local s = v.slookups[tname] |
685 | 718 | if s then |
686 | - if not dest then dest = {} end | |
687 | - if not dest[i] then dest[i] = {} end | |
719 | + dest = dest or {} | |
720 | + dest[i] = dest[i] or {} | |
688 | 721 | dest[i].vert = dest[i].vert or s |
689 | 722 | end |
690 | 723 | end |
@@ -712,15 +745,12 @@ end | ||
712 | 745 | |
713 | 746 | -- |
714 | 747 | do |
715 | - local font_extra_basename = {} -- key: basename | |
716 | - local cache_ver = 2 | |
748 | + local cache_ver = 3 | |
717 | 749 | local checksum = file.checksum |
718 | 750 | |
719 | 751 | local function prepare_extra_data(n, id) |
720 | 752 | -- test if already loaded |
721 | - if type(id)=='number' then -- sometimes id is an integer | |
722 | - return | |
723 | - elseif (not id) or font_extra_info[n] then return | |
753 | + if (not id) or font_extra_info[n] then return | |
724 | 754 | end |
725 | 755 | local fname = id.filename |
726 | 756 | local bname = file.basename(fname) |
@@ -754,7 +784,10 @@ do | ||
754 | 784 | end |
755 | 785 | luatexbase.add_to_callback('luatexja.define_font', |
756 | 786 | function (res, name, size, id) |
757 | - prepare_extra_data(id, res) | |
787 | + if type(res)~='number' then | |
788 | + prepare_extra_data(id, res) | |
789 | + supply_vkern_table(res) | |
790 | + end | |
758 | 791 | end, |
759 | 792 | 'ltj.prepare_extra_data', 1) |
760 | 793 |
@@ -763,10 +796,56 @@ do | ||
763 | 796 | |
764 | 797 | local identifiers = fonts.hashes.identifiers |
765 | 798 | for i=1,font.nextid()-1 do |
766 | - if identifiers[i] then prepare_extra_data(i, identifiers[i]) end | |
799 | + if identifiers[i] then | |
800 | + prepare_extra_data(i, identifiers[i]) | |
801 | + supply_vkern_table(identifiers[i]) | |
802 | + end | |
767 | 803 | end |
768 | 804 | end |
769 | 805 | |
806 | + | |
807 | +------------------------------------------------------------------------ | |
808 | +-- calculate vadvance | |
809 | +------------------------------------------------------------------------ | |
810 | +do | |
811 | + local function acc_feature(table_vadv, subtables, ft) | |
812 | + for char_num,v in pairs(ft.shared.rawdata.descriptions) do | |
813 | + if v.slookups then | |
814 | + for sn, sv in pairs(v.slookups) do | |
815 | + if subtables[sn] and type(sv)=='table' and sv[4]~=0 then | |
816 | + table_vadv[char_num] | |
817 | + = (table_vadv[char_num] or 0) + sv[4] | |
818 | + end | |
819 | + end | |
820 | + end | |
821 | + end | |
822 | + end | |
823 | + | |
824 | +luatexbase.add_to_callback( | |
825 | + "luatexja.define_jfont", | |
826 | + function (fmtable, fnum) | |
827 | + local vadv = {}; fmtable.v_advance = vadv | |
828 | + local ft = font_getfont(fnum) | |
829 | + local subtables = {} | |
830 | + for feat_name,v in pairs(ft.specification.features.normal) do | |
831 | + if v then | |
832 | + for _,i in pairs(ft.resources.sequences) do | |
833 | + if i.order[1]== feat_name and i.type == 'gpos_single' then | |
834 | + for _,st in pairs(i.subtables) do | |
835 | + subtables[st] = true | |
836 | + end | |
837 | + end | |
838 | + end | |
839 | + end | |
840 | + end | |
841 | + acc_feature(vadv, subtables, ft) | |
842 | + for i,v in pairs(vadv) do | |
843 | + vadv[i]=vadv[i]/ft.units_per_em*fmtable.size | |
844 | + end | |
845 | + return fmtable | |
846 | + end, 1, 'ltj.v_advance' | |
847 | +) | |
848 | +end | |
770 | 849 | ------------------------------------------------------------------------ |
771 | 850 | -- MISC |
772 | 851 | ------------------------------------------------------------------------ |
@@ -139,6 +139,7 @@ local function set_box_stack_level(head, mode) | ||
139 | 139 | end |
140 | 140 | end |
141 | 141 | end |
142 | + --luatexja.ext_show_node_list(head, 'S> ', print) | |
142 | 143 | return head |
143 | 144 | end |
144 | 145 |
@@ -97,11 +97,11 @@ local function capsule_glyph_yoko(p, met, class, head, dir) | ||
97 | 97 | if ht_diff == 0 and dp_diff ==0 then -- offset only |
98 | 98 | set_attr(p, attr_icflag, PROCESSED) |
99 | 99 | setfield(p, 'xoffset', getfield(p, 'xoffset') - fshift.left) |
100 | - setfield(p, 'yoffset', - kbl - fshift.down) | |
100 | + setfield(p, 'yoffset', getfield(p, 'yoffset') - kbl - fshift.down) | |
101 | 101 | return node_next(p), head, p |
102 | 102 | elseif ht_diff >= 0 and dp_diff >=0 then -- rule |
103 | 103 | local box = node_new(id_rule) |
104 | - setfield(p, 'yoffset', - kbl - fshift.down) | |
104 | + setfield(p, 'yoffset', getfield(p, 'yoffset') - kbl - fshift.down) | |
105 | 105 | setfield(box, 'width', 0) |
106 | 106 | setfield(box, 'height', fheight - kbl) |
107 | 107 | setfield(box, 'depth', fdepth + kbl) |
@@ -121,7 +121,9 @@ local function capsule_glyph_yoko(p, met, class, head, dir) | ||
121 | 121 | if need_hbox then |
122 | 122 | local q |
123 | 123 | head, q = node_remove(head, p) |
124 | - setfield(p, 'yoffset', -fshift.down); setfield(p, 'next', nil) | |
124 | + local box = node_new(id_hlist) | |
125 | + setfield(p, 'yoffset', getfield(p, 'yoffset') -fshift.down); | |
126 | + setfield(p, 'next', nil) | |
125 | 127 | setfield(p, 'xoffset', getfield(p, 'xoffset') |
126 | 128 | + char_data.align*(fwidth-pwidth) - fshift.left) |
127 | 129 | local box = node_new(id_hlist) |
@@ -148,11 +150,13 @@ local function capsule_glyph_tate(p, met, class, head, dir) | ||
148 | 150 | local fwidth, pwidth = char_data.width |
149 | 151 | do |
150 | 152 | local pf = getfont(p) |
151 | - local pc = ltjf_get_vert_glyph(pf, getchar(p)) | |
153 | + local pc = getchar(p) -- ltjf_get_vert_glyph(pf, getchar(p)) | |
152 | 154 | setfield(p, 'char', pc) |
153 | - pwidth = ltjf_font_extra_info[pf] and ltjf_font_extra_info[pf][pc] | |
155 | + pwidth = ltjf_font_extra_info[pf] and ltjf_font_extra_info[pf][pc] | |
154 | 156 | and ltjf_font_extra_info[pf][pc].vwidth |
155 | 157 | and ltjf_font_extra_info[pf][pc].vwidth * met.size or (ascent+descent) |
158 | + pwidth = pwidth + (met.v_advance and met.v_advance[pc] or 0) | |
159 | + print(pc, met.v_advance[pc], getfield(p, 'yoffset')) | |
156 | 160 | end |
157 | 161 | fwidth = (fwidth ~= 'prop') and fwidth or pwidth |
158 | 162 | fshift.down = char_data.down; fshift.left = char_data.left |
@@ -160,7 +164,7 @@ local function capsule_glyph_tate(p, met, class, head, dir) | ||
160 | 164 | local fheight, fdepth = char_data.height, char_data.depth |
161 | 165 | |
162 | 166 | local y_shift |
163 | - = - getfield(p, 'yoffset') + (has_attr(p,attr_tkblshift) or 0) | |
167 | + = getfield(p, 'xoffset') + (has_attr(p,attr_tkblshift) or 0) | |
164 | 168 | local q |
165 | 169 | head, q = node_remove(head, p) |
166 | 170 | local box = node_new(id_hlist) |
@@ -170,8 +174,8 @@ local function capsule_glyph_tate(p, met, class, head, dir) | ||
170 | 174 | setfield(box, 'shift', y_shift) |
171 | 175 | setfield(box, 'dir', dir) |
172 | 176 | |
173 | - setfield(p, 'xoffset', -fshift.down) | |
174 | - setfield(p, 'yoffset', - (getfield(p, 'xoffset') + ascent | |
177 | + setfield(p, 'xoffset', - fshift.down) | |
178 | + setfield(p, 'yoffset', getfield(p, 'yoffset') -(ascent | |
175 | 179 | + char_data.align*(fwidth-pwidth) - fshift.left) ) |
176 | 180 | local ws = node_new(id_whatsit, sid_save) |
177 | 181 | local wm = node_new(id_whatsit, sid_matrix) |
@@ -328,6 +328,7 @@ do | ||
328 | 328 | tex_set_attr('global', attr_icflag, 0) |
329 | 329 | if gc == 'fin_row' then return head |
330 | 330 | else |
331 | + --luatexja.ext_show_node_list(head, 'T> ', print) | |
331 | 332 | start_time_measure('jfmglue') |
332 | 333 | local p = ltjj.main(to_direct(head),mode, dir) |
333 | 334 | stop_time_measure('jfmglue') |