enddef;
+def draw_staff(expr first, last, offset)=
+ pickup pencircle scaled stafflinethickness;
+ for i:= first step 1 until last:
+ draw (- staff_space, (i + offset) * staff_space) .. (4 staff_space,( i+ offset)* staff_space);
+ endfor
+ enddef;
+
+
%
% Transforms
%
shifted -point scaled scale shifted point
enddef;
+
+%
+% make a local (restored after endgroup) copy of t_var
+%
+def local_copy(text type, t_var)=
+ save copy_temp;
+ type copy_temp;
+ copy_temp := t_var;
+ save t_var;
+ type t_var;
+ t_var := copy_temp;
+enddef;
+
+
%
% Urgh! Want to do parametric types
%
% drawing
%
+def soft_penstroke text t =
+ forsuffixes e = l,r: path_.e:=t; endfor
+ if cycle path_.l:
+ cyclestroke_
+ else:
+ fill path_.l .. tension1.5 .. reverse path_.r .. tension1.5 .. cycle
+ fi
+enddef;
+
+
+%
+% make a round path segment going from P to Q. 2*A is the angle that the
+% path should take.
+%
+
+def simple_serif(expr p,q, a)=
+ p{dir(angle(q-p) -a)} .. q{ - dir(angle(p -q) + a)}
+enddef;
+%
+
% a: x diameter
% b: y diameter
% err_x: drift of y axis at top
superellipse((a,err_x),(-err_y,b),(-a,-err_x),(err_y,-b),super);
enddef;
+
+
+%
+% draw an axis aligned block making sure that edges are on pixels.
+%
+
+def draw_rounded_block (expr bottom_left, top_right, roundness) =
+ save round;
+ round = floor min(roundness,xpart (top_right-bottom_left),
+ ypart (top_right-bottom_left));
+
+
+ pickup pencircle scaled round;
+
+ begingroup;
+ save x,y;
+ z2+(round/2,round/2) = top_right;
+ z4-(round/2,round/2) = bottom_left;
+ y3 = y2;
+ y4 = y1;
+ x2 = x1;
+ x4 = x3;
+ fill bot z1 .. rt z1 --- rt z2 .. top z2 ---
+ top z3 .. lft z3 --- lft z4 .. bot z4 --- cycle;
+ endgroup;
+ enddef;
+
+
+
+ def draw_block (expr bottom_left, top_right) =
+ draw_rounded_block (bottom_left, top_right, blot_diameter);
+ enddef;
+
+ def draw_gridline (expr bottom_left,top_right,thickness) =
+ draw_rounded_block (bottom_left-(thickness/2,thickness/2),
+ top_right+(thickness/2,thickness/2),
+ thickness);
+ enddef;
+
+
def draw_brush(expr a,w,b,v) =
save x,y;
z1=a; z2=b;
fill z3r{z3r-z5l}..z4l..{z5r-z3l}z3l..z5r{z5r-z3l}..z6l..{z3r-z5l}z5l..cycle;
enddef;
+
+
+%
+% make a superellipsoid segment going from FROM to TO, with SUPERNESS.
+% Take superness = sqrt(2)/2 to get a circle segment
+%
+% see Knuth, p. 267 and p.126
+def super_curvelet(expr from, to, superness, dir) =
+ if dir = 1:
+ (superness [xpart to, xpart from], superness [ypart from,ypart to]){to - from}
+ else:
+ (superness [xpart from, xpart to], superness [ypart to,ypart from]){to - from}
+ fi
+enddef;
+
+
+%
+% Bulb with smooth inside curve.
+%
+% alpha = start direction.
+% beta = which side to turn to.
+% flare = diameter of the bulb
+% line = diameter of line attachment
+% direction = is ink on left or right side (1 or -1)
+%
+def flare_path(expr pos,alpha,beta,line,flare, direction) =
+ begingroup;
+ clearxy;
+ penpos1(line,180+beta+alpha);
+ z1r=pos;
+ penpos2(flare,180+beta+alpha);
+ z2=z3;
+ penpos3(flare,0+alpha);
+ z3l=z1r+(1/2+0.43)*flare*dir(alpha+beta) ;
+ save taille;
+ taille = 0.0;
+ z4=z2r- line * dir(alpha);
+ penlabels(1,2,3,4);
+ pickup pencircle;
+ save t; t=0.833;
+ save p;
+ path p;
+ p:=z1r{dir(alpha)}..z3r{dir(180+alpha-beta)}..z2l{dir(alpha+180)}
+ ..z3l{dir(180+alpha+beta)}..tension t
+ ..z4{dir(180+alpha+beta)}..z1l{dir(alpha+180)};
+
+ if direction = 1:
+ p
+ else:
+ reverse p
+ fi
+ endgroup
+ enddef;
+
+def flare_path_t(expr pos,alpha,beta,line, flare, bulb, direction) =
+ begingroup;
+ clearxy;
+ penpos1(line, 180+beta+alpha);
+ z1r=pos;
+ penpos2(bulb, 180+beta+alpha);
+ z2=z3;
+ penpos3(bulb, 0+alpha);
+ save taille,roundness;
+
+ taille = -0.5;
+ roundness = 0.5;
+ z3r = z1 + flare * (dir (alpha) + dir (alpha +beta));
+ z4= z2r - taille * line * dir(alpha)
+ + roundness * line *dir (alpha - beta)
+ ;
+
+ penlabels(1,2,3,4);
+ pickup pencircle;
+ save t; t=0.833;
+ save p;
+ path p;
+ p:=z1r{dir(alpha)}..z3r{dir(180+alpha-beta)}..z2l{dir(alpha+180)}
+ ..z3l{dir(180+alpha+beta)}..tension t
+ ..z4{dir(180+alpha+beta)}
+ ..z1l{dir(alpha+180)};
+
+ if direction = 1:
+ p
+ else:
+ reverse p
+ fi
+ endgroup
+ enddef;
+
+
def brush(expr a,w,b,v) =
begingroup;
draw_brush(a,w,b,v);
endgroup;
enddef;
-def draw_rounded_path(expr p, thick) =
- push_pen(currentpen);
- fill p;
- pickup pencircle scaled thick;
- draw p;
- currentpen := pop_pen;
-enddef;
-
-%
%
+% Draw a (rest) crook, starting at thickness STEM in point A,
+% ending a ball W to the left, diameter BALLDIAM
+% ypart of the center of the ball is BALLDIAM/4 lower than ypart A
%
def balled_crook(expr a, w, balldiam, stem) =
begingroup;
endgroup;
enddef;
+
def y_mirror_char =
currentpicture := currentpicture yscaled -1;
set_char_box(charbp, charwd, charht, chardp);
currentpicture := currentpicture scaled -1;
set_char_box(charwd, charbp, charht, chardp);
enddef;
+
+
+%
+% center_factor: typically .5, the larger, the larger the radius of the bulb
+% radius factor: how much the bulb curves inward
+%
+def draw_bulb(expr turndir, zl, zr, bulb_rad, radius_factor)=
+ begingroup;
+ clearxy;
+ save rad, ang;
+
+ ang = angle(zr-zl);
+
+ % don't get near infinity
+ %z0 = zr + bulb_rad * (zl-zr)/length(zr -zl);
+ z0 = zr + bulb_rad /length(zr -zl) * (zl-zr);
+
+ rad = bulb_rad;
+
+ z1 = z0 + radius_factor* rad * dir(ang + turndir* 100);
+ z2 = z0 + rad * dir(ang + turndir*300);
+ labels(0,1,2);
+ fill zr{dir (ang + turndir* 90)} .. z1 .. z2 -- cycle;
+
+ endgroup
+enddef;