2 bow.cc -- implement Bow
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "dimension-cache.hh"
13 #include "paper-def.hh"
14 #include "molecule.hh"
16 #include "bezier-bow.hh"
18 #include "directional-element-interface.hh"
22 dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0;
23 dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0;
27 Bow::do_brew_molecule_p () const
29 Real thick = paper_l ()->get_var ("slur_thickness");
30 Bezier one = get_curve ();
33 SCM d = get_elt_property ("dashed");
35 a = lookup_l ()->dashed_slur (one, thick, gh_scm2int (d));
37 a = lookup_l ()->slur (one, directional_element (this).get () * thick, thick);
39 return new Molecule (a);
45 Real dy = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT];
46 Real dx = extent(X_AXIS).length ();
48 return Offset (dx / 2, dy);
53 Bow::curve_extent (Axis a) const
55 return get_curve ().extent (a);
59 Bow::get_curve () const
61 Bezier_bow b (paper_l (),
62 get_encompass_offset_arr (), directional_element (this).get ());
64 return b.get_curve ();
76 This function tries to address two issues:
77 * the tangents of the slur should always point inwards
78 in the actual slur, i.e. *after rotating back*.
80 * slurs shouldn't be too high
81 let's try : h <= 1.2 b && h <= 3 staffheight?
83 We could calculate the tangent of the bezier curve from
84 both ends going inward, and clip the slur at the point
85 where the tangent (after rotation) points up (or inward
86 with a certain maximum angle).
88 However, we assume that real clipping is not the best
89 answer. We expect that moving the outer control point up
90 if the slur becomes too high will result in a nicer slur
93 Knowing that the tangent is the line through the first
94 two control points, we'll clip (move the outer control
95 point upwards) too if the tangent points outwards.
99 Bezier_bow::calc_clipping ()
101 Real clip_height = paper_l_->get_var ("slur_clip_height");
102 Real clip_ratio = paper_l_->get_var ("slur_clip_ratio");
103 Real clip_angle = paper_l_->get_var ("slur_clip_angle");
105 Real b = curve_.control_[3][X_AXIS] - curve_.control_[0][X_AXIS];
106 Real clip_h = clip_ratio * b <? clip_height;
107 Real begin_h = curve_.control_[1][Y_AXIS] - curve_.control_[0][Y_AXIS];
108 Real end_h = curve_.control_[2][Y_AXIS] - curve_.control_[3][Y_AXIS];
109 Real begin_dy = 0 >? begin_h - clip_h;
110 Real end_dy = 0 >? end_h - clip_h;
113 Real begin_alpha = (curve_.control_[1] - curve_.control_[0]).arg () + dir_ * alpha_;
114 Real end_alpha = pi - (curve_.control_[2] - curve_.control_[3]).arg () - dir_ * alpha_;
116 Real max_alpha = clip_angle / 90 * pi / 2;
117 if ((begin_dy < 0) && (end_dy < 0)
118 && (begin_alpha < max_alpha) && (end_alpha < max_alpha))
123 if ((begin_dy > 0) || (end_dy > 0))
125 Real dy = (begin_dy + end_dy) / 4;
127 encompass_[0][Y_AXIS] += dir_ * dy;
128 encompass_.top ()[Y_AXIS] += dir_ * dy;
134 if (begin_alpha >= max_alpha)
135 begin_dy = 0 >? c * begin_alpha / max_alpha * begin_h;
136 if (end_alpha >= max_alpha)
137 end_dy = 0 >? c * end_alpha / max_alpha * end_h;
139 encompass_[0][Y_AXIS] += dir_ * begin_dy;
140 encompass_.top ()[Y_AXIS] += dir_ * end_dy;
142 Offset delta = encompass_.top () - encompass_[0];
143 alpha_ = delta.arg ();
155 Bow::get_encompass_offset_arr () const
157 Array<Offset> offset_arr;
158 offset_arr.push (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT]));
159 offset_arr.push (Offset (spanner_length () + dx_f_drul_[RIGHT],