X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=mf%2Fparmesan-macros.mf;h=762a178441bbfc8af9fa9163021b377fad1e2d26;hb=HEAD;hp=6fd040c53168d10077b981311a993cea3261a83d;hpb=91396985dc33de5b35785fcdef2145301c0fccc6;p=lilypond.git diff --git a/mf/parmesan-macros.mf b/mf/parmesan-macros.mf index 6fd040c531..762a178441 100644 --- a/mf/parmesan-macros.mf +++ b/mf/parmesan-macros.mf @@ -1,10 +1,21 @@ -% -%-Fundamental-%- -*-Metafont-*- -% parmesan-macros.mf -- macros for parmesan font -% -% source file of LilyPond's pretty-but-neat music font -% -% (c) 2001--2006 Juergen Reuter +% Feta (not the Font-En-Tja) music font -- macros for parmesan font +% This file is part of LilyPond, the GNU music typesetter. +% +% Copyright (C) 2001--2015 Juergen Reuter % +% +% 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 . % @@ -26,7 +37,7 @@ def find_tangent (expr p, curve, p_in, p_out) = mid := 0.5 [in, out]; exitif abs (out - mid) <= eps; t := xpart (curve intersectiontimes (p -- mid)); - if (t > 0): + if t > 0: in := mid; t_good := t; else: @@ -47,7 +58,7 @@ enddef; % def find_tangent_shift (expr line, curve, p_in, p_out) = begingroup; - save mid, t, t_good, in, out; + save mid, t, in, out; pair mid, in, out; in := p_in; @@ -57,9 +68,8 @@ def find_tangent_shift (expr line, curve, p_in, p_out) = mid := 0.5 [in, out]; exitif abs (out - mid) <= eps; t := xpart ((curve shifted mid) intersectiontimes line); - if (t > 0): + if t > 0: in := mid; - t_good := t; else: out := mid; fi; @@ -91,6 +101,15 @@ def get_subpath (expr curve, dir_in, dir_out, offset) = enddef; +% +% Get point specified by `dir_' of `curve' which is then +% shifted by `offset'. +% +def get_subpoint (expr curve, dir_, offset) = + (directionpoint dir_ of curve) shifted offset +enddef; + + % % This is the same as `get_subpath', except that the time values % used to construct the resulting subpath are rounded to integers. @@ -111,4 +130,97 @@ def get_subpath_i (expr curve, dir_in, dir_out, offset) = endgroup enddef; + +% +% Find envelope cusp created by `object' moved along `curve', using +% step value `s' for initial intermediate points. `s' must be small +% enough so that this macro finds at least one point on the envelope +% between the `entrance' and `exit' points of the cusp which has +% a significantly different direction vector. +% +% This function returns a time value on `curve'; if there is no +% cusp, it returns -1. +% +def find_envelope_cusp (expr object, curve, s) = + begingroup; + save mid, p, t, t_good, delta, start, stop, do_exit; + pair p[]; + boolean do_exit; + + p0 := (directionpoint (direction 0 of curve) of object) + shifted (point 0 of curve); + p1 := (directionpoint (direction s of curve) of object) + shifted (point s of curve); + + t := s; + + forever: + t := t + s; + exitif t >= length curve; + + p2 := (directionpoint (direction t of curve) of object) + shifted (point t of curve); + if p2 <> p1: + delta := angle (p2 - p1) - angle (p1 - p0); + if delta > 180: + delta := delta - 360; + fi; + + % we check for a direction change by more than + % than 45 degrees + if abs (delta) >= 45: + do_exit := true; + else: + do_exit := false; + fi; + + p0 := p1; + p1 := p2; + fi; + + % having `exitif' within an if-clause doesn't work + exitif do_exit; + endfor; + + if t >= length curve: + t_good := -1; + else: + % the wanted point lies between `t - s' and `t' + start := t - s; + stop := t; + t_good := start; + + forever: + mid := 0.5 [start, stop]; + exitif abs (stop - mid) <= eps; + + p0 := (directionpoint (direction start of curve) + of object) shifted (point start of curve); + p1 := (directionpoint (direction mid of curve) + of object) shifted (point mid of curve); + p2 := (directionpoint (direction stop of curve) + of object) shifted (point stop of curve); + + exitif (length (p1 - p0) = 0) + or (length (p2 - p1) = 0); + + delta := angle (p2 - p1) - angle (p1 - p0); + if delta > 180: + delta := delta - 360; + fi; + + if abs (delta) >= 45: + stop := mid; + t_good := mid; + else: + start := mid; + t_good := stop; + fi; + endfor; + fi; + + t_good + endgroup +enddef; + % EOF