diff options
Diffstat (limited to 'language/vietnamese/vntex/fonts/source/vntex/vnr/vnbase.mf')
-rw-r--r-- | language/vietnamese/vntex/fonts/source/vntex/vnr/vnbase.mf | 954 |
1 files changed, 954 insertions, 0 deletions
diff --git a/language/vietnamese/vntex/fonts/source/vntex/vnr/vnbase.mf b/language/vietnamese/vntex/fonts/source/vntex/vnr/vnbase.mf new file mode 100644 index 0000000000..a87e32ce6c --- /dev/null +++ b/language/vietnamese/vntex/fonts/source/vntex/vnr/vnbase.mf @@ -0,0 +1,954 @@ +% Copyright 2003-2005 Han The Thanh <hanthethanh@gmx.net>. +% This file is part of vntex. License: LPPL, version 1.3 or newer, +% according to http://www.latex-project.org/lppl.txt + +% basic macros for all vnr fonts + +% get_acc_pos := 1; +% gen_t5_supp := 1; + +if known get_acc_pos or known gen_t5_supp: + mag := 100.375; +fi + +% define which letters should be generated when testing > 0 +def testchars = +% a.acute_, +% a.dot_, +% a.grave_, +% a.hook_, +% a.tilde_, +% a.breve_, +% a.breve_.acute_, +% a.breve_.dot_, +% a.breve_.grave_, +% a.breve_.hook_, +% a.breve_.tilde_, +% a.circumflex_, +% a.circumflex_.acute_, +% a.circumflex_.dot_, +% a.circumflex_.grave_, +% a.circumflex_.hook_, +% a.circumflex_.tilde_, +% d.bar_, +% e.acute_, +% e.dot_, +% e.grave_, +% e.hook_, +% e.tilde_, +% e.circumflex_, +% e.circumflex_.acute_, +% e.circumflex_.dot_, +% e.circumflex_.grave_, +% e.circumflex_.hook_, +% e.circumflex_.tilde_, +% i.acute_, +% i.dot_, +% i.grave_, +% i.hook_, +% i.tilde_, +% o.acute_, +% o.dot_, +% o.grave_, +% o.hook_, +% o.tilde_, +% o.circumflex_, +% o.circumflex_.acute_, +% o.circumflex_.dot_, +% o.circumflex_.grave_, +% o.circumflex_.hook_, +% o.circumflex_.tilde_, +o.horn_, +o.horn_.acute_, +o.horn_.dot_, +o.horn_.grave_, +o.horn_.hook_, +o.horn_.tilde_, +% u.acute_, +% u.dot_, +% u.grave_, +% u.hook_, +% u.tilde_, +u.horn_, +u.horn_.acute_, +u.horn_.dot_, +u.horn_.grave_, +u.horn_.hook_, +u.horn_.tilde_, +% y.acute_, +% y.dot_, +% y.grave_, +% y.hook_, +% y.tilde_, +last +enddef; + +C.l.last := 256; +C.u.last := 256; + +% copied from plain.mf to make metapost run with ec sources, as mfplain.mp is not +% up-to-date with plain.mf +vardef whatever = save ?; ? enddef; +def killtext text t = enddef; + + +if known testing: % turn testing on +% proofcolor := .4[white, black]; + defaultfont := "Times-Roman"; + defaultscale := 1; + prologues := 1; + show_labels := 1; + if known gensize: + mag := 20/gensize; + else: + mag := 2; + fi +fi + +if unknown exbase: + input exbase; +fi + +if unknown displaying: + displaying := 0; +fi + +let vnchar = ecchar; +let cmchar = ecchar; + +input vncode; % character encoding + +if known testing: +string inputstr; +forsuffixes _u = + A_fam_used, D_fam_used, E_fam_used, I_fam_used, O_fam_used, U_fam_used, Y_fam_used, + a_fam_used, d_fam_used, e_fam_used, i_fam_used, o_fam_used, u_fam_used, y_fam_used: + boolean _u; + _u := false; +endfor; + +def test_fam(text _f, _u, _c) = + n_ := 0; + if not _u: + forsuffixes $ = _f(,) 257: + n_ := n_ + 1; + if (($ < 32) or ($ > 127)) % check for vn chars only + and ($ = C.u._c) or ($ = C.l._c): + _u := true; + fi + endfor + fi +enddef; + +forsuffixes _c = testchars: + test_fam(A_fam)(A_fam_used)(_c); + test_fam(D_fam)(D_fam_used)(_c); + test_fam(E_fam)(E_fam_used)(_c); + test_fam(I_fam)(I_fam_used)(_c); + test_fam(O_fam)(O_fam_used)(_c); + test_fam(U_fam)(U_fam_used)(_c); + test_fam(Y_fam)(Y_fam_used)(_c); + + test_fam(a_fam)(a_fam_used)(_c); + test_fam(d_fam)(d_fam_used)(_c); + test_fam(e_fam)(e_fam_used)(_c); + test_fam(i_fam)(i_fam_used)(_c); + test_fam(o_fam)(o_fam_used)(_c); + test_fam(u_fam)(u_fam_used)(_c); + test_fam(y_fam)(y_fam_used)(_c); + + test_fam(U_horn_fam)(U_fam_used)(_c); + test_fam(u_horn_fam)(u_fam_used)(_c); +endfor + +def input_ur_fam = + inputstr := ""; + if A_fam_used: inputstr := inputstr & "input vnuar; "; fi + if D_fam_used: inputstr := inputstr & "input vnudr; "; fi + if E_fam_used: inputstr := inputstr & "input vnuer; "; fi + if I_fam_used: inputstr := inputstr & "input vnuir; "; fi + if O_fam_used: inputstr := inputstr & "input vnuor; "; fi + if U_fam_used: inputstr := inputstr & "input vnuur; "; fi + if Y_fam_used: inputstr := inputstr & "input vnuyr; "; fi + scantokens(inputstr); +enddef; + +def input_lr_fam = + inputstr := ""; + if a_fam_used: inputstr := inputstr & "input vnlar; "; fi + if d_fam_used: inputstr := inputstr & "input vnldr; "; fi + if e_fam_used: inputstr := inputstr & "input vnler; "; fi + if i_fam_used: inputstr := inputstr & "input vnlir; "; fi + if o_fam_used: inputstr := inputstr & "input vnlor; "; fi + if u_fam_used: inputstr := inputstr & "input vnlur; "; fi + if y_fam_used: inputstr := inputstr & "input vnlyr; "; fi + scantokens(inputstr); +enddef; + +def input_sc_fam = + inputstr := ""; + if a_fam_used: inputstr := inputstr & "input vnuar; "; fi + if d_fam_used: inputstr := inputstr & "input vnudr; "; fi + if e_fam_used: inputstr := inputstr & "input vnuer; "; fi + if i_fam_used: inputstr := inputstr & "input vnuir; "; fi + if o_fam_used: inputstr := inputstr & "input vnuor; "; fi + if u_fam_used: inputstr := inputstr & "input vnuur; "; fi + if y_fam_used: inputstr := inputstr & "input vnuyr; "; fi + scantokens(inputstr); +enddef; + +def input_li_fam = + inputstr := ""; + if a_fam_used: inputstr := inputstr & "input vnlai; "; fi + if d_fam_used: inputstr := inputstr & "input vnldi; "; fi + if e_fam_used: inputstr := inputstr & "input vnlei; "; fi + if i_fam_used: inputstr := inputstr & "input vnlii; "; fi + if o_fam_used: inputstr := inputstr & "input vnloi; "; fi + if u_fam_used: inputstr := inputstr & "input vnlui; "; fi + if y_fam_used: inputstr := inputstr & "input vnlyi; "; fi + scantokens(inputstr); +enddef; + +% def endchar = +% scantokens extra_endchar; +% if proofing>0: makebox(proofrule); fi +% chardx:=w; % desired width of the character in pixels +% shipit; +% endgroup enddef; + +% def makebox(text rule) = +% for y=0,asc_height,body_height,x_height,bar_height,-desc_depth,-body_depth: +% rule((l,y)t_,(r,y)t_); endfor % horizontals +% for x=l,r: rule((x,-body_depth)t_,(x,body_height)t_); endfor % verticals +% for x=u*(1+floor(l/u)) step u until r-1: +% rule((x,-body_depth)t_,(x,body_height)t_); endfor % more verticals +% if charic<>0: +% rule((r+charic*pt,h.o_),(r+charic*pt,.5h.o_)); fi % italic correction +% enddef; + +def bboxcolor = red enddef; +def bboxrule(expr w,z) = + begingroup interim linecap:=squared; + draw w..z withpen pencircle scaled (.4/bp_per_pixel) withcolor bboxcolor; + endgroup +enddef; + +def makebox(text rule) = + for y=0,(cap_height+acc_height), + asc_height,body_height,x_height,bar_height,-desc_depth,-body_depth: + rule((l,y),(r,y)); endfor % horizontals + + for y=-3.5pt,8.5pt,(x_height+acc_height): + rule((l-4pt,y),(l-2pt,y)); endfor + for x=l,r: rule((x,-body_depth),(x,body_height)); endfor % verticals + for x=u*(1+floor(l/u)) step u until r-1: + rule((x,-body_depth),(x,body_height)); endfor % more verticals + + for x=0.5w: + rule((x,-body_depth-1pt),(x,-body_depth-1.5pt)); + rule((x,cap_height+acc_height+1pt),(x,cap_height+acc_height+1.5pt)); + endfor + if charic<>0: + rule((r+charic*pt,h.o_),(r+charic*pt,.5h.o_)); fi % italic correction + enddef; + +def makebbox(text rule) = + for x=0,w: bboxrule((x,-d),(x,h)); endfor % verticals + for y = 0,h,-d: bboxrule((0, y), (w, y)); endfor +enddef; + +def endchar = + scantokens extra_endchar; + if proofing>0: +% makebox(proofrule); + makebbox(proofrule); + fi + shipit; +endgroup +enddef; + +fi % known testing + +% if (known show_labels) and (known testing): +% if (known show_labels): +% def makebox(text r) = +% for y = 0, h, -d: +% r((0, y), (w, y)); +% endfor % horizontals +% for x = 0, w: +% r((x, -d), (x, h)); +% endfor % verticals +% enddef; +% def draw_box(expr x, y, w, h, p) = +% pickup pencircle scaled p; +% draw (x, y) -- (x, y + h) -- (x + w, y + h) -- (x + w, y) -- (x, y); +% enddef; +% else: +% def makebox(text r) = enddef; +% def draw_box(expr x, y, w, h) = enddef; +% def penlabels(text r) = enddef; +% proofcolor := black; +% fi; + +numeric case_; +small := 0; +capital := 1; +smallcap := 2; + +def set_lowercase = + case_ := small; + def vncase = l enddef; +enddef; + +def set_uppercase = + case_ := capital; + def vncase = u enddef; +enddef; + +def set_smallcap = + case_ := smallcap; + def vncase = l enddef; +enddef; + +def casename expr _name = +if not known testing: + "The " & + if case_ = capital: + "capital" + elseif case_ = small: + "small" + else: + "smallcap" + fi & + " letter " & _name +fi +enddef; + +def ifknown(suffix _a)(expr _b) = + if known _a: _a + else: _b + fi +enddef; + +def tand(expr _d) = + (sind(_d)/cosd(_d)) +enddef; + +def vn_code(suffix _n) = + C.vncase._n +enddef; + +def vn_pic(suffix _n) = + vn.vncase._n.pic +enddef; + +def vn_width(suffix _n) = + vn.vncase._n.w# +enddef; + +def vn_height(suffix _n) = + vn.vncase._n.h# +enddef; + +def vn_top(suffix _n) = + vn.vncase._n.top# +enddef; + +def vn_depth(suffix _n) = + vn.vncase._n.d# +enddef; + +def vn_bot(suffix _n) = + vn.vncase._n.bot# +enddef; + +def vn_ic(suffix _n) = + vn.vncase._n.ic# +enddef; + +def vn_left_adj(suffix _n) = + vn.vncase._n.left_adj# +enddef; + +def vn_right_adj(suffix _n) = + vn.vncase._n.right_adj# +enddef; + +def vn_gap(suffix _n) = + vn.vncase._n.gap# +enddef; + +def vn_join_xp(suffix _n) = + vn.vncase._n.join.x +enddef; + +def vn_join_x(suffix _n) = + vn.vncase._n.join.x# +enddef; + +def vn_rt(suffix _n) = + vn.vncase._n.rt# +enddef; + +def vn_dot_shift_y(suffix _n) = + vn.vncase._n.dot_shift.y# +enddef; + +def vn_ac_top = + vn.vncase.accent_top# +enddef; + +def vn_double_ac_top = + vn.vncase.double_accent_top# +enddef; + +let vn_left_side = vn_join_x; + +def vn_right_side(suffix _a) = + (vn_width(_a) - vn_left_side(_a)) +enddef; + +def align_left(suffix _a, _b) = + 0 +enddef; + +def vn_align_join(suffix _a, _b) = + (vn_join_x(_a) - vn_join_x(_b)) +enddef; + +def vn_align_right(suffix _a, _b) = + (vn_width(_a) - vn_width(_b)) +enddef; + +def define_accent_dimens(suffix _a)(expr _w, _h) = + vn_width(_a) := _w; + vn_height(_a) := _h; + vn_top(_a) := vn_height(_a) + vn_letter_height# + vn_accent_gap#; + vn_max_ac_top# := max(vn_max_ac_top#, vn_top(_a)); +enddef; + +def vn_set_ac_join(suffix _a)(expr _xp, _x, _rt) = + vn_join_xp(_a) := _xp; + vn_join_x(_a) := _x; + vn_rt(_a) := _rt; + if known show_labels: + makelabel("j", (vn_join_xp(_a), 0)); + makelabel("J", (hp(vn_join_x(_a)), 0)); + makelabel("r", (hp(vn_width(_a)), vp(vn_rt(_a)))); + makelabel("o", (0,0)); + fi +enddef; + +def set_letter_join(suffix _l)(expr _xp, _x) = + vn_join_xp(_l) := _xp; + vn_join_x(_l) := _x; + if known show_labels: + makelabel("j", (vn_join_xp(_l), vp(vn_height(_l)))); + makelabel("J", (hp(vn_join_x(_l)), vp(vn_height(_l)))); + fi +enddef; + +def set_adj_gap(suffix _l, _a) = + adj_gap# := ifknown(vn_gap(_l._a), ifknown(vn_gap(_a), 0)); +enddef; + +def get_join_xp(suffix _l, _a) = + ifknown(vn_join_xp(_l._a), vn_join_xp(_l)) +enddef; + +def get_join_x(suffix _l, _a) = + ifknown(vn_join_x(_l._a), vn_join_x(_l)) +enddef; + +def get_top(suffix _a) = + max(vn_top(_a) + adj_gap#, + if vn_top(_a) <= vn_ac_top: + vn_ac_top + else: + vn_double_ac_top + fi) +enddef; + +def set_shift(suffix _l, _a) = + shift.y := vp(vn_top(_a) - vn_height(_a)); + shift.x := get_join_xp(_l, _a) - vn_join_xp(_a) + slant*shift.y; + shift.y# := vn_top(_a) - vn_height(_a); + shift.x# := get_join_x(_l, _a) - vn_join_x(_a) + slant*shift.y#; +enddef; + +def set_ic(suffix _l, _a) = + italcorr max(vn_ic(_l), + vn_width(_a) + shift.x# + + slant*(vn_rt(_a) + shift.y#) + - w# + .5u#); +enddef; + +def set_lic(suffix _l) = + italcorr vn_ic(_l); +enddef; + +def set_fit(suffix _l) = + adjust_fit(vn_left_adj(_l), vn_right_adj(_l)); +enddef; + +C.l.idot.dot_ = 256; +C.u.idot.dot_ = 256; % to avoid error when calling set_dot_shift(idot) + +def set_dot_shift(suffix _l) = + shift.y := - vp(ifknown(vn_dot_shift_y(_l), vn_bot(dot_))); + shift.x := get_join_xp(_l, dot_) - vn_join_xp(dot_) + slant*shift.y; +enddef; + +% vardef xpos@#(expr b ,d) = +% pos@#(max(currentbreadth + eps, b), d) +% enddef; +vardef pos@#(expr b,d) = + if known b: if b<=currentbreadth: + (x@#r-x@#l,y@#r-y@#l)=(eps,0) rotated d; + else: (x@#r-x@#l,y@#r-y@#l)=(b-currentbreadth,0) rotated d; fi + else: (x@#r-x@#l,y@#r-y@#l)=(b-currentbreadth,0) rotated d; fi + x@#=.5(x@#l+x@#r); y@#=.5(y@#l+y@#r) +enddef; + +def hp(expr _x) = + hround(_x*hppp) +enddef; + +def vp(expr _y) = + vround(_y*vppp) +enddef; + +def begin_pic(suffix _n) = + begingroup + clearxy; + clearit; + clearpen; + picture vn.vncase._n.pic; + vn.vncase._n.pic := + begingroup +enddef; + +def end_pic = + if known testing: +% makebox(proofrule); + makebbox(proofrule); + fi + currentpicture % continuation of `vn_pic(_n) :=' + endgroup; + endgroup +enddef; + +def set_letter_dimens(suffix _l)(expr _w, _h, _d, _ic, _lft, _rt) = + set_char_dimens(_w, _h, _d); + vn_width(_l) := _w; + vn_height(_l) := _h; + vn_depth(_l) := _d; + vn_ic(_l) := _ic; + vn_left_adj(_l) := _lft; + vn_right_adj(_l) := _rt; + adjust_fit(_lft, _rt); +enddef; + +def begin_accent(suffix _a) = + begin_pic(_a); + set_char_dimens(vn_width(_a), vn_height(_a), 0) +enddef; +let end_accent = end_pic; + +let begin_letter = begin_pic; +let end_letter = end_pic; + +def vn_sl_shift(suffix _a) = +% .5slant*(adj_y# + vn_height(_a)) + 0 +enddef; + +def set_char_dimens(expr _w, _h, _d) = + charwd := _w; + charht := _h; + chardp := _d; + w := hp(charwd); + h := vp(charht); + d := vp(chardp); + charic := 0; +enddef; + +def abs_round(expr _e) = + if _e < 0: + ceiling(_e - .5) + else: + floor(_e + .5) + fi +enddef; + +def write_shift_xy(suffix _l, _a)(expr _sx, _sy) = + if known get_acc_pos and known bp_per_pixel: + message "CC " & + if case_ = capital: + "capital" + elseif case_ = small: + "small" + else: + "smallcap" + fi & " " & + str _l & " " & + str _a & " " & + decimal(abs_round(_sx*bp_per_pixel*10/designsize)) & " " & + decimal(abs_round(_sy*bp_per_pixel*10/designsize)); + fi +enddef; + + +def define_double_accent(suffix _a, _b)(expr _adj_x, _adj_y) = + shift.y# := _adj_y + vn_height(_a); + shift.x# := _adj_x + slant*shift.y#; + define_accent_dimens(_a._b, vn_width(_a), vn_height(_b) + shift.y#); + begin_accent(_a._b); + currentpicture := vn_pic(_a); + addto currentpicture also vn_pic(_b) + shifted (hp(shift.x#), vp(shift.y#)); + write_shift_xy(_a, _b)(hp(shift.x#), vp(shift.y#)); + vn_set_ac_join(_a._b, vn_join_xp(_a), vn_join_x(_a), + if vn_width(_a) + slant*vn_rt(_a) > + vn_width(_b) + shift.x# + slant*(vn_rt(_b) + shift.y#): + vn_rt(_a) + else: + vn_rt(_b) + shift.y# + fi); + end_accent; +enddef; + +if not known testing: +vardef used_char(expr _code) = true enddef; +else: +vardef used_char(expr _code) = + boolean _is_used; + _is_used := false; + forsuffixes $ = testchars: + if _code = vn_code($): + _is_used := true; + fi; + endfor; + _is_used +enddef; +fi + +def define_vnaccent(expr _c)(suffix _a) = + beginchar(_c, vn_width(_a), vn_height(_a), 0); + currentpicture := vn_pic(_a); + endchar +enddef; + +def define_vnchar(suffix _l, _a) = +if used_char(vn_code(_l._a)): + set_adj_gap(_l, _a); % set adj_gap# + beginchar(vn_code(_l._a), + vn_width(_l), + get_top(_a), + vn_depth(_l)); + set_shift(_l, _a); % set shift.x, shift.y, shift.x# and shift.y# + set_ic(_l, _a); % call italcorr + set_fit(_l); % call adjust_fit + currentpicture := vn_pic(_l); + addto currentpicture also vn_pic(_a) + shifted (shift.x, shift.y + vp(adj_gap#)); + write_shift_xy(_l, _a) + (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y + vp(adj_gap#)); +% message "vn_left_adj: " & decimal hp(vn_left_adj(_l)); +% message "letter_fit: " & decimal letter_fit; + endchar +fi +enddef; + +def define_vnchar_dot(suffix _l) = +if used_char(vn_code(_l.dot_)): + % test for the small i letter with dot + if (case_ = small) and (vn_code(_l.dot_) = vn_code(i.dot_)): + beginchar(vn_code(i.dot_), + vn_width(idot), + vn_height(idot), + vn_bot(dot_)); + set_dot_shift(idot); % set shift.x and shift.y + set_lic(idot); % call italcorr + set_fit(idot); % call adjust_fit + currentpicture := vn_pic(idot); + else: + beginchar(vn_code(_l.dot_), + vn_width(_l), + vn_height(_l), + ifknown(vn_depth(_l.dot_), max(vn_bot(dot_), vn_depth(_l)))); + set_dot_shift(_l); + set_lic(_l); + set_fit(_l); + currentpicture := vn_pic(_l); + fi + addto currentpicture also vn_pic(dot_) + shifted (shift.x, shift.y); + write_shift_xy(_l, dot_) + (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y); + endchar +fi +enddef; + +def define_vnchar_dot_ac(suffix _l, _a) = +if used_char(vn_code(_l._a.dot_)): + set_adj_gap(_l, _a); + beginchar(vn_code(_l._a.dot_), + vn_width(_l), + get_top(_a), + max(vn_bot(dot_), vn_depth(_l))); + set_shift(_l, _a); + set_ic(_l, _a); + set_fit(_l); + currentpicture := vn_pic(_l); + addto currentpicture also vn_pic(_a) + shifted (shift.x, shift.y + vp(adj_gap#)); + set_dot_shift(_l); + addto currentpicture also vn_pic(dot_) + shifted (shift.x, shift.y); + write_shift_xy(_l._a, dot_) + (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y); + endchar +fi +enddef; + +def define_vnchar_horn(suffix _l) = +if used_char(vn_code(_l.horn_)): + select_horn(_l); + set_shift_horn(_l); + update_horn_width(_l); + beginchar(vn_code(_l.horn_), + updated_width#, + vn_top(cur_horn_), + vn_depth(_l)); + set_ic(_l, cur_horn_); + set_fit(_l); + select_letter_u(_l); + addto currentpicture also vn_pic(cur_horn_) + shifted (shift.x, shift.y); + endchar +fi +enddef; + +def select_horn(suffix _l) = % set cur_horn_ to uhorn_ or ohorn_ according to _l + if vn_code(_l.horn_) = vn_code(u.horn_): + def cur_horn_ = uhorn_ enddef; + else: + def cur_horn_ = ohorn_ enddef; + fi +enddef; + +def update_horn_width(suffix _l) = + _du := (shift.x + hp(vn_width(cur_horn_))) - + (hp(vn_width(_l) + vn_left_adj(_l) + vn_right_adj(_l)) + 2letter_fit) - + slant*(shift.y + vp(vn_height(cur_horn_))); + updated_width# := vn_width(_l) + if _du > .5u: + + .5u#*floor(_du/.5u) + fi +enddef; + +def set_shift_horn(suffix _l) = + shift.y := vp(vn_bot(cur_horn_)); + shift.x := vn_join_xp(_l.horn_join) - vn_join_xp(cur_horn_) + + slant*(shift.y); +enddef; + +def select_letter_u(suffix _l) = + % test for the serif capital u letter with horn + if serifs and (case_ <> small) and (vn_code(_l.horn_) = vn_code(u.horn_)): + % use the modified "U" (without right part of the right serif) + currentpicture := vn_pic(Uhorn) + else: + currentpicture := vn_pic(_l) + fi +enddef; + +def define_vnchar_horn_ac(suffix _l, _a) = +if used_char(vn_code(_l.horn_._a)): + select_horn(_l); % set cur_horn_ to uhorn_ or ohorn_ according to _l + set_adj_gap(_l, _a); + set_shift_horn(_l); + update_horn_width(_l); + beginchar(vn_code(_l.horn_._a), + updated_width#, + get_top(_a), + vn_depth(_l)); + set_ic(_l, cur_horn_); + set_fit(_l); + select_letter_u(_l); + addto currentpicture also vn_pic(cur_horn_) + shifted (shift.x, shift.y); + set_shift(_l.horn_, _a); +% if serifs and (vn_code(_l.horn_._a) = vn_code(o.horn_.grave_)): +% shift.x := shift.x + max(0, u - .3stem); +% fi + set_ic(_l, _a); + addto currentpicture also vn_pic(_a) + shifted (shift.x, shift.y + vp(adj_gap#)); + write_shift_xy(_l.horn_, _a) + (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y + vp(adj_gap#)); + endchar +fi +enddef; + +def define_vnchar_horn_dot(suffix _l) = +if used_char(vn_code(_l.horn_.dot_)): + select_horn(_l); % set cur_horn_ to uhorn_ or ohorn_ according to _l + set_shift_horn(_l); + update_horn_width(_l); + beginchar(vn_code(_l.horn_.dot_), + updated_width#, + vn_top(cur_horn_), + max(vn_bot(dot_), vn_depth(_l))); + set_ic(_l, cur_horn_); + set_fit(_l); + select_letter_u(_l); + addto currentpicture also vn_pic(cur_horn_) + shifted (shift.x, shift.y); + set_dot_shift(_l); +% if serifs and (vn_tt_corr = 0) and (vn_code(_l.horn_) = vn_code(o.horn_)): +% shift.x := shift.x + .1dot_size; +% fi + addto currentpicture also vn_pic(dot_) + shifted (shift.x, shift.y); + write_shift_xy(_l.horn_, dot_) + (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y); + endchar +fi +enddef; + +% hook_arc is based on super_arc from exbase.mf +vardef hook_arc.r(suffix $, $$)(expr _superness, _swap) = + pair center, corner; + if (y$ = y$r) or _swap: + center = (x$$r, y$r); + corner = (x$r, y$$r); + else: + center = (x$r, y$$r); + corner = (x$$r, y$r); + fi + z$.r{corner - z$.r} ... _superness[center, corner]{z$$.r - z$.r} ... + {z$$.r - corner}z$$.r +enddef; + +vardef hook_arc.l(suffix $, $$)(expr _superness, _swap) = + pair center, corner; + if (y$ = y$r) or _swap: + center = (x$$l, y$l); + corner = (x$l, y$$l); + else: + center = (x$l, y$$l); + corner = (x$$l, y$l); + fi + z$l{corner - z$l} ... _superness[center, corner]{z$$l - z$l} ... + {z$$l - corner}z$$l +enddef; + +% vn_hook_bulb is based on bulb from exbase.mf +def vn_hook_bulb(suffix $, $$, $$$) = + z$$$r = z$$r; + path_.l := z$l{x$$r - x$r, 0} ... {0, y$$r - y$r}z$$l; + filldraw path_.l -- z$$r{0, y$r - y$$r} ... {x$r - x$$r, 0}z$r -- cycle; % link + path_.r := z$$$l{0, y$r - y$$r} .. z$$$r{0, y$$r - y$r}; % near - circle + filldraw subpath(0, xpart(path_.r intersectiontimes path_.l)) of path_.r + -- z$$r{0, y$$r - y$r} .. cycle; % bulb +enddef; + +def vn_draw_horn(suffix _a)(expr _dotsize, _horn_stem, _horn_bot_theta) = + cur_dotsize# := _dotsize; + cur_stem# := _horn_stem; + define_blacker_pixels(cur_dotsize, cur_stem); + if not square_dots: + pickup crisp.nib; + pos4(cur_dotsize, 90); + top y4r = h; + x4 = w - .5cur_dotsize; + pos1(cur_stem, 90); + pos2(cur_stem, 0); + pos3(cur_stem, _horn_bot_theta - 90); + z1r = z4r; + rt x2r = hround(x4 + .5cur_dotsize) + 2eps; + lft x3l = 0; + bot y3r = 0; + y2 = 1/3[y1, y3]; + y_ := ypart((z1{right} ... z2{down} ... z3) + intersectiontimes (z4l{right} .. {left}z4r)); + if y_ < 0: + y_ := 1; + fi + filldraw z4r{left} .. subpath (0, y_) of (z4l{right} .. {left}z4r) + -- cycle; % dot + filldraw stroke z1e{right} ... z2e{down} ... {left}z3e; + filldraw z1r--z2r--z4l--cycle; + penlabels(0, 1, 2, 3, 4); + vn_set_ac_join(_a, x3, .5cur_stem*sind(_horn_bot_theta), + h# - .5cur_dotsize#); + else: + pickup fine.nib; + pos4(cur_dotsize, 90); + top y4r = h; + x4 = w - .5cur_dotsize; + pos4'(cur_dotsize, 0); + z4' = z4; + dot(4', 4); % squarish dot + horn_join := max(fine.breadth, floor cur_stem); + horn_bot := max(fine.breadth, floor .8cur_stem); + pos0(horn_join, 0); + pos1(horn_join, 0); + pos2(horn_bot, 0); + y0 = y4; + y1 = y4l; + x0r = x1r = x4'r; + lft x2l = 0; + bot y2r = 0; + z2' = whatever[z1, z2]; + numeric _vn_bot_width; + pos2'(_vn_bot_width, -90 + _horn_bot_theta); + z2l = z2'l; + filldraw stroke z0e -- z1e .. z2'e; % tail + penlabels(0, 1, 2', 3, 4); + vn_set_ac_join(_a, x2', 0, h#); + fi + vn_bot(_a) := vn_top(_a) - vn_height(_a); +enddef; + +def set_horn_join(suffix _l)(expr _pl, _pr) = + select_horn(_l); % set cur_horn_ to uhorn_ or ohorn_ according to _l + path bot_line; + pair L, R; + bot_line := (.5w, vp(vn_bot(cur_horn_))) -- (w, vp(vn_bot(cur_horn_))); + L := point xpart(bot_line intersectiontimes _pl) of bot_line; + R := point xpart(bot_line intersectiontimes _pr) of bot_line; + vn_set_ac_join(_l.horn_join, xpart .5[L, R], 0, 0); +enddef; + +def lig_CGQ_table(expr k) = + "C" kern k, "G" kern k, "Q" kern k +enddef; + +def end_ligtable = 0 kern 0 enddef; + +% define input_lig to generate only char oct"031" from excspl.mf +def input_lig suffix @# = + let save_endchar = endchar; + let endchar = lig_endchar; + scantokens("input " & str @#); + relax; + let endchar = save_endchar; +enddef; + +def lig_endchar = + if charcode = oct"031": + save_endchar + else: + endgroup + fi +enddef; + +def generate suffix @# = + scantokens("input null"); % can't figure out why it's needed + scantokens("input vn" & substring(2, length(str @#)) of str @#); +enddef; + +endinput; |