%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Macros to support feyn.mf
% Release 0.4.3, 2022 July 20


def looselink = ..tension 0.75.. enddef;
def pen = pickup diagram_pen enddef;

numeric nn;
def dirlooselink(expr point,rtn) =
  looselink{(-point) rotated (90-rtn)}point enddef;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Draw three related characters, one plain, one with an right-pointing
% arrow, and one with a left-pointing one, at basechar, basechar-0x20 and
% basechar-0x60.
def threechars(expr basechar, name, cp, apoint, wsharp, hsharp, dsharp, anudge, apos) =
  % basechar : the charcode of the character in the lowercase range
  % name     : the name of the character
  % cp       : the path to be drawn
  % apoint   : the point along the path where arrow and annotation are to go
  % wsharp, hsharp, dsharp : the sharped dimensions of the character
  % anudge   : if a pair, the offset from (point apoint of cp) where
  %            the annotation is to go (usually numeric 0, indicating
  %            no offset)
  % apos     : one of the apos arguments to annotate_at
    beginchar (basechar, wsharp, hsharp, dsharp);
      name;
      pen;
      draw cp;
      annotate_at(point apoint of cp if (pair anudge): shifted anudge fi,
                  apos);
    endchar;
    beginchar (byte basechar-hex"20", wsharp, hsharp, dsharp);
      "r-arrowed " & name;
      pen;
      draw cp;
      drawarrow (littlearrow,
        point apoint of cp,
        angle(direction apoint of cp));
      annotate_at(point apoint of cp if (pair anudge): shifted anudge fi,
                  apos);
    endchar;
    beginchar (byte basechar-hex"60", wsharp, hsharp, dsharp);
      "l-arrowed " & name;
      pen;
      draw cp;
      drawarrow (littlearrow,
        point apoint of cp,
        angle(direction apoint of cp) + 180);
      annotate_at(point apoint of cp if (pair anudge): shifted anudge fi,
                  apos);
    endchar;
enddef;


% Writes on the log file a string consisting of
%     annotate charcode xofs yofs apos
% where charcode is the current character code, and xofs and yofs are the
% positions of the given point, relative to the reference point, in units
% of the font module.   The string apos is one of top, bot, urt, ulft, lrt,
% llft, to indicate where the annotation is to sit, relative to the
% indicated position.
%
% Must be called within beginchar()...endchar;
def annotate_at (expr p, apos) =
  message "annotate " & decimal charcode & " " &
      decimal (xpart p/module) & " " & decimal (ypart p/module) & " "
      & apos & " ";
enddef;

% Draw an arrow.
def drawarrow (expr size, pos, ang) =
  % size : the scale of the arrow
  % pos  : the position of the arrow, relative to the reference point
  % ang  : the direction in which the arrow points
  begingroup
    pair t[];
    y0 = y1 = y4 = 0;
    x1 = -4x4 = -2x2 = size;
    
    x2 = x3 = x0;
    y2 - y0 = y0 - y3 = size/2;

    forsuffixes s = 1,2,3,4 :
      t[s] := z[s] rotated ang shifted pos;
    endfor;
    fill t4--t2--t1--t3--cycle;

  endgroup
enddef;

def garrow (expr code, ang, onaxis) =
  numeric localarrowsize;
%  if onaxis = 1 :
%    localarrowsize := bigarrow;
%  else :
    localarrowsize := littlearrow;
%  fi

  beginchar (code, 0, 0, 0);      "garrow";
    drawarrow (localarrowsize, (0, onaxis*a), ang);
  endchar;
enddef;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Error character.
%
% The parameter ht is the nominal height of the character.
def errorchar (expr ht) =
  begingroup
    numeric rad,npetals,ilowest;
    pair cent;
    cent=(0,2ht/3);		% centre of the flower
    rad=ht/6;			% radius of the inner points
    npetals=5;			% number of petals
    pickup pencircle scaled (thinlinewidth); % thin line
    z0 = cent shifted (rad,0);
    for i=1 upto npetals-1:
      z[i] = z0 rotatedabout (cent, i*360/npetals);
    endfor
    draw z0{dir 0}
    for i=1 upto npetals-1:
      .. tension 0.75 ..{dir (i*360/npetals+180)}z[i]{dir (i*360/npetals)}
    endfor
    ..{dir 180}z0;
    ilowest := 0;
    for i=1 upto npetals-1:
      if y[i] <= y[ilowest]: ilowest := i; fi
    endfor
    draw z[ilowest]{dir (ilowest*360/npetals)}..origin;
    pair leafend;
    xpart(leafend) = 3rad; % want something like currentpicture.rt;
    ypart(leafend) = 2y[ilowest]/3;
    draw origin{dir 60} .. leafend;
    draw leafend .. {dir 180}origin;
  endgroup
enddef;
