]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-nummer-code.mf
* mf/feta-nummer-code.mf ("Numeral 5"): Include intersection point
[lilypond.git] / mf / feta-nummer-code.mf
1 % feta-nummer.mf -- implement bold Orator numerals
2 %
3 % part of LilyPond's pretty-but-neat music font
4 %
5 % source file of the Feta (not the Font-En-Tja) music font
6 %
7 % (c) 1997--2005 Jan Nieuwenhuizen <janneke@gnu.org>
8
9
10 height# := number_design_size;
11 space# := number_design_size / 2;
12
13 font_x_height height#;
14 font_normal_space space#;
15
16
17 %
18 % DOCME!
19 %
20 % ugh. b and h are reused.
21 %
22
23 save b, h;
24 4h + b = 1.15;
25 10h + b = 1;
26 fatten := number_design_size * h + b;
27
28 save b, h;
29 4h + b = 1.05;
30 10h + b = 1;
31 widen := number_design_size * h + b;
32
33 tense = 0.85;
34 thick# := 7/30 height# * fatten;
35 thin# := thick# / 4 * fatten + max (.1 (height# / 10 - 1), 0);
36
37 %% sqrt (.8 * blot_diameter# * thin#);
38 hair# := thin# * .8;
39
40 flare# := 9/8 thick# + .75 (height# / 10 - 1);
41
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#;
48
49
50 %
51 % These numbers were taken from a part that that the EJE violas played
52 % 1997 -- Probably Mendelssohn's ouverture `Heimkehr aus der Fremde'.
53 %
54
55
56 %
57 % TODO all the invocation of flare_path are weird --
58 % the horizontal tangents should be more at the center of the
59 % glyph.
60 %
61
62 define_pixels (height, thick, thick, thin, hair, flare);
63 define_pixels (foot_top, foot_width);
64 define_pixels (kuulleke);
65
66
67 %
68 % Yet Another Bulb Routine with smooth inside curve.
69 %
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)
75 %
76 %
77 % move_away_to = amount left (for 2)
78 % turn_to  = amount down (for  2 )
79 %
80
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;
87
88         clearxy;
89
90 %       z5 = z2 + 0.43 * flare * dir (alpha - 1.5 beta);
91
92         z4 = (0.75 - taille) [z2r, z2l] + whatever * dir (alpha - beta);
93         z4 = (taille_ratio * taille) [z3l, z3r] + whatever * dir (alpha);
94
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);
99
100         penpos1 (line, 180 + beta + alpha);
101         penpos2 (flare, alpha );
102         penpos3 (flare, alpha +  beta);
103
104         penlabels (1, 2, 3, 4, 5);
105
106         res := z1r{dir (alpha)}
107                .. z2r{dir (180 + alpha - beta)}
108                .. z3r{dir (alpha + 180)}
109                .. z2l{dir (alpha - beta)}
110
111 %%% Two versions of the curve: one with z4, the other with z5.
112 %              .. z5{dir (alpha - beta / 2)}
113
114                .. z4{dir (180 + alpha + beta)}
115                .. z1l{dir (alpha + 180)};
116
117 %       pickup pencircle;
118 %       draw res;
119
120         if direction <> 1:
121                 res := reverse res;
122         fi;
123
124 res
125 endgroup
126 enddef;
127
128
129 def calc_kuulleke (expr w, alpha) =
130 begingroup;
131         save beta, gamma;
132
133         beta = (alpha - 90) / 2;
134         gamma = (90 + alpha) / 2;
135
136         penpos1 (w / cosd (alpha), alpha);
137         penpos2 (hair, 90 + beta);
138         penpos3 (hair, gamma - 90);
139
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;
145
146
147 % should make generic macro?
148 %
149 def draw_foot(expr xpos) =
150 begingroup;
151         clearxy;
152
153         penpos1 (thick, 0);
154         penpos2 (foot_width, 0);
155         penpos3 (hair, -90);
156         penpos4 (hair, 90);
157
158         z1= (xpos, foot_top);
159         z2= (x1, 0);
160         z3r = z2r;
161         z4l = z2l;
162         z5 = (x1, kuulleke);
163
164         penlabels (1, 2, 3, 4);
165
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;
178
179
180 def draw_six =
181         save outer_t, t;
182         save before, after, u, v;
183         path before, after;
184
185         set_char_box (0, .68 height# * widen, 0, height#);
186
187         message "w:" & decimal w;
188         message "h:" & decimal h;
189
190         penpos2 (hair, 90);
191         z2 = (w / 2, h / 2 + thin - hair / 2);
192
193         penpos3 (15/16 thick, 0);
194         x3r = w;
195         y3r = .5 [y4r, y2r];
196
197         penpos4 (hair, -90);
198         z4r = (x2, 0);
199
200         penpos6 (hair, 90);
201         x6r = .56 w;
202         y6r = h;
203
204         penpos7 (thick, 180);
205         x7r = 0;
206         y7r = .50 h;
207
208         penpos10 (thick, 180);
209         z10r = (0, y3);
210
211         penlabels (range 1 thru 10);
212
213         outer_t = 0.88;
214         t := tense;
215
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;
224
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;
231
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;
238
239
240 save dot_diam;
241 dot_diam# = 7/8 flare#;
242 define_pixels (dot_diam);
243
244
245 code := 31;     % , 32
246
247 fet_beginchar ("Space", "space");
248         set_char_box (0, space#, 0, height#);
249 fet_endchar;
250
251
252 code := 43;     % , = 44
253
254 fet_beginchar ("Numeral comma", "comma");
255         save pat, pos;
256         path pat;
257
258         set_char_box (0, dot_diam#, 3/2 dot_diam#, dot_diam#);
259
260         pat := (dot_diam / 2, 0)
261                .. (dot_diam, dot_diam / 2)
262                .. (dot_diam / 2, dot_diam)
263                .. (0, dot_diam / 2)
264                .. cycle;
265         
266         pos = ypart (((w / 3, 0) -- (w / 3, dot_diam / 2))
267                      intersectiontimes pat);
268         z0 = point pos of pat;
269
270         alpha = 65;
271         penpos1 (thin, alpha + 90);
272
273         z1l = (w / 2, -1.5 h + hair);
274         z2 = (w, h / 2);
275
276         pickup feta_fillpen;
277
278         % include z0 to assist removal of overlaps
279         fill subpath (0,3) of pat
280              .. z0
281              .. cycle;
282         filldraw z1l{dir(alpha)}
283                  .. {up}z2
284                  -- z0{direction pos of pat}
285                  ..tension 0.95.. {dir (180 + alpha)}z1r
286                  .. cycle;
287
288         labels (0, 2);
289         penlabels (1);
290 fet_endchar;
291
292
293 fet_beginchar ("Numeral dash", "hyphen");
294         set_char_box (0, height# / 3, 0, height#);
295
296         draw_rounded_block ((-b, h / 3 - thin / 2),
297                             (w, h / 3 + thin / 2), thin);
298 fet_endchar;
299
300
301 fet_beginchar ("Numeral dot", "period");
302         set_char_box (0, dot_diam#, 0, dot_diam#);
303
304         pickup pencircle scaled dot_diam;
305
306         drawdot (dot_diam / 2, dot_diam / 2);
307 fet_endchar;
308
309
310 % skip slash
311
312 code := 47;     % 0 = 48
313
314 fet_beginchar("Numeral 0", "zero");
315         set_char_box (0, 11/15 height# * widen, 0, height#);
316
317         message "w:" & decimal w;
318         message "h:" & decimal h;
319
320         penpos1 (thin, 90);
321         penpos2 (thick, 180);
322         penpos3 (thin,- 90);
323         penpos4 (thick, 0);
324
325         z1r = (w / 2, h);
326         z2r = (0, h / 2);
327         z3r = (w / 2, 0);
328         z4r = (w, h / 2);
329
330         fill z1r
331              .. z2r
332              .. z3r
333              .. z4r
334              .. cycle;
335
336         save t;
337         t = 1 / tense;
338
339         penlabels (1, 2, 3, 4);
340
341         unfill z1l
342                ..tension t.. z2l
343                ..tension t.. z3l
344                ..tension t.. z4l
345                ..tension t.. cycle;
346 fet_endchar;
347
348
349 fet_beginchar ("Numeral 1", "one");
350         save alpha, beta, gamma;
351
352 %       set_char_box (0, 19/30 height# * widen, 0, height#);
353         set_char_box (0, 1/2 foot_width# + 3/2 thick# + 1/2 hair#,
354                       0, height#);
355
356         message "w:" & decimal w;
357         message "h:" & decimal h;
358
359         alpha = 0;
360         calc_kuulleke (thick, alpha);
361         z1 = (3/2 thick, height);
362
363         penpos5 (thick, 0);
364         z5 = (x1, foot_top);
365
366         z6 = (0, h / 2);
367         beta = angle (z1l - z6);
368
369         penpos7 (thin, beta - 90);
370         z7l = z6;
371
372         penpos8 (thin / cosd (beta), -90);
373         z8l = z1l;
374
375         penpos9 (thin, beta - 90);
376         z9r = z8r + (thin / cosd (beta)) * down;
377
378         penlabels (range 1 thru 9);
379
380         gamma = angle (length (z1r - z1), 2 kuulleke);
381
382         fill z2r{dir (alpha - gamma)}
383              .. z4
384              .. {dir (alpha + gamma)}z3l
385              .. z3r{down}
386              -- z5r
387              -- z5l
388              -- z2l{up}
389              .. cycle;
390
391         fill z7l
392              -- z1l{dir (beta)}
393              .. {dir (alpha - gamma)}z2r
394              -- z9r{up}
395              .. {dir (180 + beta)}z9l
396              -- z7r{dir (180 + beta)}
397              .. {dir (beta)}cycle;
398
399         draw_foot (x1);
400 fet_endchar;
401
402
403 fet_beginchar ("Numeral 2", "two");
404         save tolerance;
405         save alpha, beta, gamma, theta;
406         save flare_start_distance;
407         save t, pat, bow;
408         path pat, bow;
409
410         set_char_box (0, 22/30 height# * widen, 0, height#);
411
412         message "w:" & decimal w;
413         message "h:" & decimal h;
414
415         alpha = -45 * widen;
416         beta = 85;
417         gamma = beta - 10;
418         theta = 20 / widen;
419
420         flare_start = 0.25;
421
422         penpos1 (hair, 90 + beta);
423         z1 = (0, 0) + (1/2 sqrt (2) * hair) * dir (45);
424
425         penpos3 (hair,90 + gamma);
426         z3 = (w, thick) + (1/2 sqrt (2) * hair) * dir (-135);
427
428         penpos2 (thick, 90 + alpha - 15);
429         x2 - x1 = x3 - x2;
430         y2 = 10/16 thick / widen;
431
432         tolerance := epsilon;
433
434         % Find proper tension to exactly touch the x axis.
435         % Later on we directly use `bow'.
436         vardef f (expr t) =
437                 bow := z3l{dir (180 + gamma)}
438                        ..tension t.. {dir (180 + alpha -5)}z2l;
439                 ypart (directionpoint left of bow) < 0
440         enddef;
441
442         % the return value of `solve' is stored in a dummy variable
443         t = solve f (0.8, 1.2);
444
445         fill z1r{dir (beta)}
446              ..tension 0.9.. {dir (alpha + 10)}z2r
447              .. {dir (gamma)}z3r
448              .. bow
449              .. {dir (180 + beta)}z1l
450              .. cycle;
451
452         penpos4 (thick, 0);
453         z4r = (w - thin / 2, .71 h);
454
455         penpos5 (hair, 90);
456         y5r = h;
457         x5r = 9/20 w;
458
459         penlabels (range 1 thru 6);
460
461         t := tense;
462
463         pat := z1l{dir (beta)}
464                ..tension t.. z4r{up}
465                .. number_flare_path (z5r, 180, 90, hair, 1.05 flare,
466                                      x5r - 1/2 hair, .21 h, 0.006, 0.4, 1)
467                .. z4l{down}
468                ..tension t.. {dir (180 + beta)}z1r
469                -- cycle;
470
471 %       pickup pencircle scaled 1;
472 %       draw pat;
473
474         fill pat;
475 fet_endchar;
476
477
478 %%
479 % TODO: should widen a bit.  The right edge of the 3 bumps into next glyph in
480 % combinations
481 %
482 fet_beginchar ("Numeral 3", "three");
483         set_char_box (0, 2/3 height# * widen, 0, height#);
484
485         message "w:" & decimal w;
486         message "h:" & decimal h;
487
488         penpos1 (hair, -90);
489
490 %       flare_start = 0.25;
491
492         x1l = 36/80 w;
493         y1l = h;
494
495 %       z1l = (17/16 thick, h);
496
497         penpos2 (7/8 thick, 180);
498         x2l = w - thick / 8;
499         y2l = 3/4 h + thick * 3/32;
500
501         penpos3 (thin, 90);
502         z3 = (w / 2, h / 2 + 1/8 thick);
503
504         penpos4 (thin, 90);
505         z4 = (5/8 thick + 1/2 thin, y3);
506
507         penpos5 (thick, 0);
508         x5r = w;
509         y5r = 17/64 h + thick / 16;
510
511         penpos6 (hair, -90);
512         x6r = 37/80 w;
513         y6r = 0;
514
515         penpos7 (3/2 thin, 90);
516         x7 = .83 w;
517         y7 = y3;
518
519         penlabels (range 1 thru 7);
520
521         save alpha, t, outer_t;
522         alpha = 25;
523         t = tense;
524         outer_t := 0.93;
525
526 %       pickup pencircle scaled 1;
527 %       draw
528         fill number_flare_path (z1l, 180, 90, hair, 7/8 flare, x1l - .5 hair,
529                                 .16 h, 0.06, 1.5, -1)
530              ..tension outer_t.. z2l{down}
531              ..tension outer_t.. z7r{dir (180 + alpha)}
532              .. z7l{dir (-alpha)}
533              ..tension outer_t.. z5r{down}
534              ..tension outer_t.. number_flare_path (z6r, 180, -90, hair,
535                                                     flare, x6l, .18 h, 0.06,
536                                                     1.5, 1)
537              .. z5l{up}
538              ..tension t.. z3l{left}
539              .. z4l{left}
540              .. z4r{right}
541              .. z3r{right}
542              ..tension t.. z2r{up}
543              ..tension t.. cycle;
544 fet_endchar;
545
546
547 fet_beginchar ("Numeral 4", "four");
548         save alpha, beta, gamma;
549
550         set_char_box (0, 4/5 height# * widen, 0, height#);
551
552         message "w:" & decimal w;
553         message "h:" & decimal h;
554
555         alpha = 0;
556         calc_kuulleke (3/2 thick, alpha);
557
558         z1r = (w - 3/4 thick, height);
559         z5 = (thin, 1/4 height + thin);
560
561         beta = angle (z3r - z5);
562
563         penpos6 (thin, -90);
564         z6l = z5;
565
566         penpos7 (thin, -90);
567         y7 = y6;
568         x7 = w - 1/2 thin;
569
570         penpos8 (thin, -alpha);
571         z8r = z5;
572
573         penlabels (range 1 thru 8);
574
575         gamma = angle (length (z1r - z1), 2 kuulleke);
576
577         fill z2r{dir (alpha - gamma)}
578              .. z4
579              .. {dir (alpha + gamma)}z3l
580              .. {dir (180 + beta)}z3r
581              -- z8r
582              -- z7l{right}
583              .. {left}z7r
584              -- z6r{left}
585              ..tension 0.8 and 2.. z8l{dir (beta)}
586              .. {up}z2l
587              .. cycle;
588
589         clearxy;
590
591         alpha := beta;
592         calc_kuulleke (thick, alpha);
593
594         z1r = (w - 3/4 thick, height - (3/2 thin) / cosd (alpha));
595
596         penpos5 (thick, 0);
597         z5 = (x1, foot_top);
598
599         gamma := angle (length (z1r - z1), 2 kuulleke);
600
601         fill z2r{dir (alpha - gamma)}
602              .. z4
603              .. {dir (alpha + gamma)}z3l
604              .. {down}z3r
605              -- z5r
606              -- z5l
607              -- z2l{up}
608              .. cycle;
609
610         penlabels (1, 2, 3, 4, 5);
611
612         draw_foot (x5);
613 fet_endchar;
614
615
616 fet_beginchar ("Numeral 5", "five");
617         save alpha, beta, gamma, delta;
618         save inner_t, outer_t;
619         save pat;
620         path pat;
621
622         set_char_box (0, 27/40 height# * widen, 0, height#);
623
624         message "w:" & decimal w;
625         message "h:" & decimal h;
626
627         alpha = 0;
628         calc_kuulleke (w - thin, alpha);
629
630         z1 = (w / 2 + 1/8 thick, h);
631
632         penpos5 (thin, 0);
633         z5l = (x1l, h - 15/16 thick);
634
635         penpos6 (hair, 90 - 45);
636         z6 = z5r + 1/2 hair * dir (-45);
637
638         penpos7 (thin, 0);
639         z7l = (x1l, h / 2 + thin - hair);
640
641         penlabels (range 1 thru 7);
642
643         gamma = angle (length (z1r - z1), 2 kuulleke);
644
645         pat := z2r{dir (alpha - gamma)}
646                .. z4
647                .. {dir (alpha + gamma)}z3l
648                .. z3r{dir (-135)}
649                .. {left}z6r
650                .. {down}z6l
651                -- z7r{down}
652                .. {up}z7l
653                -- z2l{up}
654                .. cycle;
655
656         beta = 45;
657         delta = 180 + beta + 10;
658         z8r = (x7r, y7r - 1/16 thick + thin);
659         z8l = directionpoint dir (delta) of
660                 subpath (6, 7) of pat;
661
662         % include intersection point to improve overlap removal
663         fill subpath (0, 6) of pat
664              .. z8l
665              .. subpath (7, length (pat)) of pat
666              .. cycle;
667
668         penpos9 (thin, 90);
669         y9 = 10/16 [y5, y7];
670         x9 = .36 [x8r, x10r];
671
672         penpos10 (thick, 0);
673         x10r = w + hair / 2;
674         y10r = 1/2 [y9r, y11r];
675
676         penpos11 (hair, -90);
677         y11r = 0;
678         x11r = .7 [0, x10l];
679
680         penlabels (range 8 thru 12);
681
682         inner_t = 1.0;
683         outer_t = .85;
684
685         fill z8r {dir (beta)}
686              .. z9r{right}
687              ..tension outer_t.. z10r{down}
688              .. number_flare_path (z11r, 180, -90, hair, flare, x11l,
689                                    .18 h, 0.06, 1.5, 1)
690              .. z11l{right}
691              ..tension inner_t.. z10l{up}
692              ..tension inner_t.. z9l{left}
693              .. z8l{dir (delta)}
694              -- cycle;
695 fet_endchar;
696
697
698 fet_beginchar ("Numeral 6", "six");
699         draw_six;
700 fet_endchar;
701
702
703 fet_beginchar ("Numeral 7", "seven");
704         save tolerance;
705         save alpha, beta, gamma, delta;
706         save bow;
707         path bow;
708
709         set_char_box (0, 11/15 height# * widen, 0, height#);
710
711         message "w:" & decimal w;
712         message "h:" & decimal h;
713
714         alpha = -180;
715
716 if true:
717         penpos1 (3/2 thick, 180 + alpha);
718         penpos2 (hair, 180 + alpha - 45);
719         penpos3 (hair, 180 + alpha + 45);
720
721         z2 = z1l + (1/4 sqrt (2) * hair) * dir (alpha - 135);
722         z3 = z1r + (1/4 sqrt (2) * hair) * dir (alpha - 45);
723         z4 = z1 + kuulleke * dir (alpha - 90);
724 else:
725         % does not work
726         calc_kuulleke (3/2 thick, -alpha);
727 fi;
728
729         z1l = (thin, 0);
730
731         beta = 55;
732         penpos5 (thin, 90 + beta);
733         z5 = (w, h) + (1/2 sqrt (2) * thin) * dir (-135);
734
735         gamma = angle (length (z1r - z1), 2 kuulleke);
736         delta = 12;
737
738         pickup pencircle;
739
740         fill z3l{dir (alpha - gamma)}
741              .. z4
742              .. {dir (alpha + gamma)}z2r
743              .. z2l{dir (beta + delta)}
744              .. {dir (beta)}z5r
745              .. z5l{dir (180 + beta)}
746              .. {dir (delta - 90)}z3r
747              .. cycle;
748
749         penlabels (1, 2, 3, 4, 5);
750
751         alpha := -45 * widen;
752
753         penpos11 (1/2 thick, 90);
754         z11 = (3/2 thin, h - (thick + thin) / 2);
755
756         penpos13 (thin, 90 + beta);
757         z13 = z5;
758
759         penpos12 (thick, 90 + alpha);
760         x12 = 1/2 [x11, x13] - 1/4 thick;
761         y12 = h - 15/16 thick + thin * widen;
762
763         penpos14 (thin, 0);
764         z14l = (0, h - thin / 2);
765
766         penpos15 (thin, 0);
767         z15l = (0, h / 2 + thin / 2);
768
769         penpos16 (9/8 thick, 90);
770         z16r = (thin, y11r + 2/16 thick);
771
772         tolerance := epsilon;
773
774         % Find proper tension to exactly touch the x axis.
775         % Later on we directly use `bow'.
776         vardef f (expr t) =
777                 bow := z11r{dir (beta)}
778                        ..tension t.. {dir (alpha)}z12r;
779                 ypart (directionpoint right of bow) > h
780         enddef;
781
782         % the return value of `solve' is stored in a dummy variable
783         t = solve f (0.8, 1.2);
784
785         fill bow
786              .. {dir (beta)}z13r
787              -- z13l{dir (180 + beta)}
788              .. {dir (180 + alpha)}z12l
789              .. {dir (180 + beta)}z11l
790              .. {down}z16l
791              -- z15r{down}
792              .. {up}z15l
793              -- z14l{up}
794              .. {down}z14r
795              -- z16r{down}
796              ..tension 1.5.. {dir (beta)}cycle;
797
798         penlabels (range 11 thru 16);
799 fet_endchar;
800
801
802 fet_beginchar ("Numeral 8", "eight");
803         save alpha, beta;
804
805         set_char_box (0, 11/15 height# * widen, 0, height#);
806
807         message "w:" & decimal w;
808         message "h:" & decimal h;
809
810         alpha = 60;
811         beta = alpha - 15;
812
813         z1 = (w / 2, h / 2 + thick / 8);
814
815         penpos2 (14/8 thin, 0);
816         z2 = (w / 3, h / 2 + thin);
817
818         penpos3 (3/2 thin, 0);
819         z3l = (0, h / 4 + thin / 2);
820
821         penpos4 (hair, 90);
822         z4l = (x1, 0);
823
824         penpos5 (thick, 90 + 90 + alpha);
825         z5 = z1 + w / 4 * dir (alpha - 90);
826
827         penpos6 (thick, 90 + 90 + alpha);
828         z6 = z1 + (w / 4 - thin / 2) * dir (90 + alpha);
829
830         penpos7 (hair, 90);
831         z7r = (x1 + .02 w, h);
832
833         penpos8 (3/2 thin, 0);
834         z8r = (w - thin / 2, 3/4 h + thin / 2);
835
836         penpos9 (13/8 thin, 0);
837         z9 = (2/3 w, h / 2);
838
839         penlabels (range 1 thru 9);
840
841         save t;
842         t = tense;
843
844         fill z2r{dir (180 + beta)}
845              .. z3r{down}
846              .. z4r{right}
847              .. z5r{dir (90 + alpha)}
848              -- z6r{dir (90 + alpha)}
849              ..tension t.. z7r{right}
850              .. z8r{down}
851              .. {dir (180 + beta)}z9r
852              -- z9l{dir (beta)}
853              .. z8l{up}
854              .. z7l{left}
855              .. {dir (alpha - 90)}z6l
856              -- z5l{dir (alpha - 90)}
857              ..tension t.. z4l{left}
858              .. z3l{up}
859              .. {dir (beta)}z2l
860              -- cycle;
861 fet_endchar;
862
863
864 fet_beginchar ("Numeral 9", "nine");
865         draw_six;
866 %       xy_mirror_char;
867
868         currentpicture := currentpicture scaled -1;
869         currentpicture := currentpicture shifted (w, h);
870 fet_endchar;
871
872
873 ligtable "3":
874         "3" kern 0.1 space#,
875         "0" kern 0.1 space#;
876
877 ligtable "2":
878         "7" kern 0.15 space#;