% Feta (not the Font-En-Tja) music font -- draw arrow heads
% This file is part of LilyPond, the GNU music typesetter.
%
% Copyright (C) 2005--2022 Han-Wen Nienhuys <hanwen@xs4all.nl>
%
% The LilyPond font is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version, or under the SIL Open Font License.
%
% LilyPond is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.

fet_begingroup ("arrowheads");

%
% To consider: we could put arrow heads at their real Unicode locations.
%

%
% Set up paths for arrow head pointing right.
% CLOSED (boolean): true -> closed arrowhead, false -> open arrowhead
% TENS_O sets the tension for the Outer part of the path
% *_I; inner contour, *_O: outer contour
%


def set_arrow_path (expr width, height, closed, tens_o, arrowlinethickness) =
  save pat, arrow_path;
  save tip_dir_i, tip_dir_o, wing_dir, ta;
  save indent;
  path pat, arrow_path;
  pair tip_dir_i, tip_dir_o, wing_dir;
  numeric ta;

  pickup pencircle scaled arrowlinethickness;

  indent = linethickness / 2;

  x1 = 0;
  y1 = 0;
  lft x2 = -width;
  top y2 = height;
  penpos1 (arrowlinethickness, 90);

  pat := z2
         ..tension tens_o.. z1{right};
  tip_dir_o := direction 0 of pat;
  z4 = z3 = z2;

  penpos2 (arrowlinethickness, angle tip_dir_o + 90);
  penpos3 (arrowlinethickness, angle tip_dir_o + 180);

  if closed:
    y5 = 0;
    x5 = x2 + indent;
    pat := z4
           .. z5{down};
    tip_dir_i := direction 0 of pat;
    wing_dir := down;

    penpos5 (arrowlinethickness, angle wing_dir + 90);
  else:
    pat := z2l{tip_dir_o}
           .. z1l{right};
    ta = xpart (pat intersectiontimes pat yscaled -1);
    z5 = point ta of pat;

    tip_dir_i := tip_dir_o;
    wing_dir := direction ta of pat;

    penpos5 (0, 0);
  fi;

  penpos4 (arrowlinethickness, angle tip_dir_i + 90);

  pat := z1r{left}
         ..tension tens_o.. z2r{-tip_dir_o}
         .. z3r
         .. z4l{tip_dir_i}
         .. z5l{wing_dir};
  arrow_path := pat
                .. reverse pat yscaled -1
                .. cycle;
enddef;


fet_beginchar ("open (right)", "open.01");
  set_char_box (staff_space#, 1.6 linethickness# / 2,
                0.5 staff_space#, 0.5 staff_space#);
  set_arrow_path (staff_space, 0.5 staff_space,
                  false, 1.0, 1.6 linethickness);
  fill arrow_path;
  penlabels (1, 2, 3, 4, 5);
fet_endchar;


fet_beginchar ("open (left)", "open.0M1");
  set_char_box (1.6 linethickness# / 2, staff_space#,
                0.5 staff_space#, 0.5 staff_space#);
  set_arrow_path (staff_space, 0.5 staff_space,
                  false, 1.0, 1.6 linethickness);
  fill arrow_path;
  currentpicture := currentpicture xscaled -1;
fet_endchar;


fet_beginchar ("open (up)", "open.11");
  set_char_box (.5 staff_space#, .5 staff_space#,
                1.0 staff_space#, 1.6 linethickness# / 2);
  set_arrow_path (staff_space, 0.5 staff_space,
                  false, 1.0, 1.6 linethickness);
  fill arrow_path;
  currentpicture := currentpicture rotated 90;
fet_endchar;


fet_beginchar ("open (down)", "open.1M1");
  set_char_box (.5 staff_space#, .5 staff_space#,
                1.6 linethickness# / 2, 1.0 staff_space#);
  set_arrow_path (staff_space, 0.5 staff_space,
                  false, 1.0, 1.6 linethickness);
  fill arrow_path;
  currentpicture := currentpicture rotated 90;
  currentpicture := currentpicture yscaled -1;
fet_endchar;


fet_beginchar ("close (right)", "close.01");
  set_char_box (staff_space#, 0, 0.5 staff_space#, 0.5 staff_space#);
  set_arrow_path (staff_space, 0.5 staff_space,
                  true, 1.5, blot_diameter);
  fill arrow_path;
  penlabels (1, 2, 3, 4, 5);
fet_endchar;


fet_beginchar ("close (left)", "close.0M1");
  set_char_box (0, staff_space#,  0.5 staff_space#, 0.5 staff_space#);
  set_arrow_path (staff_space, 0.5 staff_space,
                  true, 1.5, blot_diameter);
  fill arrow_path;
  currentpicture := currentpicture xscaled -1;
fet_endchar;


fet_beginchar ("close (up)", "close.11");
  set_char_box (.5 staff_space#, .5 staff_space#,
                1.0 staff_space#, 0.0 staff_space#);
  set_arrow_path (staff_space, 0.5 staff_space,
                  true, 1.5, blot_diameter);
  fill arrow_path;
  currentpicture := currentpicture rotated 90;
fet_endchar;


fet_beginchar ("close (down)", "close.1M1");
  set_char_box (.5 staff_space#, .5 staff_space#,
                0.0 staff_space#, 1.0 staff_space#);
  set_arrow_path (staff_space, 0.5 staff_space,
                  true, 1.5, blot_diameter);
  fill arrow_path;
  currentpicture := currentpicture rotated -90;
fet_endchar;

fet_endgroup ("arrowheads");
