% \iffalse %\ProvidesFile{vnbase.dtx}[2003/11/01 v01.01 VNR.KTV.DTX.Base] % \fi % % \section{Basic macros} % % \begin{macrocode} %<*vnbase> % \end{macrocode} % % §Þnh nghÜa tÊt c¶ c¸c macro ®­îc dïng bëi |VNR|. % % \subsection{Generic Macros} % % \danger % V× |mfplain.mp| kh«ng ®­îc cËp nhËt cïng víi |plain.mf|, % nªn ®Ó |MetaPost| cã thÓ lµm viÖc víi |ec| fonts, % ta ph¶i cÇn c¸c dßng sau (chÐp tõ |plain.mf|). % \endanger % % \begin{macrocode} %<*test> vardef whatever = save ?; ? enddef; def killtext text t = enddef; % % \end{macrocode} % % \begin{macrocode} if unknown exbase: input exbase; fi; % \end{macrocode} % % \begin{macrocode} if unknown displaying: displaying := 0; fi % \end{macrocode} % Trong *exbase.mf*, macro *ecchar* ®­îc ®Þnh nghÜa bëi *|let ecchar=\;|*. % \begin{macrocode} let vnchar = ecchar; let cmchar = ecchar; % \end{macrocode} % % Load |T5| |encoding| vµ c¸c macro ®Þnh nghÜa c¸c hä ch÷ c¸i, hä dÊu. % \begin{macrocode} input vncode; % \end{macrocode} % % \subsection{Test: Parameters} % % Parameter for |t5supp-encoding|. % \begin{macrocode} %<*t5supp> % get_acc_pos := 1; % gen_t5_supp := 1; % if known get_acc_pos or known gen_t5_supp: mag := 100.375; % fi % % \end{macrocode} % % *(KTV,2003/11/02):* % ViÖc ®Æt *|defaultfont:="Times-Roman"|* sÏ sinh ra lçi % (kh«ng t×m thÊy font |tfm|) t­¬ng øng. % Xem thªm trong \href{../doc/vnr_bug_fix.dvi}{vnr_bug_fix}. % % *(KTV,2003/11/13):* % Ph¶i dïng *|prologues:=1|* míi cã thÓ |merge| c¸c output t¹o bëi % |MetaPost| b»ng |mpmergeps.py|. % (Ch­a kiÓm tra ®iÒu nµy víi |mergemps.py|.) % \begin{macrocode} %<*test> % show_labels := 1; % value passed in the `makefile' % makeXbox := 0; % value passed in the `makefile' defaultscale := 1; prologues := 1; %defaultfont := "Times-Roman"; if known black_proof: proofcolor := .9999[white, black]; else: proofcolor := .3[white, black]; fi if known gensize: mag := 20/gensize; else: mag := 2; fi if known no_labels: def penlabels(text _list) = enddef; fi % % \end{macrocode} % % \subsection{Test: Letters} % % Danh s¸ch c¸c ch÷ c¸i ®­îc vÏ khi trong \tstmode. % Muèn |test| ch÷ c¸i nµo th× chØ viÖc bá dÊu |%| ë tr­íc ch÷ ®ã. % Cã thÓ thùc hiÖn c¸c phÐp g¸n, vÝ dô: *|test_grave:=1|*. % \emph{L­u ý:} nh÷ng ch÷ c¸i ®­îc test sÏ gåm c¶ ch÷ hoa lÉn ch÷ th­êng. % (Xem ®Þnh nghÜa cña *grave_fam*, *acute_fam*,... ë \lref{def:accent_fam}, % ®Þnh nghÜa cña *a_fam*, *d_fam*,... ë \lref{def:letter_fam}.) % % \begin{multicols}3 % \begin{macrocode} %<*test> def testchars = %<=def:testchars> if known test_grave: grave_fam(,) fi if known test_acute: acute_fam(,) fi if known test_tilde: tilde_fam(,) fi if known test_hook: hook_fam(,) fi if known test_dot: dot_fam(,) fi if known test_a: a_fam(,) fi if known test_e: e_fam(,) fi if known test_i: i_fam(,) fi if known test_o: o_fam(,) fi if known test_u: u_fam(,) fi if known test_uhorn: uhorn_fam(,) fi if known test_y: y_fam(,) fi if known test_d: d_fam(,) fi if known test_all_chars: full_fam(,) fi % 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; % % \end{macrocode} % \end{multicols} % % \danger % Ta thªm vµo danh s¸ch trªn ch÷ c¸i ¶o |last|. \emph{Môc ®Ých:} % Khi dïng vßng lÆp |for| ®Ó duyÖt qua danh s¸ch % |testchars|, ta ph¶i biÕt lóc nµo th× kÕt thóc danh s¸ch. % Ch÷ c¸i ¶o |last| t¹o ®iÒu kiÖn ®Ó kiÓm tra. % Nh­ vËy, |last| ph¶i lu«n ®­îc |test|: % ta kh«ng ®­îc phÐp bá ®i |last| trong danh s¸ch nãi trªn. % \endanger % % \begin{macrocode} % C.l.last := C.u.last := 256; % \end{macrocode} % % \subsection{Test: Macros} % % \begin{macro}{used_char} % Macro nµy kiÓm tra xem \meta{char} víi m· |_code| cã n»m trong % danh s¸ch |testchars| hay kh«ng. NÕu cã, \meta{char} nµy sÏ ®­îc vÏ. % ChØ trong \tstmode\ míi cã sù kiÓm tra nµy, cßn trong b¶n % \meta{publish} cña |VNR-METAFONT| th× macro |used_char| ®­îc bá qua. % Xem ®Þnh nghÜa cña macro |define_vnchar| (\lref{def:define_vnchar}). % \begin{macrocode} %<*test> vardef used_char(expr _code) = %<=def:used_char> boolean _is_used; if not known test_all_chars: _is_used := false; forsuffixes $ = testchars: if _code = vn_code($): _is_used := true; fi; endfor; else: _is_used := true; fi; _is_used enddef; % % \end{macrocode} % \end{macro} % % Khai b¸o 14 biÕn kiÓu |BOOLEAN|. % C¸c biÕn nµy ®­îc g¸n gi¸ trÞ ban ®Çu |FALSE|. % % \emph{VÝ dô:} biÕn |a_fam_used| cã gi¸ trÞ |TRUE| nÕu mét trong c¸c % ch÷ c¸i |a|, |¸|, |µ|, |¶|, |·|, |¹| ®­îc |test|. L­u ý r»ng, % c¸c ch÷ c¸i |a|, |¸|, |µ|, |¶|, |·|, |¹| ®­îc vÏ theo c¸ch \emph{t­¬ng % tù} nhau, nªn ta chØ cÇn \emph{dïng mét biÕn} lµ |a_fam_used|: % nÕu |a_fam_used| b»ng |TRUE|, th× ta sÏ |load| m· |MF| ®Ó vÏ c¸c % ch÷ |a|, m· nµy ®Æt trong |vnlar|. % % Xem thªm ®Þnh nghÜa cña |input_lr_fam|, |input_ur_fam| bªn d­íi. % % \begin{macrocode} %<*test> 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; % % \end{macrocode} % % Gi¶ sö trong |test_char|, \meta{char} cã m· |_c| ®­îc \meta{test}. % Khi ®ã, ta sÏ t×m xem \meta{char} nµy n»m trong hä nµo (|A_fam|, % |e_fam|, v.v...). NÕu (vÝ dô) nã n»m trong hä |a_fam|, th× ta sÏ g¸n % biÕn |a_fam_used| gi¸ trÞ |TRUE|. % % \begin{macro}{test_fam} % % Macro |test_fam| d­íi ®©y cã nhiÖm % vô tr¶ lêi xem \meta{char} víi m· |_c| cã n»m trong hä |_f| hay kh«ng; % nÕu cã th× g¸n |_u| b»ng |TRUE|. \emph{L­u ý:} c¸c \meta{char} (tiÕng % ViÖt) chØ cã m· hoÆc nhá h¬n |32|, hoÆc lín h¬n |127|. % % \begin{macrocode} %<*test> def test_fam(text _f, _u, _c) = n_ := 0; if not _u: forsuffixes $ = _f(,) 257: n_ := n_ + 1; if (($ < 32) or ($ > 127)) and ($ = C.u._c) or ($ = C.l._c): _u := true; fi endfor fi enddef; % % \end{macrocode} % \end{macro} % % B©y giê, ta duyÖt qua tÊt c¶ c¸c hä (ch÷ hoa) ®Ó xem |_c| thuéc hä nµo. % Râ rµng, mçi \meta{char} chØ thuéc mét vµ chØ mét hä mµ th«i, nªn ta cã % thÓ c¶i thiÖn viÖc duyÖt b»ng c¸ch dïng |if...elif...if|. (Nh­ng viÖc % nµy kh«ng \emph{kinh tÕ}l¾m.) % % \begin{multicols}2 % \begin{macrocode} %<*test> 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 % % \end{macrocode} % \end{multicols} % % BiÕn |inpustr| ®­îc dïng trong 4 macro s¾p tíi. % % \begin{macrocode} %string inputstr; % \end{macrocode} % % \begin{macro}{input_ur_fam} % Xem hä ch÷ nµo ®­îc dïng th× |load| m· |MF| ®Ó vÏ hä t­¬ng øng. % \up ë ®©y lµ hä c¸c ch÷ hoa. % \begin{macrocode} %<*test> 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; % % \end{macrocode} % \end{macro} % % \begin{macro}{input_lr_fam} % |Load| m· vÏ c¸c ch÷ th­êng. % \begin{macrocode} %<*test> 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; % % \end{macrocode} % \end{macro} % % \begin{macro}{input_sc_fam} % |Load| m· vÏ c¸c ch÷ |small-cap|. % \begin{macrocode} %<*test> 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; % % \end{macrocode} % \end{macro} % % \begin{macro}{input_li_fam} % |Load| m· vÏ c¸c ch÷ nghiªng. % \begin{macrocode} %<*test> 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; % % \end{macrocode} % \end{macro} % % \begin{macro}{bboxcolor} % \begin{macro}{bbxorule} % Macro |bboxrule| dïng ®Ó vÏ ®o¹n th¼ng nèi hai ®iÓm |w| vµ |z|, % víi mµu lµ |bboxcolor| vµ kiÓu ®­êng th¼ng lµ |linecap|. % \emph{L­u ý:} |linecap| lµ biÕn |internal| cña |MetaPOST|. % % \danger % NÕu ta muèn t¹m thêi quªn ®i gi¸ trÞ cña mét biÕn |internal|, ë ®©y lµ % biÕn |linecap|, th× dïng |interim| trong mét |group|. Sau |group| ®ã, % gi¸ trÞ cò cña biÕn |internal| sÏ ®­îc phôc håi. §èi víi biÕn |external|, % ta dïng hµm |save| thay v× |interim|. % \endanger % \begin{macrocode} %<*test> 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; % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{makebbox} % VÏ bèn c¹nh cña h×nh ch÷ nhËt bao quanh \meta{h×nh vÏ} % víi kÝch th­íc cña h×nh ch÷ nhËt b»ng kÝch th­íc cña \meta{h×nh vÏ}. % \meta{H×nh vÏ} ë ®©y lµ \meta{char} hoÆc \meta{accent}. % \begin{macrocode} %<*test> def makebbox(text rule) = if known makeXbox: for x = 0,w: bboxrule((x,-d),(x,h)); endfor for y = 0,h,-d: bboxrule((0,y),(w,y)); endfor fi enddef; % % \end{macrocode} % \end{macro} % % \begin{macro}{makebox} % VÏ l­íi gåm c¸c ®o¹n th¼ng ®i qua c¸c ®iÓm ®Æc biÖt. % \danger % Macro nµy dïng ®Ó kÕt thóc viÖc vÏ \meta{char}, % kh«ng dïng ®Ó kÕt thóc viÖc vÏ \meta{accent}.\\ % Cã thÓ xem chó thÝch vÒ macro nµy trong \mfb E/309/. % \endanger % \begin{macrocode} %<*test> def makebox(text rule) = % \end{macrocode} % VÏ b¶y (7) ®­êng th¼ng n»m ngang: mét ®­êng ®i qua gèc täa ®é; % mét ®­êng ®i ë ®é s©u |body_depth| -- ®­êng nµy kh«ng thÓ thÊy ®­îc % nÕu ta xem kÕt qu¶ do viÖc |merge| c¸c file "PS" t¹o bëi "MetaPost". % \begin{macrocode} 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 % \end{macrocode} % \begin{macrocode} for y = -3.5pt, 8.5pt, (x_height + acc_height): rule((l-4pt,y),(l-2pt,y)); endfor % \end{macrocode} % VÏ c¸c ®­êng th¼ng ®øng. % \begin{macrocode} for x=l,r: rule((x,-body_depth),(x,body_height)); endfor % \end{macrocode} % VÏ c¸c ®­êng th¼ng ®øng phô. % \begin{macrocode} for x = u*(1 + floor(l/u)) step u until r-1: rule((x,-body_depth),(x,body_height)); endfor 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 % \end{macrocode} % VÏ thªm ®­êng th¼ng ®øng nÕu |charic <> 0|. % \begin{macrocode} if charic <> 0: rule((r + charic*pt, h.o_), (r + charic*pt,.5h.o_)); fi enddef; % % \end{macrocode} % \end{macro} % % \subsection{Test: enchar} % % \begin{macro}{endchar} % Sau khi kÕt thóc viÖc vÏ mét \meta{char}, % ta vÏ h×nh ch÷ nhËt bao quanh \meta{char} ®ã (b»ng |makebbox|), % vµ vÏ l­íi gåm c¸c ®­êng th¼ng ®Æc biÖt (b»ng |makebox|). % % \danger % Xem trong |METAFONTBook| vÒ |proofrule|. % \endanger % \begin{macrocode} %<*test> def endchar = scantokens extra_endchar; % if proofing > 0: if known makeXbox: makebox(proofrule); makebbox(proofrule); fi shipit; endgroup enddef; % % \end{macrocode} % \end{macro} % % \subsection{Writting Shifting Information} % % \begin{macro}{abs_round} % \begin{macrocode} %<*t5supp> def abs_round(expr _e) = if _e < 0: ceiling(_e - .5) else: floor(_e + .5) fi enddef; % % \end{macrocode} % \end{macro} % % \begin{macro}{write_shift_xy} % Ghi ra *log* file th«ng tin vÒ |shift|; c¸c th«ng tin nµy ®­îc sö dông % trong qu¸ tr×nh chuyÓn font *VNR* sang *type1* format. % Xem \href{../doc/vnr_type1.pdf}{vnr_type1.pdf} (appendix {\bf A}) % ®Ó biÕt thªm vai trß cña macro nµy. % \begin{macrocode} %<*t5supp> def write_shift_xy(suffix _l, _a)(expr _sx, _sy) = if 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; % % \end{macrocode} % \end{macro} % % \subsection{Miscellanea} % % BiÕn |case_| dïng lµm |switch| ®Ó x¸c ®Þnh kiÓu ch÷ hoa/th­êng/... % \begin{macrocode} 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; % \end{macrocode} % % \begin{macro}{casename} % Tªn ®Çy ®ñ cña ch÷ c¸i ®ang ®­îc % |METAFONT| vÏ (chØ khi |testing| lµ \emph{unknown}). % Cã thÓ thÊy c¸c tªn nµy trªn |terminal| vµ trong file |log| % nÕu ch¹y |mf| víi |mode := proof|. % \begin{macrocode} def casename expr _name = %<*!test> "The " & if case_ = capital: "capital" elseif case_ = small: "small" else: "smallcap" fi & " letter " & _name % enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{ifknown} % This macro expands to |_b| if the suffix |_a| is \emph{unknown}, % and to |_a| itself in the other case. % Macro nµy ®­îc dïng nhiÒu, khi ph¶i lùa chän c¸c biÕn t­¬ng øng % víi c¸c dÊu. Xem mét vÝ dô ë \lref{use:ifknown}. % \begin{macrocode} def ifknown(suffix _a)(expr _b) = if known _a: _a else: _b fi enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{tand} % Hµm tÝnh |tangent| cña gãc |d| (tÝnh b»ng ®é, |d = degree|). % \begin{macrocode} def tand(expr _d) = (sind(_d)/cosd(_d)) enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{hp} % Lµm trßn theo chiÒu ngang (|horizontal|). % \begin{macrocode} def hp(expr _x) = hround(_x*hppp) enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{vp} % Lµm trßn theo chiÒu ®øng (|vertical|). % \begin{macrocode} def vp(expr _y) = vround(_y*vppp) enddef; % \end{macrocode} % \end{macro} % % \subsection{Macro: begin, end} % % \begin{macro}{begin_pic} % \begin{macrocode} def begin_pic(suffix _n) = begingroup clearxy; clearit; clearpen; picture vn.vncase._n.pic; vn.vncase._n.pic := begingroup enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{end_pic} % \begin{macrocode} def end_pic = % \end{macrocode} % % \danger % Ta chØ cã thÓ dïng |makebbox| ë ®©y mµ th«i! % \endanger % % \begin{macrocode} % makebbox(proofrule); % \end{macrocode} % % \begin{macrocode} currentpicture endgroup; endgroup enddef; % \end{macrocode} % \end{macro} % % \begin{macrocode} let end_accent = end_pic; let begin_letter = begin_pic; let end_letter = end_pic; % \end{macrocode} % % \begin{macro}{begin_accent} % \begin{macrocode} def begin_accent(suffix _a) = begin_pic(_a); set_char_dimens(vn_width(_a), vn_height(_a), 0) enddef; % \end{macrocode} % \end{macro} % % \subsection{Picture's Properties} % % Tõ \meta{h×nh vÏ} dïng ®Ó chØ \meta{picture} do |METAFONT| % t¹o ra khi vÏ ch÷ c¸i \meta{char}, hoÆc dÊu \meta{accent}. % Mçi \meta{h×nh vÏ} cã c¸c thuéc tÝnh sau ®©y: % \begin{verbatim} % code, pic, width, height, top, bot, depth, % ic, left, right, gap, join_xp, join_x % \end{verbatim} % % \begin{multicols}2 % \begin{macrocode} 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; % \end{macrocode} % \end{multicols} % % \subsection{Setting Macros} % % \begin{macro}{define_accent_dimens} % X¸c ®Þnh c¸c kÝch th­íc cña mét dÊu (gåm cã |width|, |height|, |top|). % \begin{macrocode} 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#; % \end{macrocode} % TÝnh l¹i gi¸ trÞ lín nhÊt cña |vn_max_ac_top#|. % \begin{macrocode} vn_max_ac_top# := max(vn_max_ac_top#, vn_top(_a)); enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{set_char_dimens} % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{set_letter_dimens} % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{set_ac_join} % \begin{macrocode} def set_ac_join(suffix _a)(expr _xp, _x, _rt) = vn_join_xp(_a) := _xp; vn_join_x(_a) := _x; vn_rt(_a) := _rt; %<*test> 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; % \end{macrocode} % \end{macro} % % \begin{macro}{set_letter_join} % \begin{macrocode} def set_letter_join(suffix _l)(expr _xp, _x) = vn_join_xp(_l) := _xp; vn_join_x(_l) := _x; %<*test> if known show_labels: makelabel("X", (vn_join_xp(_l), vp(vn_height(_l)))); makelabel("Y", (hp(vn_join_x(_l)), vp(vn_height(_l)))); fi; % enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{set_adj_gap} % \begin{macrocode} def set_adj_gap(suffix _l, _a) = %<=use:ifknown> adj_gap# := ifknown(vn_gap(_l._a), ifknown(vn_gap(_a), 0)); enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{set_shift} % \begin{macrocode} def set_shift(suffix _l, _a) = shift.y := vp(vn_top(_a) - vn_height(_a)) + ifknown(hook_shift.y._l._a,0)*u; shift.x := get_join_xp(_l, _a) - vn_join_xp(_a) + slant*shift.y + ifknown(hook_shift.x.vncase._l._a,0)*u; % \end{macrocode} % % \begin{macrocode} shift.y# := vn_top(_a) - vn_height(_a) + ifknown(hook_shift.y._l._a#,0)*u#; shift.x# := get_join_x(_l, _a) - vn_join_x(_a) + slant*shift.y# + ifknown(hook_shift.x.vncase._l._a#,0)*u#; enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{set_ic} % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{set_lic} % \begin{macrocode} def set_lic(suffix _l) = italcorr vn_ic(_l); enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{set_fit} % \begin{macrocode} def set_fit(suffix _l) = adjust_fit(vn_left_adj(_l), vn_right_adj(_l)); enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{set_dot_shift} % to avoid error when calling |set_dot_shift(idot)| % \begin{macrocode} C.l.idot.dot_ = C.u.idot.dot_ = 256; % \end{macrocode} % % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \subsection{Getting Macros} % % \begin{macro}{get_join_xp} % \begin{macrocode} def get_join_xp(suffix _l, _a) = ifknown(vn_join_xp(_l._a), vn_join_xp(_l)) enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{get_join_x} % \begin{macrocode} def get_join_x(suffix _l, _a) = ifknown(vn_join_x(_l._a), vn_join_x(_l)) enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{get_top} % \begin{macrocode} def get_top(suffix _a) = %<=def:get_top> max(vn_top(_a) + adj_gap#, if vn_top(_a) <= vn_ac_top: vn_ac_top else: vn_double_ac_top fi) enddef; % \end{macrocode} % \end{macro} % % \subsection{Pos Function} % % \begin{macro}{pos} % Xem chó thÝch trong \mfb E/310/. % \begin{macrocode} 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 % \end{macrocode} % H×nh nh­ anh Thµnh nhÇm lÉn, khi dïng *|if known b ... else|*? % Kh«ng! Quan s¸t file *log* (sau khi thªm *message ...* vµo trong *else:*) % ta thÊy cã nhiÒu lÇn tr­êng hîp "else" x¶y ra... Xem xÐt mét sè tr­êng hîp % gäi *pos*, ta thÊy: cã khi *|expr b|* lµ mét biÓu thøc, % cã khi nã lµ mét biÕn. VÝ dô, khi vÏ *tilde* trong *vnaccent*, % anh Thµnh ®· dïng\\\centerline{"pos1(vn_tilde_vair, theta + 90)"} % Nh­ vËy lµ, hµm *pos* ®­îc ®Þnh nghÜa ë ®©y \emph{rÊt m¹nh}. % Mét c©u hái ®Æt ra lµ, liÖu cã cÇn ph©n biÖt hai tr­êng hîp nh­ trªn? % C©u tr¶ lêi lµ \emph{kh¼ng ®Þnh}. % \up ý cña anh Thµnh lµ: nÕu *|expr b|* ®­îc dïng lµ mét biÕn, th× cÇn % ph¶i khèng chÕ tr­êng hîp gi¸ trÞ cña biÕn ®ã ë d­íi ng­ìng cho phÐp! % \begin{macrocode} x@# = .5(x@#l + x@#r); y@# = .5(y@#l + y@#r) enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{vn_sl_shift} % \begin{macrocode} def vn_sl_shift(suffix _a) = % .5slant*(adj_y# + vn_height(_a)) 0 enddef; % \end{macrocode} % \end{macro} % % \subsection{Drawing Letters and Accents} % % \begin{macro}{define_vnchar} % \label{def:define_vnchar} % % Macro nµy nèi dÊu |_c| víi ch÷ |_c|, t¹o thµnh mét ch÷ c¸i % tiÕng ViÖt. VÝ dô, nèi dÊu huyÒn víi ch÷ "a". % % \begin{macrocode} def define_vnchar(suffix _l, _a) = %<=def:define_vnchar> % if used_char(vn_code(_l._a)): set_adj_gap(_l, _a); beginchar(vn_code(_l._a), vn_width(_l), get_top(_a), 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#)); %<*t5supp> write_shift_xy(_l, _a) (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y + vp(adj_gap#)); % endchar % fi enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{define_double_accent} % \begin{macrocode} 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#)); %<*t5supp> write_shift_xy(_a, _b)(hp(shift.x#), vp(shift.y#)); % 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; % \end{macrocode} % \end{macro} % % \begin{macro}{define_vnaccent} % % VÏ \meta{accent} |_a| víi m· |_c|. % ChØ dïng víi |T5supp|. % Xem c¸ch dïng trong *vnuacc* \lref{use:define_vnaccent}. % % \begin{macrocode} %<*t5supp> def define_vnaccent(expr _c)(suffix _a) = %<=def:define_vnaccent> beginchar(_c, vn_width(_a), vn_height(_a), 0); currentpicture := vn_pic(_a); endchar enddef; % % \end{macrocode} % \end{macro} % % \begin{macro}{define_vnchar_dot} % % Thªm dÊu nÆng vµo mét ch÷ % % \begin{macrocode} def define_vnchar_dot(suffix _l) = % if used_char(vn_code(_l.dot_)): % \end{macrocode} % Ta ph©n biÖt hai tr­êng hîp: ch÷ |Þ| (th­êng) % vµ c¸c ch÷ kh¸c (víi dÊu nÆng). % \begin{macrocode} 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_lic(idot); set_fit(idot); 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); %<*t5supp> write_shift_xy(_l, dot_) (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y); % endchar % fi enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{define_vnchar_dot_ac} % % Thªm dÊu vµ dÊu nÆng vµo mét ch÷ cã dÊu. % % \begin{macrocode} 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); %<*t5supp> write_shift_xy(_l._a, dot_) (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y); % endchar % fi enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{define_vnchar_horn} % % VÏ r©u cho ch÷ |u| hoÆc |o|. % % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{select_horn} % % Chän r©u cña ch÷ |u| hay ch÷ |o|. % % \begin{macrocode} def select_horn(suffix _l) = if vn_code(_l.horn_) = vn_code(u.horn_): def cur_horn_ = uhorn_ enddef; else: def cur_horn_ = ohorn_ enddef; fi enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{update_horn_width} % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{set_shift_horn} % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{select_letter_u} % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{define_vnchar_horn_ac} % set |cur_horn_| to |uhorn_| or |ohorn_| according to |_l|. % \begin{macrocode} def define_vnchar_horn_ac(suffix _l, _a) = % if used_char(vn_code(_l.horn_._a)): select_horn(_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#)); %<*t5supp> write_shift_xy(_l.horn_, _a) (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y + vp(adj_gap#)); % endchar % fi enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{define_vnchar_horn} % \begin{macrocode} 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); addto currentpicture also vn_pic(dot_) shifted (shift.x, shift.y); %<*t5supp> write_shift_xy(_l.horn_, dot_) (shift.x + hp(vn_left_adj(_l)) + letter_fit, shift.y); % endchar % fi enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{hook_arck.r} % |hook_arc| is based on |super_arc| from exbase.mf % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{hook_arc.l} % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{vn_hook_bulb} % |vn_hook_bulb| is based on bulb from |exbase.mf| % \begin{macrocode} 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; % \end{macrocode} % \end{macro} % % \begin{macro}{vn_draw_horn} % \begin{verbatim} % ====4r=== % = 1 = z1r = z4r % = = y2 = 1/3[y1, y3] % = 4 22l % = = % = = % ===4l==== % == % == % 3=== % \end{verbatim} % % \begin{macrocode} 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); % \end{macrocode} % \begin{macrocode} 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 % \end{macrocode} % Víi ®o¹n m· d­íi ®©y, ta t« ®­îc mét nöa h×nh trßn vµ mét tam gi¸c cong % cã mét c¹nh lµ ®­êng kÝnh cña nöa h×nh trßn. Tam gi¸c nµy ®­îc chän % dùa trªn tham sè |y_| ë trªn. % {\ttfamily % \begin{verbatim} % ooooo % ooooooox % ooooooooxx % oooooooooxxx % oooooooooxxxx % oooooooooxxxxx % ooooooooxxxxxxx % oooooooxxxxxx % ooooooxxxxx % ooooxxx % \end{verbatim} % } % \begin{macrocode} filldraw z4r{left} .. subpath (0, y_) of (z4l{right}.. {left}z4r) -- cycle; % \end{macrocode} % \danger % Tuy nhiªn, víi phÇn h×nh trßn ë trªn, khi ®­îc phãng to, c¸i r©u sÏ % bÞ khuyÕt mét m¶nh. % % §Ó kh¾c phôc lçi nµy, anh Thµnh ®· thªm vµo mét chót, % |--z2--cycle|, trong ®o¹n m· trªn. M¶nh khuyÕt b©y giê kh«ng cßn. % Tuy nhiªn, c¸c font |typewriter| khi ®ã ®Òu bÞ lçi <<|strange path|>>. % \emph{Lçi nµy xuÊt hiÖn trong bé |VNR| ngµy 2003/03/03 % (\href{http://vinux.sourceforge.net/vntex}{vinux.sourceforge.net/vntex}).} % \endanger % % TiÕp theo, ta vÏ dÊu phÈy, thªm vµo h×nh ë trªn ®Ó t¹o r©u. % \begin{macrocode} filldraw stroke z1e{right} ... z2e{down} ... {left}z3e; % \end{macrocode} % §Ó che ®i m¶nh khuyÕt ®ång thêi tr¸nh lçi ë trªn, % ta cã thÓ viÕt m· riªng... ®Ó t¹o mét tam gi¸c ®ñ lín. % C¸c ®Ønh cña tam gi¸c nµy lµ c¸c ®iÓm \meta{ngoµi cïng} cña r©u. % Cho ®Õn ngµy "2003/11/30", miÕng v¸ nµy ch­a thÓ hiÖn thiÕu sãt nµo. % C¸c font |typewriter| ®Òu tèt, nh­ng c¸c font |csc| th× vÉn\footnote{% % §· kh¾c phôc lçi sau ®ã mét ngµy, còng víi viÖc viÕt l¹i |docstrip|. % \emph{Nguyªn nh©n:} c¸c |guard| trong file % *|vndriver.dtx|* lµ c¸c |nested| |guard|, vµ |docstrip.py| khi ®ã % kh«ng thÓ hiÓu ®iÒu nµy.}... % \danger % CÇn xem l¹i |METAFONTbook|, xem thö tam gi¸c nµy liÖu cã ®Ønh *rÊt nhän* % hay lµ *trßn* (nh­ khi dïng |draw|)? (\emph{Tr¶ lêi:} dïng |filldraw| % th× chuyÖn nµy khái ph¶i lo....) % \endanger % \begin{macrocode} filldraw z1r--z2r--z4l--cycle; % \end{macrocode} % \begin{macrocode} % penlabels(0, 1, 2, 3, 4); set_ac_join(_a, x3, .5cur_stem*sind(_horn_bot_theta), h# - .5cur_dotsize#); % \end{macrocode} % \begin{macrocode} 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); set_ac_join(_a, x2', 0, h#); fi vn_bot(_a) := vn_top(_a) - vn_height(_a); enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{set_horn_join} % \begin{macrocode} 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; set_ac_join(_l.horn_join, xpart .5[L, R], 0, 0); enddef; % \end{macrocode} % \end{macro} % % \subsection{Oct031 Character} % % \begin{macro}{lig_CGQ_table} % \begin{macrocode} def lig_CGQ_table(expr k) = "C" kern k, "G" kern k, "Q" kern k enddef; % \end{macrocode} % % \begin{macrocode} def end_ligtable = 0 kern 0 enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{input_lig} % define input_lig to generate only char oct"031" from excspl.mf % \begin{macrocode} def input_lig suffix @# = let save_endchar = endchar; let endchar = lig_endchar; scantokens("input " & str @#); relax; let endchar = save_endchar; enddef; % \end{macrocode} % \end{macro} % % \begin{macro}{lig_endchar} % \begin{macrocode} def lig_endchar = if charcode = oct"031": save_endchar else: endgroup fi enddef; % \end{macrocode} % \end{macro} % % \subsection{Macro: generate} % % \begin{macro}{generate} % File |vnr10.mf| sÏ |input| c¸c file |vnbase.mf| vµ |ecrm.mf|. % §Õn l­ît m×nh, |ecrm| sÏ |input| driver lµ |exroman| b»ng c¸ch gäi % *|generate exroman|* (®èi víi |ec|, |generate| chÝnh lµ |input|). % {\tiny % \begin{verbatim} % 0: 0 * % 1: 1 +- vnr10.mf % 2: 2 | +- vnbase.mf % 3: 3 | | +- exbase.mf % 4: 3 | | +- vncode.mf % 5: 2 | +- ecrm.mf % 6: 3 | | +- null.mf % 7: 3 | | +- vnroman.mf % % (See |doc/vnr10_tree_*.txt| for full detail) % \end{verbatim} % } % §Ó thay thÕ |exroman| b»ng |driver| cña |VNR|, ta sÏ ®Þnh nghÜa l¹i % |generate|, nhê vµo ®Æc ®iÓm: c¸c |driver| cña |ec| ®Òu b¾t ®Çu b»ng % hai ký tù |ec|, vµ c¸c |driver| cña |VNR| (bao gåm \emph{vnroman}, % \emph{vncsc}, \emph{vntextit}) ®­îc b¾t ®Çu bëi |vn|. % % \danger % Kh«ng thÓ hiÓu t¹i sao ph¶i dïng |scantokens("input null")|. % NÕu kh«ng cã dßng nµy, th× tÊt c¶ c¸c file ®Òu ®­îc |input| mét % c¸ch \emph{b×nh th­êng}, nh­ng kh«ng cã ch÷ nµo ®­îc vÏ c¶. % % T¹i sao anh Thµnh l¹i cã thÓ nghÜ ra chuyÖn thªm dßng nµy vµo? % \emph{Qu¸ siªu!} % \endanger % \begin{macrocode} vardef generate @# = scantokens("input null"); scantokens("input vn" & substring(2, length(str @#)) of str @#); enddef; % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % \endinput