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