summaryrefslogtreecommitdiff
path: root/support/pydocstrip/vnbase.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/pydocstrip/vnbase.dtx
Initial commit
Diffstat (limited to 'support/pydocstrip/vnbase.dtx')
-rw-r--r--support/pydocstrip/vnbase.dtx1600
1 files changed, 1600 insertions, 0 deletions
diff --git a/support/pydocstrip/vnbase.dtx b/support/pydocstrip/vnbase.dtx
new file mode 100644
index 0000000000..080ade8f52
--- /dev/null
+++ b/support/pydocstrip/vnbase.dtx
@@ -0,0 +1,1600 @@
+% \iffalse
+%<dtx>\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;
+%</test>
+% \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
+%</t5supp>
+% \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
+%</test>
+% \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;
+%</test>
+% \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}
+%<test> 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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</test>
+% \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
+%</test>
+% \end{macrocode}
+% \end{multicols}
+%
+% BiÕn |inpustr| ®­îc dïng trong 4 macro s¾p tíi.
+%
+% \begin{macrocode}
+%<test>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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</test>
+% \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;
+%</t5supp>
+% \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;
+%</t5supp>
+% \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
+%</!test>
+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}
+%<test> 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;
+%</test>
+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;
+%</test>
+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>
+%<test> 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#));
+%</t5supp>
+ endchar
+%<test> 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#));
+%</t5supp>
+ 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;
+%</t5supp>
+% \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) =
+%<test> 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);
+%</t5supp>
+ endchar
+%<test> 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) =
+%<test> 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);
+%</t5supp>
+ endchar
+%<test> 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) =
+%<test> 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
+%<test> 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) =
+%<test> 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#));
+%</t5supp>
+ endchar
+%<test> fi
+enddef;
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{define_vnchar_horn}
+% \begin{macrocode}
+def define_vnchar_horn_dot(suffix _l) =
+%<test> 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);
+%</t5supp>
+ endchar
+%<test> 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}
+%<test> 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
+%<test> 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}
+%</vnbase>
+% \end{macrocode}
+% \endinput