*** empty log message ***
[lilypond/patrick.git] / mf / feta-nummer-code.mf
blob1574669256a2da86d5138c0b27491bf490f1c685
1 % feta-nummer-code.mf -- implement bold Orator numerals
3 % part of LilyPond's pretty-but-neat music font
5 % source file of the Feta (not the Font-En-Tja) music font
7 % (c) 1997--2006 Jan Nieuwenhuizen <janneke@gnu.org>
10 height# := number_design_size;
11 space# := number_design_size / 2;
13 font_x_height height#;
14 font_normal_space space#;
18 % DOCME!
20 % ugh. b and h are reused.
23 save b, h;
24 4 h + b = 1.15;
25 10 h + b = 1;
26 fatten := number_design_size * h + b;
28 save b, h;
29 4 h + b = 1.05;
30 10 h + b = 1;
31 widen := number_design_size * h + b;
33 tense = 0.85;
34 thick# := 7/30 height# * fatten;
35 thin# := thick# / 4 * fatten + max (.1 (height# / 10 - 1), 0);
37 %% sqrt (.8 * blot_diameter# * thin#);
38 hair# := thin# * .8;
40 flare# := 9/8 thick# + .75 (height# / 10 - 1);
42 save b, h;
43 4h + b = 1/8;
44 10h + b = 1/6;
45 kuulleke# := thick# * number_design_size * h + b;
46 foot_top# := thick#;
47 foot_width# := 9/4 thick#;
51 % These numbers were taken from a part that that the EJE violas played
52 % 1997 -- Probably Mendelssohn's ouverture `Heimkehr aus der Fremde'.
57 % TODO all the invocation of flare_path are weird --
58 % the horizontal tangents should be more at the center of the
59 % glyph.
62 define_pixels (height, thick, thick, thin, hair, flare);
63 define_pixels (foot_top, foot_width);
64 define_pixels (kuulleke);
68 % Yet Another Bulb Routine with smooth inside curve.
70 % alpha = start direction.
71 % beta = which side to turn to
72 % flare = diameter of the bulb
73 % line = diameter of line attachment
74 % direction = is ink on left or right side (1 or -1)
77 % move_away_to = amount left (for 2)
78 % turn_to = amount down (for 2)
81 def number_flare_path (expr pos, alpha, beta, line, flare,
82                        move_away_to, turn_to, taille, taille_ratio,
83                        direction) =
84 begingroup;
85         save res;
86         path res;
88         clearxy;
90 %       z5 = z2 + 0.43 * flare * dir (alpha - 1.5 beta);
92         z4 = (0.75 - taille) [z2r, z2l] + whatever * dir (alpha - beta);
93         z4 = (taille_ratio * taille) [z3l, z3r] + whatever * dir (alpha);
95         z1r = pos;
96         z2r = z1r + move_away_to * dir (alpha)
97               + (line + turn_to) * dir (alpha + beta);
98         z3r = 0.5 [z2l, z2r] + 0.5 * flare * dir (alpha + beta);
100         penpos1 (line, 180 + beta + alpha);
101         penpos2 (flare, alpha);
102         penpos3 (flare, alpha + beta);
104         penlabels (1, 2, 3, 4, 5);
106         res := z1r{dir (alpha)}
107                .. z2r{dir (180 + alpha - beta)}
108                .. z3r{dir (alpha + 180)}
109                .. z2l{dir (alpha - beta)}
111 %%% Two versions of the curve: one with z4, the other with z5.
112 %              .. z5{dir (alpha - beta / 2)}
114                .. z4{dir (180 + alpha + beta)}
115                .. z1l{dir (alpha + 180)};
117 %       pickup pencircle;
118 %       draw res;
120         if direction <> 1:
121                 res := reverse res;
122         fi;
125 endgroup
126 enddef;
129 def calc_kuulleke (expr w, alpha) =
130 begingroup;
131         save beta, gamma;
133         beta = (alpha - 90) / 2;
134         gamma = (90 + alpha) / 2;
136         penpos1 (w / cosd (alpha), alpha);
137         penpos2 (hair, 90 + beta);
138         penpos3 (hair, gamma - 90);
140         z2 = z1l + (1/2 hair / tand ((alpha + 90) / 2)) * dir (beta);
141         z3 = z1r - (1/2 hair / tand ((90 - alpha) / 2)) * dir (gamma);
142         z4 = z1 + kuulleke * dir (alpha - 90);
143 endgroup;
144 enddef;
147 % should make generic macro?
149 def draw_foot (expr xpos) =
150 begingroup;
151         clearxy;
153         penpos1 (thick, 0);
154         penpos2 (foot_width, 0);
155         penpos3 (hair, -90);
156         penpos4 (hair, 90);
158         z1= (xpos, foot_top);
159         z2= (x1, 0);
160         z3r = z2r;
161         z4l = z2l;
162         z5 = (x1, kuulleke);
164         penlabels (1, 2, 3, 4);
166         fill z1
167              .. {right}z1r{down}
168              .. {right}z3l
169              .. z3r{left}
170              .. z5
171              .. {left}z4l
172              .. z4r{right}
173              .. {up}z1l{right}
174              .. z1
175              .. cycle;
176 endgroup;
177 enddef;
180 def draw_six =
181         save outer_t, t;
182         save before, after, u, v;
183         path before, after;
185         set_char_box (0, .68 height# * widen, 0, height#);
187         message "w:" & decimal w;
188         message "h:" & decimal h;
190         penpos2 (hair, 90);
191         z2 = (w / 2, h / 2 + thin - hair / 2);
193         penpos3 (15/16 thick, 0);
194         x3r = w;
195         y3r = .5 [y4r, y2r];
197         penpos4 (hair, -90);
198         z4r = (x2, 0);
200         penpos6 (hair, 90);
201         x6r = .56 w;
202         y6r = h;
204         penpos7 (thick, 180);
205         x7r = 0;
206         y7r = .50 h;
208         penpos10 (thick, 180);
209         z10r = (0, y3);
211         penlabels (range 1 thru 10);
213         outer_t = 0.88;
214         t := tense;
216         before := z7{right}
217                   .. z2r{right};
218         after := z7r{up}
219                  .. number_flare_path (z6r, 0, -90, hair, flare,
220                                        w - x6r - hair / 2, .16 h,
221                                        0.05, 2.5, 1)
222                  .. z7l{down};
223         (u, v) = before intersectiontimes after;
225 %       draw
226         fill subpath (u, infinity) of before
227              ..tension outer_t.. z3r{down}
228              ..tension outer_t.. z4r{left}
229              .. subpath (0, v) of after
230              .. cycle;
232         unfill z2l{right}
233                ..tension t.. z3l{down}
234                ..tension t.. z4l{left}
235                ..tension t.. z10l{up}
236                ..tension t.. cycle;
237 enddef;
240 save dot_diam;
241 dot_diam# = 7/8 flare#;
242 define_pixels (dot_diam);
245 code := 31;     % , 32
247 fet_beginchar ("Space", "space");
248         set_char_box (0, space#, 0, height#);
249 fet_endchar;
252 code := 42;     % , 43
254 fet_beginchar ("Plus", "plus");
255         set_char_box (0, .5 height#, -0.25 height#, 0.75 height#);
257         save hthick, vthick, size, outer_hsize, outer_vsize;
259         hthick# = vthick# = 2 linethickness#;
260         size# = 1.1 staff_space#;
261         define_whole_blacker_pixels (vthick);
262         define_whole_vertical_blacker_pixels (hthick);
264         outer_hsize = hround ((b + w - vthick) / 2);
265         outer_vsize = vround ((h + d - hthick) / 2);
267         centerx := hround (w / 2);
268         centery := vround ((h - d) / 2);
270         z1 = (centerx - hthick / 2, -d); 
271         z2 = (centerx + hthick / 2, h); 
273         labels (1, 2);
275         draw_rounded_block (z1, z2, hthick);
276         draw_rounded_block ((0, centery - vthick / 2),
277                             (w, (centery + vthick / 2)),
278                             vthick);
279 fet_endchar;
282 code := 43;     % , = 44
284 fet_beginchar ("Numeral comma", "comma");
285         save pat, pos;
286         path pat;
288         set_char_box (0, dot_diam#, 3/2 dot_diam#, dot_diam#);
290         pat := (dot_diam / 2, 0)
291                .. (dot_diam, dot_diam / 2)
292                .. (dot_diam / 2, dot_diam)
293                .. (0, dot_diam / 2)
294                .. cycle;
295         
296         pos = ypart (((w / 3, 0) -- (w / 3, dot_diam / 2))
297                      intersectiontimes pat);
298         z0 = point pos of pat;
300         alpha = 65;
301         penpos1 (thin, alpha + 90);
303         z1l = (w / 2, -1.5 h + hair);
304         z2 = (w, h / 2);
306         pickup feta_fillpen;
308         % include z0 to assist removal of overlaps
309         fill subpath (0,3) of pat
310              .. z0
311              .. cycle;
312         filldraw z1l{dir (alpha)}
313                  .. {up}z2
314                  -- z0{direction pos of pat}
315                  ..tension 0.95.. {dir (180 + alpha)}z1r
316                  .. cycle;
318         labels (0, 2);
319         penlabels (1);
320 fet_endchar;
323 fet_beginchar ("Numeral dash", "hyphen");
324         set_char_box (0, height# / 3, 0, height#);
326         draw_rounded_block ((-b, h / 3 - thin / 2),
327                             (w, h / 3 + thin / 2), thin);
328 fet_endchar;
331 fet_beginchar ("Numeral dot", "period");
332         set_char_box (0, dot_diam#, 0, dot_diam#);
334         pickup pencircle scaled dot_diam;
336         drawdot (dot_diam / 2, dot_diam / 2);
337 fet_endchar;
340 % skip slash
342 code := 47;     % 0 = 48
344 fet_beginchar ("Numeral 0", "zero");
345         set_char_box (0, 11/15 height# * widen, 0, height#);
347         message "w:" & decimal w;
348         message "h:" & decimal h;
350         penpos1 (thin, 90);
351         penpos2 (thick, 180);
352         penpos3 (thin,- 90);
353         penpos4 (thick, 0);
355         z1r = (w / 2, h);
356         z2r = (0, h / 2);
357         z3r = (w / 2, 0);
358         z4r = (w, h / 2);
360         fill z1r
361              .. z2r
362              .. z3r
363              .. z4r
364              .. cycle;
366         save t;
367         t = 1 / tense;
369         penlabels (1, 2, 3, 4);
371         unfill z1l
372                ..tension t.. z2l
373                ..tension t.. z3l
374                ..tension t.. z4l
375                ..tension t.. cycle;
376 fet_endchar;
379 fet_beginchar ("Numeral 1", "one");
380         save alpha, beta, gamma;
382 %       set_char_box (0, 19/30 height# * widen, 0, height#);
383         set_char_box (0, 1/2 foot_width# + 3/2 thick# + 1/2 hair#,
384                       0, height#);
386         message "w:" & decimal w;
387         message "h:" & decimal h;
389         alpha = 0;
390         calc_kuulleke (thick, alpha);
391         z1 = (3/2 thick, height);
393         penpos5 (thick, 0);
394         z5 = (x1, foot_top);
396         z6 = (0, h / 2);
397         beta = angle (z1l - z6);
399         penpos7 (thin, beta - 90);
400         z7l = z6;
402         penpos8 (thin / cosd (beta), -90);
403         z8l = z1l;
405         penpos9 (thin, beta - 90);
406         z9r = z8r + (thin / cosd (beta)) * down;
408         penlabels (range 1 thru 9);
410         gamma = angle (length (z1r - z1), 2 kuulleke);
412         fill z2r{dir (alpha - gamma)}
413              .. z4
414              .. {dir (alpha + gamma)}z3l
415              .. z3r{down}
416              -- z5r
417              -- z5l
418              -- z2l{up}
419              .. cycle;
421         fill z7l
422              -- z1l{dir (beta)}
423              .. {dir (alpha - gamma)}z2r
424              -- z9r{up}
425              .. {dir (180 + beta)}z9l
426              -- z7r{dir (180 + beta)}
427              .. {dir (beta)}cycle;
429         draw_foot (x1);
430 fet_endchar;
433 fet_beginchar ("Numeral 2", "two");
434         save tolerance;
435         save alpha, beta, gamma, theta;
436         save flare_start_distance;
437         save t, pat, bow;
438         path pat, bow;
440         set_char_box (0, 22/30 height# * widen, 0, height#);
442         message "w:" & decimal w;
443         message "h:" & decimal h;
445         alpha = -45 * widen;
446         beta = 85;
447         gamma = beta - 10;
448         theta = 20 / widen;
450         flare_start = 0.25;
452         penpos1 (hair, 90 + beta);
453         z1 = (0, 0) + (1/2 sqrt (2) * hair) * dir (45);
455         penpos3 (hair,90 + gamma);
456         z3 = (w, thick) + (1/2 sqrt (2) * hair) * dir (-135);
458         penpos2 (thick, 90 + alpha - 15);
459         x2 - x1 = x3 - x2;
460         y2 = 10/16 thick / widen;
462         tolerance := epsilon;
464         % Find proper tension to exactly touch the x axis.
465         % Later on we directly use `bow'.
466         vardef f (expr t) =
467                 bow := z3l{dir (180 + gamma)}
468                        ..tension t.. {dir (180 + alpha -5)}z2l;
469                 ypart (directionpoint left of bow) < 0
470         enddef;
472         % the return value of `solve' is stored in a dummy variable
473         t = solve f (0.8, 1.2);
475         fill z1r{dir (beta)}
476              ..tension 0.9.. {dir (alpha + 10)}z2r
477              .. {dir (gamma)}z3r
478              .. bow
479              .. {dir (180 + beta)}z1l
480              .. cycle;
482         penpos4 (thick, 0);
483         z4r = (w - thin / 2, .71 h);
485         penpos5 (hair, 90);
486         y5r = h;
487         x5r = 9/20 w;
489         penlabels (range 1 thru 6);
491         t := tense;
493         pat := z1l{dir (beta)}
494                ..tension t.. z4r{up}
495                .. number_flare_path (z5r, 180, 90, hair, 1.05 flare,
496                                      x5r - 1/2 hair, .21 h, 0.006, 0.4, 1)
497                .. z4l{down}
498                ..tension t.. {dir (180 + beta)}z1r
499                -- cycle;
501 %       pickup pencircle scaled 1;
502 %       draw pat;
504         fill pat;
505 fet_endchar;
509 % TODO: should widen a bit.  The right edge of the 3 bumps into next glyph in
510 % combinations
512 fet_beginchar ("Numeral 3", "three");
513         set_char_box (0, 2/3 height# * widen, 0, height#);
515         message "w:" & decimal w;
516         message "h:" & decimal h;
518         penpos1 (hair, -90);
520 %       flare_start = 0.25;
522         x1l = 36/80 w;
523         y1l = h;
525 %       z1l = (17/16 thick, h);
527         penpos2 (7/8 thick, 180);
528         x2l = w - thick / 8;
529         y2l = 3/4 h + thick * 3/32;
531         penpos3 (thin, 90);
532         z3 = (w / 2, h / 2 + 1/8 thick);
534         penpos4 (thin, 90);
535         z4 = (5/8 thick + 1/2 thin, y3);
537         penpos5 (thick, 0);
538         x5r = w;
539         y5r = 17/64 h + thick / 16;
541         penpos6 (hair, -90);
542         x6r = 37/80 w;
543         y6r = 0;
545         penpos7 (3/2 thin, 90);
546         x7 = .83 w;
547         y7 = y3;
549         penlabels (range 1 thru 7);
551         save alpha, t, outer_t;
552         alpha = 25;
553         t = tense;
554         outer_t := 0.93;
556 %       pickup pencircle scaled 1;
557 %       draw
558         fill number_flare_path (z1l, 180, 90, hair, 7/8 flare, x1l - .5 hair,
559                                 .16 h, 0.06, 1.5, -1)
560              ..tension outer_t.. z2l{down}
561              ..tension outer_t.. z7r{dir (180 + alpha)}
562              .. z7l{dir (-alpha)}
563              ..tension outer_t.. z5r{down}
564              ..tension outer_t.. number_flare_path (z6r, 180, -90, hair,
565                                                     flare, x6l, .18 h, 0.06,
566                                                     1.5, 1)
567              .. z5l{up}
568              ..tension t.. z3l{left}
569              .. z4l{left}
570              .. z4r{right}
571              .. z3r{right}
572              ..tension t.. z2r{up}
573              ..tension t.. cycle;
574 fet_endchar;
577 fet_beginchar ("Numeral 4", "four");
578         save alpha, beta, gamma;
580         set_char_box (0, 4/5 height# * widen, 0, height#);
582         message "w:" & decimal w;
583         message "h:" & decimal h;
585         alpha = 0;
586         calc_kuulleke (3/2 thick, alpha);
588         z1r = (w - 3/4 thick, height);
589         z5 = (thin, 1/4 height + thin);
591         beta = angle (z3r - z5);
593         penpos6 (thin, -90);
594         z6l = z5;
596         penpos7 (thin, -90);
597         y7 = y6;
598         x7 = w - 1/2 thin;
600         penpos8 (thin, -alpha);
601         z8r = z5;
603         penlabels (range 1 thru 8);
605         gamma = angle (length (z1r - z1), 2 kuulleke);
607         fill z2r{dir (alpha - gamma)}
608              .. z4
609              .. {dir (alpha + gamma)}z3l
610              .. {dir (180 + beta)}z3r
611              -- z8r
612              -- z7l{right}
613              .. {left}z7r
614              -- z6r{left}
615              ..tension 0.8 and 2.. z8l{dir (beta)}
616              .. {up}z2l
617              .. cycle;
619         clearxy;
621         alpha := beta;
622         calc_kuulleke (thick, alpha);
624         z1r = (w - 3/4 thick, height - (3/2 thin) / cosd (alpha));
626         penpos5 (thick, 0);
627         z5 = (x1, foot_top);
629         gamma := angle (length (z1r - z1), 2 kuulleke);
631         fill z2r{dir (alpha - gamma)}
632              .. z4
633              .. {dir (alpha + gamma)}z3l
634              .. {down}z3r
635              -- z5r
636              -- z5l
637              -- z2l{up}
638              .. cycle;
640         penlabels (1, 2, 3, 4, 5);
642         draw_foot (x5);
643 fet_endchar;
646 fet_beginchar ("Numeral 5", "five");
647         save alpha, beta, gamma, delta;
648         save inner_t, outer_t;
649         save pat;
650         path pat;
652         set_char_box (0, 27/40 height# * widen, 0, height#);
654         message "w:" & decimal w;
655         message "h:" & decimal h;
657         alpha = 0;
658         calc_kuulleke (w - thin, alpha);
660         z1 = (w / 2 + 1/8 thick, h);
662         penpos5 (thin, 0);
663         z5l = (x1l, h - 15/16 thick);
665         penpos6 (hair, 90 - 45);
666         z6 = z5r + 1/2 hair * dir (-45);
668         penpos7 (thin, 0);
669         z7l = (x1l, h / 2 + thin - hair);
671         penlabels (range 1 thru 7);
673         gamma = angle (length (z1r - z1), 2 kuulleke);
675         pat := z2r{dir (alpha - gamma)}
676                .. z4
677                .. {dir (alpha + gamma)}z3l
678                .. z3r{dir (-135)}
679                .. {left}z6r
680                .. {down}z6l
681                -- z7r{down}
682                .. {up}z7l
683                -- z2l{up}
684                .. cycle;
686         beta = 45;
687         delta = 180 + beta + 10;
688         z8r = (x7r, y7r - 1/16 thick + thin);
689         z8l = directionpoint dir (delta) of
690                 subpath (6, 7) of pat;
692         % include intersection point to improve overlap removal
693         fill subpath (0, 6) of pat
694              .. z8l
695              .. subpath (7, length (pat)) of pat
696              .. cycle;
698         penpos9 (thin, 90);
699         y9 = 10/16 [y5, y7];
700         x9 = .36 [x8r, x10r];
702         penpos10 (thick, 0);
703         x10r = w + hair / 2;
704         y10r = 1/2 [y9r, y11r];
706         penpos11 (hair, -90);
707         y11r = 0;
708         x11r = .7 [0, x10l];
710         penlabels (range 8 thru 12);
712         inner_t = 1.0;
713         outer_t = .85;
715         fill z8r {dir (beta)}
716              .. z9r{right}
717              ..tension outer_t.. z10r{down}
718              .. number_flare_path (z11r, 180, -90, hair, flare, x11l,
719                                    .18 h, 0.06, 1.5, 1)
720              .. z11l{right}
721              ..tension inner_t.. z10l{up}
722              ..tension inner_t.. z9l{left}
723              .. z8l{dir (delta)}
724              -- cycle;
725 fet_endchar;
728 fet_beginchar ("Numeral 6", "six");
729         draw_six;
730 fet_endchar;
733 fet_beginchar ("Numeral 7", "seven");
734         save tolerance;
735         save alpha, beta, gamma, delta;
736         save bow;
737         path bow;
739         set_char_box (0, 11/15 height# * widen, 0, height#);
741         message "w:" & decimal w;
742         message "h:" & decimal h;
744         alpha = -180;
746 if true:
747         penpos1 (3/2 thick, 180 + alpha);
748         penpos2 (hair, 180 + alpha - 45);
749         penpos3 (hair, 180 + alpha + 45);
751         z2 = z1l + (1/4 sqrt (2) * hair) * dir (alpha - 135);
752         z3 = z1r + (1/4 sqrt (2) * hair) * dir (alpha - 45);
753         z4 = z1 + kuulleke * dir (alpha - 90);
754 else:
755         % does not work
756         calc_kuulleke (3/2 thick, -alpha);
759         z1l = (thin, 0);
761         beta = 55;
762         penpos5 (thin, 90 + beta);
763         z5 = (w, h) + (1/2 sqrt (2) * thin) * dir (-135);
765         gamma = angle (length (z1r - z1), 2 kuulleke);
766         delta = 12;
768         pickup pencircle;
770         fill z3l{dir (alpha - gamma)}
771              .. z4
772              .. {dir (alpha + gamma)}z2r
773              .. z2l{dir (beta + delta)}
774              .. {dir (beta)}z5r
775              .. z5l{dir (180 + beta)}
776              .. {dir (delta - 90)}z3r
777              .. cycle;
779         penlabels (1, 2, 3, 4, 5);
781         alpha := -45 * widen;
783         penpos11 (1/2 thick, 90);
784         z11 = (3/2 thin, h - (thick + thin) / 2);
786         penpos13 (thin, 90 + beta);
787         z13 = z5;
789         penpos12 (thick, 90 + alpha);
790         x12 = 1/2 [x11, x13] - 1/4 thick;
791         y12 = h - 15/16 thick + thin * widen;
793         penpos14 (thin, 0);
794         z14l = (0, h - thin / 2);
796         penpos15 (thin, 0);
797         z15l = (0, h / 2 + thin / 2);
799         penpos16 (9/8 thick, 90);
800         z16r = (thin, y11r + 2/16 thick);
802         tolerance := epsilon;
804         % Find proper tension to exactly touch the x axis.
805         % Later on we directly use `bow'.
806         vardef f (expr t) =
807                 bow := z11r{dir (beta)}
808                        ..tension t.. {dir (alpha)}z12r;
809                 ypart (directionpoint right of bow) > h
810         enddef;
812         % the return value of `solve' is stored in a dummy variable
813         t = solve f (0.8, 1.2);
815         fill bow
816              .. {dir (beta)}z13r
817              -- z13l{dir (180 + beta)}
818              .. {dir (180 + alpha)}z12l
819              .. {dir (180 + beta)}z11l
820              .. {down}z16l
821              -- z15r{down}
822              .. {up}z15l
823              -- z14l{up}
824              .. {down}z14r
825              -- z16r{down}
826              ..tension 1.5.. {dir (beta)}cycle;
828         penlabels (range 11 thru 16);
829 fet_endchar;
832 fet_beginchar ("Numeral 8", "eight");
833         save alpha, beta;
835         set_char_box (0, 11/15 height# * widen, 0, height#);
837         message "w:" & decimal w;
838         message "h:" & decimal h;
840         alpha = 60;
841         beta = alpha - 15;
843         z1 = (w / 2, h / 2 + thick / 8);
845         penpos2 (14/8 thin, 0);
846         z2 = (w / 3, h / 2 + thin);
848         penpos3 (3/2 thin, 0);
849         z3l = (0, h / 4 + thin / 2);
851         penpos4 (hair, 90);
852         z4l = (x1, 0);
854         penpos5 (thick, 90 + 90 + alpha);
855         z5 = z1 + w / 4 * dir (alpha - 90);
857         penpos6 (thick, 90 + 90 + alpha);
858         z6 = z1 + (w / 4 - thin / 2) * dir (90 + alpha);
860         penpos7 (hair, 90);
861         z7r = (x1 + .02 w, h);
863         penpos8 (3/2 thin, 0);
864         z8r = (w - thin / 2, 3/4 h + thin / 2);
866         penpos9 (13/8 thin, 0);
867         z9 = (2/3 w, h / 2);
869         penlabels (range 1 thru 9);
871         save t;
872         t = tense;
874         fill z2r{dir (180 + beta)}
875              .. z3r{down}
876              .. z4r{right}
877              .. z5r{dir (90 + alpha)}
878              -- z6r{dir (90 + alpha)}
879              ..tension t.. z7r{right}
880              .. z8r{down}
881              .. {dir (180 + beta)}z9r
882              -- z9l{dir (beta)}
883              .. z8l{up}
884              .. z7l{left}
885              .. {dir (alpha - 90)}z6l
886              -- z5l{dir (alpha - 90)}
887              ..tension t.. z4l{left}
888              .. z3l{up}
889              .. {dir (beta)}z2l
890              -- cycle;
891 fet_endchar;
894 fet_beginchar ("Numeral 9", "nine");
895         draw_six;
896 %       xy_mirror_char;
898         currentpicture := currentpicture scaled -1;
899         currentpicture := currentpicture shifted (w, h);
900 fet_endchar;
903 ligtable "3":
904         "3" kern 0.1 space#,
905         "0" kern 0.1 space#;
907 ligtable "2":
908         "7" kern 0.15 space#;