% -*-Fundamental-*- % feta-bolletjes.mf -- implement noteheads % % source file of LilyPond's pretty-but-neat music font % % (c) 1997--2003 Jan Nieuwenhuizen % & Han-Wen Nienhuys % & Juergen Reuter % % most beautiful noteheads are pronounced, not circular, % and not even symmetric. % These examples are inspired by [Wanske], see literature list save black_notehead_width; numeric black_notehead_width; fet_begingroup("noteheads"); test_outlines := 0; noteheight#:=staff_space#+ (1 + overdone_heads) *stafflinethickness#; % % SLANT moves both extremes on the long axis (by SLANT * ELLIPSIDITY, % so SLANT = -1, puts the extreme on the long axis next to the short axis one.) % def draw_outside_ellipse (expr ellipsidity, tilt, superness, slant) = save attachment_y; save p; path p; p := superellipse ((ellipsidity, 0), (-slant * ellipsidity, 1.0), (- ellipsidity, 0), (slant * ellipsidity, -1.0), superness); p := p rotated tilt; save top_point, right_point; pair top_point, right_point; top_point := directionpoint left of p; right_point := directionpoint up of p; save scaling, width, height; scaling# = noteheight# /(2 ypart (top_point)); width# := 2 xpart (right_point) * scaling#; define_pixels (width, scaling); set_char_box (0, width#, noteheight#/2, noteheight#/2); % attachment Y charwy := ypart (right_point) * scaling#; charwx := width# ; p := p scaled scaling shifted (width/2, 0) ; if test_outlines = 1: pickup pencircle scaled 1 ; draw p; else: fill p; fi; enddef; def undraw_inside_ellipse (expr ellipsidity, tilt, superness, clearance, center) = begingroup save p; path p; p := superellipse ((ellipsidity, 0), (0, 1.0), (- ellipsidity, 0), (0, -1.0), superness); p := p rotated tilt; save top_point, right_point; pair top_point, right_point; top_point := directionpoint left of p; right_point := directionpoint up of p; save height, scaling; height# = staff_space# + stafflinethickness# - clearance; scaling# = height# /(2 ypart (top_point)); define_pixels (scaling); p := (p scaled scaling) shifted center; if test_outlines = 1: pickup pencircle scaled 1; draw p; else: unfill p; fi endgroup; enddef; % % dimensions aren't entirely right. % fet_beginchar ("Brevis notehead", "-1", "brevishead"); save stemthick, fudge; define_pixels (stemthick); fudge = blot_diameter /2; stemthick# = 2 stafflinethickness#; draw_outside_ellipse (1.80, 0, 0.707, 0); undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#, (w /2, 0)); pickup pencircle scaled stemthick; bot y1 = -d; top y2 = h; rt x1 - fudge = 0; x1 = x2; fudge + lft x3 = w; x4 = x3; y4 = y2; y3 = y1; draw_gridline(z1,z2,stemthick); draw_gridline(z3,z4,stemthick); fet_endchar; % whole note % Wanske, p.38 fet_beginchar("Whole notehead", "0", "wholehead") draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, 0.707, 0); undraw_inside_ellipse (1.30, 125 - puff_up_factor *10, 0.68, 2 stafflinethickness#, (w /2, 0)); % draw_staff_outline (-2, 2, 0.5); fet_endchar; % half note % Wanske, p.39 fet_beginchar("Half notehead", "1", "halfhead") draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17); undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#, (w/2, 0)); fet_endchar; % quarter note % Wanske p.38 fet_beginchar("Quart notehead", "2", "quarthead") draw_outside_ellipse (1.54 - puff_up_factor / 2.0, 32, 0.707, 0); black_notehead_width# := charwd; fet_endchar; fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead") draw_outside_ellipse (1.80, 0, 0.495, 0); undraw_inside_ellipse (1.30, 125, 0.6, .4 staff_space# + stafflinethickness#, (w /2, 0)); fet_endchar; % half note % Wanske, p.39 fet_beginchar("Half diamondhead", "1diamond", "halfdiamondhead") draw_outside_ellipse (1.50, 34, 0.49, 0.17); undraw_inside_ellipse (3.5, 33, 0.80, .3 staff_space# + 1.5 stafflinethickness#, (w/2, 0)); fet_endchar; % quarter note % Wanske p.38 fet_beginchar("Quart diamondheadh", "2diamondh", "diamondheadh") draw_outside_ellipse (1.80, 35, 0.495, -0.25); fet_endchar; save pen_thick; pen_thick# = stafflinethickness# + .1 staff_space#; define_pixels(pen_thick); begingroup; def def_triangle_old = save triangle,kern; path triangle; kern = 1/3(x2-x1); z2 = z1 rotated 120; z3 = z1 rotated 240; z12 = caveness[.5[z1,z2],z3]; z23 = z12 rotated 120; z31 = z12 rotated 240; triangle = z1 .. z12 .. z2 .. z2 .. z23 .. z3 .. z3 .. z31 .. z1 .. cycle; triangle := triangle shifted (-x1+pent/2-kern,0) xscaled xs; pickup pencircle scaled pent xscaled xs; hei = max(y1,-y2)+pent/2; %set_char_box(-kern*xs*fac, ((x3-x1)*fac+pent#)*xs,hei*fac,hei*fac); set_char_box(0, ((x3-x1-kern)*fac+pent#)*xs,hei*fac,hei*fac); enddef; def def_triangle = save triangle,kern; path triangle; save left_point, height, width; pair exact_left_point; exact_left_point := llap# * dir (90 + tilt); height# = max (ypart exact_left_point, -ypart (exact_left_point rotated 120)) + pen_thick#/2; kern# = 1/3 xpart (exact_left_point - (exact_left_point rotated 120)); width# = xpart (-exact_left_point + (exact_left_point rotated 240)); define_pixels (kern); z1 = (hround_pixels (xpart exact_left_point), vround_pixels (ypart exact_left_point)); z2 = z1 rotated 120; z3 = z1 rotated 240; z12 = caveness[.5[z1,z2],z3]; z23 = z12 rotated 120; z31 = z12 rotated 240; triangle = z1 .. z12 .. z2 .. z2 .. z23 .. z3 .. z3 .. z31 .. z1 .. cycle; triangle := triangle shifted (-x1+pen_thick/2-kern,0) xscaled xs; pickup pencircle scaled pen_thick xscaled xs; % labels(1,2,12,23,31,3); set_char_box(0, width# - kern#+ pen_thick#, height#, height#); enddef; fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead") save hei,xs; save llap; save tilt; tilt = 40; llap# = 3/4noteheight#; xs = 1.5; caveness:=0.1; def_triangle; draw triangle; fet_endchar; fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead") save hei,xs; save llap; save tilt; tilt = 40; llap# = 2/3noteheight#; xs = 1.2; caveness:=0.1; def_triangle; draw triangle; fet_endchar; fet_beginchar("Quart trianglehead", "2triangle", "trianglehead") save hei,xs; save llap; save tilt; tilt = 40; llap# = 2/3noteheight#; xs = 1.0; caveness:=0.1; def_triangle; filldraw triangle; fet_endchar; endgroup; %%% Editable values: % slope of slash. From scm/grob-description.scm. How to auto-copy? slash_slope := 1.7; % thickness of lines. quarter notes get 1.5slt width. slash_thick# := 2/3*0.48staff_space#; define_pixels(slash_thick); def draw_slash(expr hwid_hash) = set_char_box (0, staff_space# / slash_slope + hwid_hash, staff_space#/2 + stafflinethickness#/2, staff_space#/2 + stafflinethickness#/2); charwx := charwd; charwy := charht; clearxy; pickup pencircle scaled blot_diameter; bot y1 = - d; top y2 = h; lft x1 = 0; lft x2 = staff_space / slash_slope; rt x3 = w; y3 = y2; y4 = y1; x3- x2 = x4 - x1; filldraw z1 --- z2 --- z3 --- z4 --- cycle; if hwid_hash > 2 slash_thick#: save th; th = slash_thick - blot_diameter; y6 = y7; y5 = y8; y3 - y7 = th; y5 - y1 = th; z6 - z5 = whatever * (1, slash_slope); z8 - z7 = whatever * (1, slash_slope); z5 = z1 + whatever * (1, slash_slope) + (th, 0); z8 = z4 + whatever * (1, slash_slope) + (-th, 0); unfill z5 -- z6 -- z7 -- z8 -- cycle; fi labels (range 1 thru 10); enddef; fet_beginchar("Whole slashhead","0slash","wholeslashhead") draw_slash(2 slash_thick# + 0.5 staff_space#); fet_endchar; fet_beginchar("Half slashhead","1slash","halfslashhead") draw_slash(2 slash_thick# + 0.15 staff_space#); fet_endchar; fet_beginchar("Quart slashhead","2slash","quartslashhead") draw_slash(slash_thick#); fet_endchar; % thick is the distance between the two parallel lines in the cross (distance between centres of lines) def draw_cross(expr thick) = save pent, slant, ne_dir; pair ne_dir; save crz; path crz; pent# := 1.2stafflinethickness#; define_pixels (pent); pickup pencircle scaled pent; top y3 = h; ne_dir := (1, (2 h -pent)/(w - pent)); rt x4 = w/2; y5 = 0; z4 - z5 = whatever * ne_dir; x6 = 0; z6 - z3 = whatever * ne_dir; z3 - z4 = whatever * (ne_dir yscaled -1); z1 = (0, charht - 1.5 pent#); y2 = 0; z2 = z1 + whatever * (ne_dir yscaled -1); z7 = z2 + whatever * ne_dir; x7 = charwd/2 - .5 pent#; top y6 = h - pent; labels (1,2,3,4,5,6); crz = (z6 -- z3 -- z4 -- z5) ; draw crz shifted(w/2,0); draw crz xscaled -1 shifted(w/2,0); draw crz yscaled -1 shifted(w/2,0); draw crz scaled -1 shifted(w/2,0); charwx := charwd; charwy := y7; enddef; fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead") wid# := black_notehead_width#+4stafflinethickness#; hei# := noteheight#+stafflinethickness#; set_char_box(0, wid#,hei#/2,hei#/2); draw_cross(3.75stafflinethickness); fet_endchar; fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead") wid# := black_notehead_width#+2stafflinethickness#; hei# := noteheight#+stafflinethickness#/2; set_char_box(0, wid#,hei#/2,hei#/2); draw_cross(3stafflinethickness); fet_endchar; fet_beginchar("Crossed notehead", "2cross", "crossedhead") wid# := black_notehead_width#; hei# := noteheight#; set_char_box(0, wid#,hei#/2,hei#/2); draw_cross(stafflinethickness/4); fet_endchar; fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead") wid# := black_notehead_width#*sqrt(sqrt2); hei# := noteheight#*sqrt(sqrt2); set_char_box(0, wid#,hei#/2,hei#/2); cthick := (1.2+1/4)*stafflinethickness; cxr := w/2-cthick/2; cyr := h-cthick/2; pickup pencircle scaled cthick; draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0); xpos := cxr/sqrt2; ypos := cyr/sqrt2; draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos); draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos); charwx := 3/4 charwd ; charwy := 1/4 charwd ; fet_endchar; fet_endgroup("noteheads"); define_pixels(black_notehead_width);