1 % Feta (not the Font-En-Tja) music font -- dynamic signs
2 % This file is part of LilyPond, the GNU music typesetter.
4 % Copyright (C) 1997--2012 Jan Nieuwenhuizen <janneke@gnu.org>
6 % LilyPond 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.
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.
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/>.
20 ex# := (dynamic_design_size / 2.4) * pt#;
21 descender# := 0.5 ex#;
22 ascender# := 0.72 ex#;
23 staffspace# := 1.75 / 2.0 * ex#;
24 horizontal_space# := .66 ex#;
27 font_normal_space horizontal_space#;
29 define_pixels (staffspace, linethickness, ex, descender, ascender);
33 % TODO: blot diameter should be fixed, not scalable.
36 save serif_thick, med_thick, bottom_blot;
38 serif_thick# = 1.1 linethickness#;
39 define_blacker_pixels (serif_thick);
41 med_thick = round (1.5 linethickness);
42 bottom_blot = 1.3 serif_thick;
47 fet_beginchar ("Space", "space");
48 set_char_box (0, horizontal_space#, 0, ex#);
53 % Couldn't find many z examples. This one is losely inspired
54 % by a sfz from Mueller Etuden fuer Horn (Edition Hofmeister).
59 fet_beginchar ("dynamic z", "z");
60 save thin_thick, top_narrow, over_shoot;
63 set_char_box (0, .98 ex#, 0, 0.9 ex#);
65 thin_thick = serif_thick;
66 top_narrow = thin_thick;
67 top_overshoot = .8 serif_thick;
70 bot_overshoot = serif_thick;
75 penpos1 (top_thick, 80);
80 y2 = y1r - top_overshoot;
82 y3 = h - .7 thin_thick;
83 x3 = w - .6 top_narrow - .5 thin_thick;
87 penpos3 (thin_thick, angle (z3 - z4) + 90);
88 penpos4 (thin_thick, angle (z3 - z4) + 90);
90 penpos5 (bot_thick, 70);
92 y5l = .4 bot_overshoot;
94 penpos6 (3/2 bot_thick, 70);
96 x6 = w - 3 top_narrow;
101 penpos8 (thin_thick, 20);
102 x8r = w - .35 top_narrow;
105 penlabels (range 0 thru 8);
107 % pickup pencircle scaled 1;
112 .. simple_serif (z3l, z3r, 90)
115 ..tension 1.2.. cycle;
125 fill simple_serif (z4r, z4l, 90)
129 .. simple_serif (z8r, z8l, 90)
136 % forte f, grabbed from Ed Breitkopf Mozart horn concerto 3.
140 % * the bulbs are open
142 % * blotting around the serif
144 % TODO: insert blots around the serif
150 fet_beginchar ("dynamic f", "f");
151 save left_angle, right_angle;
152 save serif_length, serif_eccentricity;
154 save bulb_thick, bulb_diam, fill_up;
159 set_char_box (0, 1.1 ex#, descender#, ex# + ascender#);
161 bulb_diam = 7.5 / 40 ex;
162 bulb_thick = 8.5 / 40 ex;
163 fill_up = 1.5 serif_thick;
164 left_angle = slant_angle - 6;
165 right_angle = slant_angle - 3;
167 serif_length = 0.96 ex;
168 serif_eccentricity = 0.01 ex;
170 % z1 is the `base point'
171 z1 = (0.2 ex, -serif_thick);
173 penpos2 (f_thick, 0);
175 z2l = z1 + whatever * dir (90 - left_angle);
177 penpos3 (med_thick, -90);
178 y3l = y1 + ex + ascender;
181 penpos4 (bulb_thick, -20);
182 z3r = whatever [z4r, z4l];
186 penpos5 (bulb_thick, -45);
187 x5r = 0.1 [x4l, x4r];
188 y5l = y4l - bulb_diam;
190 z6 = z2r + whatever * dir (90 - right_angle);
193 penpos7 (med_thick, -90);
197 penpos8 (bulb_thick, 160);
200 z7l = whatever [z8r, z8l];
202 penpos9 (bulb_thick, 135);
203 x9r = 0.1 [x8l, x8r];
204 y9l = y8l + bulb_diam;
207 penlabels (2, 3, 4, 5, 7, 8, 9);
209 % pickup pencircle scaled 1;
214 ..tension 1.1.. z3l{right}
218 ..tension 0.8.. z4l{up}
220 ..tension 1.1.. z2r{z6 - z2r}
222 ..tension 1.25.. z7r{left}
226 ..tension 0.8.. z8l{down}
230 x13 - x14 = serif_length;
233 0.5 [x13, x14] = x2 + serif_eccentricity;
235 draw_rounded_block (z14 - (0, 0.7 serif_thick),
236 z13 + (0, 0.7 serif_thick),
246 % - The `s' is trapezoidal (i.e., narrower at the top).
248 % - The white space is differently shaped at the top (the bulb's inner
249 % curve is filled up).
251 % - Less heavy than the `f' and `p' signs.
256 fet_beginchar ("dynamic s", "s");
257 save left_angle, right_angle;
258 save s_thick, s_thin;
259 save bulb_diam, bulb_len;
264 set_char_box (0, 17/24 ex#, 0, ex#);
266 over_shoot = 0; % .2 serif_thick;
267 bulb_diam = 11/70 ex;
268 bulb_len = 1.0 bulb_diam;
269 left_angle = slant_angle - 2;
270 right_angle = slant_angle - 11;
272 s_thin = serif_thick;
276 penpos1 (bulb_diam, -45);
277 z1 = 0.35 [z2l, z2r] + bulb_len * dir (45);
279 penpos2 (bulb_diam, -25);
280 y2l = 0.845 [y7r, y3r];
281 z2l = base_point + whatever * dir (90 - left_angle);
283 penpos3 (s_thin, 100);
285 y3l = ypart base_point - over_shoot;
287 penpos4 (s_thick, 25);
289 z4r = base_point + (w, 0) + whatever * dir (90 - right_angle);
291 penpos5 (s_thick, 40);
292 z5 = z3l + whatever * dir (90 - right_angle);
293 y5 = 0.48 [y7r, y3r];
295 penpos6 (s_thick, 25);
296 z6l = base_point + whatever * dir (90 - left_angle);
299 penpos7 (.9 s_thin, 110);
300 z7l = 0.45 [z6r, z8l] + whatever * dir (90 - left_angle);
301 y7r = h + over_shoot;
303 penpos8 (.9 bulb_diam, -25);
304 z8 = .6 [z4l, z4r] + whatever * dir (90 - right_angle);
305 y8r = 0.23 [y7r, y3r];
307 penpos9 (.9 bulb_diam, -45);
308 z9 = .4 [z8r, z8l] + .9 bulb_len * dir (-135);
310 penlabels (range 1 thru 9);
312 % pickup pencircle scaled 1;
339 slant := ypart (dir (slant_angle));
343 % Piano `p', grabbed from Ed Breitkopf Mozart horn concerto 3.
347 % * There is no dishing in the serif (but we do it anyway).
349 % * The cheek is a little fatter than the stem.
351 % * The slant is extreme: 20 degrees.
353 % * The twiddle (what's-it-called) is a slightly darker than the serif.
355 % * The hole in the cheek has a straight right side.
357 % * Corners are filled up.
362 fet_beginchar ("dynamic p", "p")
363 % TODO: w really is 13/12 ex
364 % but should do kerning
366 save twiddle_thick, stem_thick, cheek_thick, cheek_width;
367 save fill_up, straigh_len;
368 save serif, dishing_angle, p, tmp;
369 save cheek_medium, left_serif_protrude, right_serif_protrude;
370 save lower_overshoot;
371 save blot_t, corner_t;
375 set_char_box (0, 15/12 ex#, descender#, 1.0 ex#);
377 twiddle_thick = med_thick;
378 cheek_medium = 1/6 ex;
381 fill_up = 1.5 serif_thick;
382 straigh_len = 0.5 ex;
383 lower_overshoot = .3 serif_thick;
386 cheek_thick = 13/32 ex;
387 cheek_width = 0.72 ex;
388 left_serif_protrude = 18/60 ex;
389 right_serif_protrude = 15/60 ex;
391 currenttransform := currenttransform slanted slant;
393 penpos1 (twiddle_thick, -slant - 5);
394 penpos2 (cheek_medium, 90 - slant);
395 penpos3 (cheek_medium, 90 - slant);
397 x4r - x4l = cheek_thick;
399 penpos4 (whatever, 0);
400 penpos5 (whatever, -38);
401 penpos6 (stem_thick, 0);
402 penpos17 (straigh_len, 90 - slant);
404 whatever [z17l, z17r] = z4l;
407 y6l = -descender + serif_thick / 2;
408 z1l = z6l - whatever * dir (110);
411 z7 = whatever * up + z6l;
413 z2l = whatever * up + 0.3 [z7, z1r];
415 z8 = 2/3 [z6l, z6r] + whatever * up;
417 z3l = 0.58 [(stem_thick, -descender),
418 (stem_thick + cheek_width - cheek_thick, -descender)]
421 z4r = whatever * up + (stem_thick + cheek_width, -descender);
422 z5l = whatever * up + z3l;
423 y5r = -lower_overshoot;
424 y5l = y5r + cheek_medium * ypart dir (55);
425 z9 = z6r + whatever * up;
429 .. {dir (-60)}z8{dir 60}
432 ..tension 1.1.. z5r{left}
438 ..tension 1.2.. simple_serif (z1r, z1l, -90)
442 corner_t := xpart (p intersectiontimes z9);
444 % pickup pencircle scaled 1;
447 fill subpath (0, corner_t - 2 blot_t) of p
448 .. subpath (corner_t + blot_t, length p) of p
452 z12 = z6r + whatever * up;
457 ..tension 1.05.. z12{down}
458 ..tension 1.05.. z5l{right}
461 penlabels (1, 2, 3, 4, 5, 6, 17);
464 pickup pencircle scaled serif_thick;
466 lft x11 = -left_serif_protrude;
467 rt x10 = stem_thick + right_serif_protrude;
468 bot y10 = bot y11 = -descender;
470 z15 = z6l + up * fill_up;
471 z16 = z6r + up * 1.2 fill_up;
473 % Since pens are not affected by currenttransform we directly
474 % transform the necessary points, then simulating the pen with
475 % an outline while using the identity transformation.
477 forsuffixes $ = 7, 10, 11, 15, 16:
478 tmp := z$ transformed currenttransform;
483 currenttransform := identity;
487 serif := simple_serif (z10, z11, dishing_angle);
489 penpos10 (serif_thick, -dishing_angle - 90);
490 penpos11 (serif_thick, dishing_angle - 90);
491 penpos13 (serif_thick, angle (direction 0.05 of serif) + 90);
492 penpos14 (serif_thick, angle (direction 0.85 of serif) + 90);
494 z13 = point 0.05 of serif;
495 z14 = point 0.85 of serif;
497 penlabels (10, 11, 13, 14);
502 .. z14l{direction 0.85 of serif}
503 .. z11l{-dir (dishing_angle)}
504 .. z11r{dir (dishing_angle)}
505 .. z14r{-direction 0.85 of serif}
506 .. z13r{-direction 0.05 of serif}
507 .. z10r{dir (-dishing_angle)}
508 .. z10l{-dir (-dishing_angle)}
509 .. z13l{direction 0.05 of serif}
518 % * Right stem is fatter and more straight than the left two stems.
520 % * The twiddle at the left is similar to the `p' twiddle.
522 % * The bottoms of the stems are blotted.
525 % This is cut & paste programming. Somehow three `i' shapes in two
526 % characters (`p' and `m') -- doesn't seem worth the trouble of writing
532 fet_beginchar ("dynamic m", "m");
533 save i_thick, i_angle, i_twiddle_thick;
534 save i_twiddle_start_angle, i_twiddle_start_y;
535 save i_twiddle_end_angle, i_left_space;
536 save idir, center, right_ending;
539 pair center, idir, right_ending;
542 set_char_box (0, 1.5 ex#, 0, 1.0 ex#);
544 % should share code with p for twiddle.
546 overshoot = .25 serif_thick;
548 i_twiddle_thick = 1.2 serif_thick;
549 i_twiddle_start_y = 8/16 ex;
550 i_twiddle_start_angle = 0;
551 i_twiddle_end_angle := 35;
555 currenttransform := currenttransform slanted slant;
558 idir := dir (90 - i_angle);
559 i_left_space = 16/80 ex;
561 penpos1 (i_twiddle_thick, -i_twiddle_start_angle);
562 y1 = i_twiddle_start_y;
563 z1r = center - (i_left_space, 0) + whatever * idir;
565 y2l = ex + overshoot;
566 z2l = .08 [z3l, z3r] + whatever * idir;
567 z2r = 5/8 [z1r, z3l] + whatever * idir;
571 penpos3 (i_thick, 0);
572 y3 = 0.5 bottom_blot + ypart center;
573 z3l = center + whatever * idir;
575 penpos4 (i_thick - bottom_blot, 0);
577 z4 - z3 = whatever * idir;
579 penpos5 (i_thick, 0);
580 z5 = z4 + whatever * idir;
583 fill simple_serif (z1l, z1r, 90)
584 ..tension 1.2.. z2r{right}
591 ..tension 1.2.. z2l{left}
595 penlabels (1, 2, 3, 4, 5);
597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602 idir := dir (90 - i_angle);
603 i_left_space := 14/80 ex;
605 penpos1 (serif_thick, -i_twiddle_start_angle);
609 z2l = .08 [z3l, z3r] + whatever * idir;
610 z2r = 5/8 [z1r, z3l] + whatever * idir;
614 penpos3 (i_thick, 0);
615 y3 = 0.5 bottom_blot + ypart center;
616 z3l = z5l + whatever * idir;
618 penpos4 (i_thick - bottom_blot, 0);
620 z4 - z3 = whatever * idir;
622 penpos5 (i_thick, 0);
623 z5l = right_ending + (i_left_space, 0);
625 fill simple_serif (z1l, z1r, 90)
626 ..tension 1.05.. z2r{right}
633 ..tension 1.2.. z2l{left}
637 penlabels (1, 2, 3, 4, 5);
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 idir := dir (90 - i_angle);
646 i_left_space := 14/80 ex;
648 penpos1 (serif_thick, -i_twiddle_start_angle);
651 y2l = ex + overshoot;
652 z2l = .08 [z3l, z3r] + whatever * idir;
653 z2r = 5/8 [z1r, z3l] + whatever * idir;
657 penpos3 (whatever, 20);
658 y3l = 1/8 ex + ypart center;
659 z3l = z7l + whatever * idir;
660 z3r = z7r + whatever * idir;
662 penpos5 (whatever, 10);
663 z5l = right_ending + (i_left_space, 0);
664 z5r = z7r + whatever * idir;
666 penpos6 (serif_thick, -i_twiddle_end_angle);
667 y6l = 23/80 ex + ypart center;
668 z6l = 1.6 [z3l, z3r] + whatever * idir;
670 penpos7 (i_thick, 0);
672 z7l = z5l + whatever * idir;
674 z8 = z7 - (0, overshoot);
676 fill simple_serif (z1l, z1r, 90)
677 ..tension 1.05.. z2r{right}
681 .. simple_serif (z6r, z6l, 90)
682 ..tension 0.85.. z3r{z5 - z3}
684 ..tension 1.2.. z2l{left}
687 penlabels (range 1 thru 8);
693 fet_beginchar ("dynamic r", "r");
694 save base_point, stem_thick, bulb_diam;
695 save twiddle_thick, attach_len, overshoot, taille;
698 set_char_box (0, .75 ex#, 0, ex#);
702 twiddle_thick = 1.1 serif_thick;
703 overshoot = .5 serif_thick;
704 taille = -0.3 serif_thick;
705 attach_len + bulb_diam / 2 + stem_thick = w;
710 currenttransform := identity slanted ypart (dir (15));
712 penpos1 (stem_thick, 0);
714 y1l = .5 bottom_blot;
716 penpos2 (stem_thick, 0);
718 y2l - y1l = 36/47 ex;
720 penpos3 (twiddle_thick, -20);
724 x4l = -0.1 [x1l, x1r];
725 y4l = ex + overshoot;
726 x4r = 0.62 [x3r, x2l];
727 y4r = 0.5 [y4l, y2l];
729 penpos5 (whatever, -74);
730 y5l - y5r = bulb_diam;
731 y5l = ex + overshoot;
732 x5 = x2r + attach_len;
734 penpos6 (bulb_diam, 0);
737 % z7 = z6l + taille * dir (180);
738 z7 = z6 + .4 * bulb_diam * dir (-125);
740 z8 = 9/10 [z1r, z2r];
742 x9 = 0.15 [x1r, x1l];
745 penpos10 (stem_thick - bottom_blot, 0);
749 % pickup pencircle scaled 1;
758 ..tension 1.2.. {down}simple_serif (z3r, z3l,-90){up}
760 .. {curl 1}z9{curl 1}
766 ..tension 1.2.. z8{down}
769 penlabels (range 1 thru 10);
786 %% notes from old dyn code.
788 % `f' obviously has a _lot_ bigger slant than `p' (see Wanske p.239).
789 % However; perhaps we need two f symbols:
790 % - a super-slanted one used in `f', `mf', `sfz', `sf'
791 % - a more normal-slanted in `ff', `fff', `fp', `fp' (see Wanske p.241)
793 % Looking at professionally typeset music reveals that typesetters
794 % are somewhat unsure about slanting in `mf', `fp', `sfz'
796 % `f' and `p' (in any combination) are a lot (factor two) fatter than
797 % `s', `m', and `z'. Sometimes the `m' and `z' are a bit fatter than
800 % Chester, Breitkopf suggest smaller sizes of these other glyphs,
801 % using the x-height as reference point.