translate_atom (Offset o, SCM func)
{
return gh_list (ly_symbol2scm ("translate-atom"),
- ly_quote_scm (ly_offset2scm (o)),
+ ly_quote_scm (to_scm (o)),
func,
SCM_UNDEFINED);
}
Offset o ;
o[a] = r;
return gh_list (ly_symbol2scm ("translate-atom"),
- ly_quote_scm (ly_offset2scm (o)),
+ ly_quote_scm (to_scm (o)),
func,
SCM_UNDEFINED);
}
#include "debug.hh"
#include "main.hh"
#include "lily-guile.hh"
-
-void
-flipy (Array<Offset> &c)
-{
- for (int i = c.size (); i--;)
- c[i][Y_AXIS] = - c[i][Y_AXIS];
-}
-
-void
-rotate (Array<Offset> &c, Real phi)
-{
- Offset rot (complex_exp (Offset (0, phi)));
- for (int i = 0; i < c.size (); i++)
- c[i] = complex_multiply (rot, c[i]);
-}
-
-void
-translate (Array<Offset> &c, Offset o)
-{
- for (int i = 0; i < c.size (); i++)
- c[i] += o;
-}
+#include "paper-def.hh"
-Bezier_bow::Bezier_bow (Array<Offset> points, Direction dir)
+Bezier_bow::Bezier_bow (Array<Offset> encompass, Direction dir)
{
+ alpha_ = 0;
dir_ = dir;
- encompass_ = points;
- to_canonic_form ();
-
- rc_factor_ = 1.0;
- height_limit_ = 1.0;
- ratio_ = 1.0;
-}
-
-static Real
-default_height (Real len)
-{
- // assume 20pt staff
- // see fonts.doc
- Real staff_space = 5.0;
- Real h_inf = 2.0* staff_space;
- Real r_0 = 0.33;
- return h_inf * 2.0 / M_PI * atan ( M_PI * r_0 / (2.0 * h_inf) * len);
-}
-
-void
-Bezier_bow::blow_fit ()
-{
- Real len = curve_.control_[3][X_AXIS];
- Real h = curve_.control_[1][Y_AXIS] * fit_factor () / len;
- curve_.control_[1][Y_AXIS] = h * len;
- curve_.control_[2][Y_AXIS] = h * len;
- curve_.check_sanity ();
-}
-
-void
-Bezier_bow::de_uglyfy ()
-{
- Real len = curve_.control_[3][X_AXIS] ;
- Real ff = fit_factor ();
- for (int i = 1; i < 3; i++)
- {
- Real ind = abs (curve_.control_[(i-1)*3][X_AXIS]
- - curve_.control_[i][X_AXIS]) / len;
- Real h = curve_.control_[i][Y_AXIS] * ff / len;
-
- // ugh. Unhardcode this
-#if 0
- // Too crude.
- if (h > 4 * ind)
- {
- h = 4* ind;
- }
-#else
- Real f = default_height (len) / len;
- if (h > 2.0 * f)
- {
- h = 2.0 * f;
- }
-#endif
-
- if (h > 0.8 + -2 * ind)
- {
- h = 0.8 - 2 *ind;
- }
-
- curve_.control_[i][Y_AXIS] = h * len;
- }
-
- curve_.check_sanity ();
-}
-
-Real
-Bezier_bow::calc_enclosed_area_f () const
-{
- Real a = 0;
- for (int i=0; i < encompass_.size (); i++)
- {
- Interval x;
- Interval y;
- if (i == 0)
- {
- x = Interval (0, encompass_[1][X_AXIS] / 2);
- y = Interval (0,
- curve_.get_other_coordinate (X_AXIS,
- encompass_[1][X_AXIS]
- / 2));
- }
- else if (i == encompass_.size () - 1)
- {
- x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS])/2,
- encompass_[i][X_AXIS]);
- y = Interval (0,
- (curve_.get_other_coordinate (X_AXIS,
- (x[MIN] + x[MAX]) / 2)));
- }
- else
- {
- x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS]) / 2,
- (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2);
- y = Interval (encompass_[i][Y_AXIS],
- (curve_.get_other_coordinate (X_AXIS, x[MIN])
- + curve_.get_other_coordinate (X_AXIS,
- (x[MIN] + x[MAX]) / 2)
- + curve_.get_other_coordinate (X_AXIS, x[MAX])) / 3);
- }
-
- Real da = x.length () * y.length ();
- a += da;
- }
- return a;
-}
-
-Array<Offset>
-Bezier_bow::area_gradient_offset_arr ()
-{
- Real len = curve_.control_[3][X_AXIS];
- Real area = calc_enclosed_area_f ();
-
- Real grow = len / 10.0;
- Array<Offset> da (2);
- for (int i=1; i < 3; i++)
- {
- for (Axis a=X_AXIS; a < NO_AXES; incr (a))
- {
- Real r = curve_.control_[i][a];
- curve_.control_[i][a] += grow;
- da[i-1][a] = (calc_enclosed_area_f () - area) / grow;
-
- curve_.control_[i][a] = r;
- }
- }
- return da;
-}
-
-void
-Bezier_bow::minimise_enclosed_area ()
-{
- Real len = curve_.control_[3][X_AXIS];
- Real beautiful = len * default_height (len) / 2.0;
-
- DEBUG_OUT << to_str ("Beautiful: %f\n", beautiful);
- DEBUG_OUT << to_str ("Length: %f\n", len);
- int steps=2;
- for (int i=0; i < steps; i++)
- {
- Real ff = fit_factor ();
- if (!ff)
- break;
-
- DEBUG_OUT << to_str ("FitFac: %f\n", ff);
-
- // slur must be higher at every point
- if (ff > 1.01)
- {
- blow_fit ();
- DEBUG_OUT << to_str ("Blown area: %f\n", calc_enclosed_area_f ());
- }
- else
- DEBUG_OUT << to_str ("Init area: %f\n", calc_enclosed_area_f ());
-
- Real area = calc_enclosed_area_f ();
-
-
- if (area <= beautiful)
- break;
-
- Array<Offset> da = area_gradient_offset_arr ();
-
- /*
- Urg: empiric cs
- Small slurs are easily too asymmetric,
- while big slurs are too symmetric
-
- This makes short slurs strictly x-bound,
- long slurs become y-bound.
- */
- Real ypct = 0.50;
- //Real xpct = (0.07 * len * len / 1000.0) <? 0.80;
- Real xpct = (0.1 * len * len * len / 100000.0) <? 0.80;
-
- Real yu = (abs (curve_.control_[1][Y_AXIS] / da[0][Y_AXIS])
- <? abs (curve_.control_[2][Y_AXIS] / da[1][Y_AXIS]))
- * ypct;
- Real xu = (abs (curve_.control_[1][X_AXIS] / da[0][X_AXIS])
- <? abs ((curve_.control_[3][X_AXIS]
- - curve_.control_[2][X_AXIS]) / da[1][X_AXIS]))
- * xpct;
- Real u = yu <? xu;
- DEBUG_OUT << to_str ("u (xu, yu): %f (%f, %f)\n", u, xu, yu);
- DEBUG_OUT << to_str ("pct (x, y): (%f, %f)\n", xpct, ypct);
-
- DEBUG_OUT << to_str ("da1: (%f, %f)\n", da[0][X_AXIS], da[0][Y_AXIS]);
- DEBUG_OUT << to_str ("da2: (%f, %f)\n", da[1][X_AXIS], da[1][Y_AXIS]);
-
- curve_.control_[1] -= da[0] * u;
- curve_.control_[2] -= da[1] * u;
- }
-
-
- if (fit_factor () > 1.5)
- blow_fit ();
-
- DEBUG_OUT << to_str ("Exarea: %f\n", calc_enclosed_area_f ());
- Real area = calc_enclosed_area_f ();
- /*
- Slurs that fit beautifully are not ugly
- */
- if (area > beautiful)
- {
- DEBUG_OUT << "DE-UGLYFY\n";
- de_uglyfy ();
- }
-
-}
-
-void
-Bezier_bow::calculate ()
-{
- calc_default ();
- if (fit_factor () > 1.0)
- {
- // calc_tangent_controls ();
- // blow_fit ();
- minimise_enclosed_area ();
- }
+ encompass_ = encompass;
+ to_canonical_form ();
}
-
-
Bezier
-Bezier_bow::get_curve ()const
+Bezier_bow::get_bezier () const
{
Bezier rv = curve_;
if (dir_ == DOWN)
return rv;
}
-static Real const FUDGE = 1e-8;
-
-/*
- This function calculates 2 center control points,
- based on lines through c_0 --> left disturbing
- and c_3--> right disturbing encompass points.
-
- See Documentation/fonts.tex
- */
void
-Bezier_bow::calc_tangent_controls ()
-{
- Real b = curve_.control_[3][X_AXIS];
- Real h = curve_.control_[1][Y_AXIS];
-
-
- Drul_array<Offset> disturb;
- Drul_array<Real> maxtan;
- maxtan[LEFT] = maxtan[RIGHT] = h/(b/2);
- disturb[LEFT] = disturb[RIGHT] = Offset (b / 2, h);
-
- for (int i = 1; i < encompass_.size () -1; i++)
- {
- Real y= encompass_[i][Y_AXIS];
- if (y> 0)
- {
- Real x = encompass_[i][X_AXIS];
-
- Direction d = LEFT;
- do
- {
- // 1 if d == LEFT
- int k = (1 - d)/2;
- Real tan = y / ((1-k)* b - d * x);
-
- if (tan > maxtan[d])
- {
- maxtan[d] = tan;
- disturb[d] = Offset (x,y);
- }
- }
- while (flip (&d)!=LEFT);
- }
- }
-
- for (int i = 0; i < encompass_.size (); i++ )
- h = h >? encompass_[i][Y_AXIS];
-
- /*
- The curve will always be under line between curve_.control_0 -> curve_.control_1, so
- make it extra steep by slur_rc_factor
- */
-
-
- Drul_array<Real> angles;
- Direction d = LEFT;
- do
- {
- maxtan[d] *= -d * rc_factor_;
- angles[d] = atan (maxtan[d]);
- }
- while (flip(&d) != LEFT);
-
- Real rc3 = 0.0;
-
- /*
- if we have two disturbing points, have line through those...
- in order to get a sane line, make sure points are reasonably far apart
- X distance must be reasonably(!) big (division)
- */
- if (abs (disturb[LEFT][X_AXIS] - disturb[RIGHT][X_AXIS]) > FUDGE)
- rc3 = (disturb[RIGHT][Y_AXIS] - disturb[LEFT][Y_AXIS]) / (disturb[RIGHT][X_AXIS] - disturb[LEFT][X_AXIS]);
-
- else
- rc3 = tan ((angles[LEFT] - angles[RIGHT]) / 2);
-
-
- // ugh: be less steep
- rc3 /= 2*rc_factor_;
-
-
- Real c2 = -maxtan[RIGHT] * curve_.control_[3][X_AXIS];
-
- // use highest because rc3 is damped.
- Real maxy = disturb[LEFT][Y_AXIS] >? disturb[RIGHT][Y_AXIS];
- Real c3 = disturb[LEFT][Y_AXIS] > disturb[RIGHT][Y_AXIS] ?
- maxy - rc3 * disturb[LEFT][X_AXIS] :
- maxy - rc3 * disturb[RIGHT][X_AXIS];
-
- curve_.control_[1][X_AXIS] = c3 / (maxtan[LEFT] - rc3);
- curve_.control_[1][Y_AXIS] = maxtan[LEFT] * curve_.control_[1][X_AXIS];
-
- curve_.control_[2][X_AXIS] = (c3 - c2) / (maxtan[RIGHT] - rc3);
- curve_.control_[2][Y_AXIS] = maxtan[RIGHT] * curve_.control_[2][X_AXIS] + c2;
-
-
- curve_.check_sanity();
-}
-
-/*
- max ( encompass.y / curve.y )
-
- */
-Real
-Bezier_bow::fit_factor () const
-{
- Real x1 = encompass_[0][X_AXIS];
- Real x2 = encompass_.top ()[X_AXIS];
-
- Real factor = 0.0;
- for (int i=1; i < encompass_.size ()-1; i++)
- {
- if (encompass_[i][X_AXIS] > x1 && encompass_[i][X_AXIS] < x2)
- {
- Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]);
- if (y>0)
- {
- Real f = encompass_[i][Y_AXIS] / y;
- factor = factor >? f;
- }
- }
- }
-
-
- return factor;
-}
-
-
-
-
-void
-Bezier_bow::to_canonic_form ()
+Bezier_bow::to_canonical_form ()
{
origin_ = encompass_[0];
- translate (encompass_,-origin_);
+ translate (&encompass_, -origin_);
Offset delta = encompass_.top () - encompass_[0];
alpha_ = delta.arg ();
- rotate (encompass_, -alpha_);
+ rotate (&encompass_, -alpha_);
if (dir_ == DOWN)
{
- flipy (encompass_);
+ flip (&encompass_, Y_AXIS);
}
while (encompass_.size () > 1 && encompass_[1][X_AXIS] <= 0.0)
{
- programming_error ("Degenerate slur: infinite steepness reqd");
+ programming_error ("Degenerate bow: infinite steepness reqd");
encompass_.del (1);
}
Real l = encompass_.top ()[X_AXIS];
while (encompass_.size () > 1 && encompass_.top (1)[X_AXIS] >= l)
{
- programming_error ("Degenerate slur: infinite steepness reqd");
+ programming_error ("Degenerate bow: infinite steepness reqd");
encompass_.del (encompass_.size ()-2);
}
}
-
+void
+Bezier_bow::set_default_bezier (Real h_inf, Real r_0)
+{
+ curve_ = get_default_bezier (h_inf, r_0);
+}
/*
- See Documentation/fonts.tex
+ See Documentation/programmer/fonts.doc
*/
-void
-Bezier_bow::calc_default ()
+Bezier
+Bezier_bow::get_default_bezier (Real h_inf, Real r_0) const
{
- Real pi = M_PI;
-
- Real alpha = height_limit_ * 2.0 / pi;
- Real beta = pi * ratio_ / (2.0 * height_limit_);
-
- Offset delta (encompass_.top ()[X_AXIS]
- - encompass_[0][X_AXIS], 0);
-
+ Offset delta (encompass_.top ()[X_AXIS] - encompass_[0][X_AXIS], 0);
Real b = delta.length ();
- Real indent = alpha * atan (beta * b);
- Real height = indent;
-
- curve_.control_ [0] = Offset (0, 0);
- curve_.control_ [1] = Offset (indent, height);
- curve_.control_ [2] = Offset (b - indent, height);
- curve_.control_ [3] = Offset (b, 0);
-}
+ Real height = get_default_height (h_inf, r_0, b);
+ // urg: scmify this?
+ Real indent = height;
+ Bezier curve;
+ curve.control_[0] = Offset (0, 0);
+ curve.control_[1] = Offset (indent, height);
+ curve.control_[2] = Offset (b - indent, height);
+ curve.control_[3] = Offset (b, 0);
+ return curve;
+}
+/*
+ See Documentation/programmer/fonts.doc
+ */
+Real
+Bezier_bow::get_default_height (Real h_inf, Real r_0, Real b) const
+{
+#if 0
+ Real pi = M_PI;
+ Real alpha = 2.0 * h_inf / pi;
+ Real beta = pi * r_0 / (2.0 * h_inf);
+ return alpha * atan (beta * b);
+#else
+ SCM h = scm_eval (scm_listify (ly_symbol2scm ("slur-default-height"),
+ gh_double2scm (h_inf),
+ gh_double2scm (r_0),
+ gh_double2scm (b),
+ SCM_UNDEFINED));
+ return gh_scm2double (h);
+#endif
+}
+
#include "bezier.hh"
#include "polynomial.hh"
+Real
+binomial_coefficient (Real over , int under)
+{
+ Real x = 1.0;
+
+ while (under)
+ {
+ x *= over / Real (under);
+
+ over -= 1.0;
+ under --;
+ }
+ return x;
+}
+
+void
+flip (Array<Offset>* arr_p, Axis a)
+{
+ // huh?
+ // for (int i = c.size (); i--;)
+ for (int i = 0; i < arr_p->size (); i++)
+ (*arr_p)[i][a] = - (*arr_p)[i][a];
+}
+
+void
+rotate (Array<Offset>* arr_p, Real phi)
+{
+ Offset rot (complex_exp (Offset (0, phi)));
+ for (int i = 0; i < arr_p->size (); i++)
+ (*arr_p)[i] = complex_multiply (rot, (*arr_p)[i]);
+}
+
+void
+translate (Array<Offset>* arr_p, Offset o)
+{
+ for (int i = 0; i < arr_p->size (); i++)
+ (*arr_p)[i] += o;
+}
+
/*
Formula of the bezier 3-spline
*/
Bezier::Bezier ()
+ : control_ (CONTROL_COUNT)
{
}
return c[other];
}
-Real
-binomial_coefficient (Real over , int under)
-{
- Real x = 1.0;
-
- while (under)
- {
- x *= over / Real (under);
-
- over -= 1.0;
- under --;
- }
- return x;
-}
Offset
Bezier::curve_point (Real t)const
void
Bezier::flip (Axis a)
{
- for (int i = CONTROL_COUNT; i--;)
- control_[i][a] = - control_[i][a];
+ ::flip (&control_, a);
}
void
Bezier::rotate (Real phi)
{
- Offset rot (complex_exp (Offset (0, phi)));
- for (int i = 0; i < CONTROL_COUNT; i++)
- control_[i] = complex_multiply (rot, control_[i]);
+ ::rotate (&control_, phi);
}
void
Bezier::translate (Offset o)
{
- for (int i = 0; i < CONTROL_COUNT; i++)
- control_[i] += o;
+ ::translate (&control_, o);
}
void
-Bezier::check_sanity () const
+Bezier::assert_sanity () const
{
for (int i=0; i < CONTROL_COUNT; i++)
assert (!isnan (control_[i].length ())
from bow paratime_signatures. */
class Bezier_bow
{
- Bezier curve_;
- Array<Offset> encompass_;
-
- void blow_fit ();
- void de_uglyfy ();
- void calc_default ();
- void to_canonic_form ();
- void calc_tangent_controls ();
- Real calc_enclosed_area_f () const;
- void minimise_enclosed_area ();
- Array<Offset> area_gradient_offset_arr ();
+public:
+ Bezier_bow (Array<Offset> encompass, Direction dir);
- Real fit_factor () const;
+ Bezier get_bezier () const;
+ Bezier get_default_bezier (Real h_inf, Real r_0) const;
+ Real get_default_height (Real h_inf, Real r_0, Real length) const;
+ void set_default_bezier (Real h_inf, Real r_0);
+ /**
+ The canonical bezier.
+ */
+ Bezier curve_;
- Paper_def* paper_l_;
+protected:
+ Array<Offset> encompass_;
+
+private:
+ void to_canonical_form ();
Direction dir_;
Real alpha_;
Offset origin_;
-public:
- Real rc_factor_;
- Real height_limit_;
- Real ratio_;
-
-
- Real vertical_offset_needed () const;
-
- Bezier_bow (Array<Offset> points, Direction dir);
- void calculate ();
- Bezier get_curve () const;
};
public:
Bezier ();
+ void assert_sanity () const;
+ void flip (Axis);
+ void reverse ();
void rotate (Real);
void translate (Offset);
- void flip (Axis);
- void check_sanity () const;
+
Real get_other_coordinate (Axis a, Real x) const;
Array<Real> solve_point (Axis, Real coordinate) const;
Array<Real> solve_derivative (Offset) const;
Polynomial polynomial (Axis)const;
Offset curve_point (Real t) const;
- void reverse ();
-
static const int CONTROL_COUNT = 4;
- Offset control_[CONTROL_COUNT];
+ Array<Offset> control_;
};
+void flip (Array<Offset>* arr_p, Axis a);
+void rotate (Array<Offset>* arr_p, Real phi);
+void translate (Array<Offset>* arr_p, Offset o);
#endif // BEZIER_HH
SCM ly_symbol2scm (char const *);
String ly_symbol2string (SCM);
-SCM ly_offset2scm (Offset o);
-Offset ly_scm2offset (SCM s);
SCM ly_eval (SCM a);
SCM ly_parse_scm (char const* s, int* n);
SCM ly_quote_scm (SCM s);
SCM to_scm (Real r);
Real scm_to (SCM s, Real* r);
+SCM to_scm (Offset o);
+Offset scm_to (SCM s, Offset* o);
+
/*
snarfing.
*/
*/
class Slur : public Spanner
{
- int cross_staff_count () const;
- Offset encompass_offset (Note_column const* )const;
public:
Slur ();
VIRTUAL_COPY_CONS(Score_element);
protected:
- virtual Molecule* do_brew_molecule_p () const;
+ virtual Molecule do_brew_molecule () const;
virtual Array<Offset> get_encompass_offset_arr () const;
Bezier get_curve () const;
Drul_array<Real> dy_f_drul_;
virtual void do_post_processing ();
virtual void do_add_processing ();
Array<Rod> get_rods () const;
+
+private:
+ void de_uglyfy (class Slur_bezier_bow* bb, Real default_height);
+ void set_extremities ();
+ void set_control_points ();
+ int cross_staff_count () const;
+ Offset encompass_offset (Note_column const* )const;
};
#endif // SLUR_HH
SCM
-ly_offset2scm (Offset o)
+to_scm (Offset o)
{
return gh_cons (gh_double2scm (o[X_AXIS]), gh_double2scm(o[Y_AXIS]));
}
Offset
-ly_scm2offset (SCM s)
+scm_to (SCM s, Offset*)
{
return Offset (gh_scm2double (gh_car (s)),
gh_scm2double (gh_cdr (s)));
}
}
AFM_CharMetricInfo const *cm = afm_l_->find_char_metric (s, warn);
- Molecule m;
+
if (!cm)
{
+ Molecule m;
m.set_empty (false);
return m;
}
SCM_UNDEFINED));
at= fontify_atom (afm_l_,at);
- m.dim_ = afm_bbox_to_box (cm->charBBox);
- m.add_atom (at);
- return m;
+ return Molecule ( afm_bbox_to_box (cm->charBBox), at);
}
Molecule
Real max_y = (0 >? height) + thick/2;
- Molecule m;
- m.dim_[X_AXIS] = Interval (0, width);
- m.dim_[Y_AXIS] = Interval (min_y, max_y);
-
- SCM at = (gh_list (ly_symbol2scm ("beam"),
- gh_double2scm (width),
- gh_double2scm (slope),
- gh_double2scm (thick),
- SCM_UNDEFINED));
+ Box b( Interval (0, width),
+ Interval (min_y, max_y));
- m.add_atom (at);
- return m;
+
+ SCM at = gh_list (ly_symbol2scm ("beam"),
+ gh_double2scm (width),
+ gh_double2scm (slope),
+ gh_double2scm (thick),
+ SCM_UNDEFINED);
+ return Molecule (b, at);
}
Lookup::dashed_slur (Bezier b, Real thick, Real dash)
{
SCM l = SCM_EOL;
+ // this is silly, we have array_to_scm
for (int i= 4; i -- ;)
{
- l = gh_cons (ly_offset2scm (b.control_[i]), l);
+ l = gh_cons (to_scm (b.control_[i]), l);
}
SCM at = (gh_list (ly_symbol2scm ("dashed-slur"),
gh_double2scm (dash),
ly_quote_scm (l),
SCM_UNDEFINED));
- Molecule m;
- m.add_atom (at);
- return m;
+
+ Box box (Interval(0,0),Interval( 0,0));
+ return Molecule (box, at);
}
Molecule
Lookup::filledbox (Box b )
{
- Molecule m;
-
SCM at = (gh_list (ly_symbol2scm ("filledbox"),
gh_double2scm (-b[X_AXIS][LEFT]),
gh_double2scm (b[X_AXIS][RIGHT]),
gh_double2scm (b[Y_AXIS][UP]),
SCM_UNDEFINED));
- m.dim_ = b;
- m.add_atom (at);
- return m;
+ return Molecule ( b,at);
}
Molecule
Molecule
Lookup::text (String style, String text, Paper_def *paper_l)
{
- Molecule m;
if (style.empty_b ())
style = "roman";
else if (output_global_ch == "ps")
text = sanitise_PS_string (text);
- m.dim_ = metric_l->text_dimension (text);
+
SCM at = (gh_list (ly_symbol2scm ("text"),
ly_str02scm (text.ch_C()),
SCM_UNDEFINED));
at = fontify_atom (metric_l,at);
-
- m.add_atom (at);
- return m;
+ return Molecule ( metric_l->text_dimension (text),
+ at);
}
Molecule
Lookup::staff_brace (Real y, int staff_size)
{
- Molecule m;
-
// URG
Real step = 1.0;
int minht = 2 * staff_size;
at = fontify_atom (all_fonts_global_p->find_font (nm), at);
- m.dim_[Y_AXIS] = Interval (-y/2,y/2);
- m.dim_[X_AXIS] = Interval (0,0);
- m.add_atom (at);
- return m;
+ Box b ( Interval (-y/2,y/2),
+ Interval (0,0));
+ return Molecule(b, at);
}
back.control_[2] += curvethick * complex_exp (Offset (0, alpha + M_PI/2));
SCM scontrols[8];
+ // this is silly, we have array_to_scm
for (int i=4; i--;)
- scontrols[ i ] = ly_offset2scm (back.control_[i]);
+ scontrols[ i ] = to_scm (back.control_[i]);
for (int i=4 ; i--;)
- scontrols[i+4] = ly_offset2scm (curve.control_[i]);
+ scontrols[i+4] = to_scm (curve.control_[i]);
/*
Need the weird order b.o. the way PS want its arguments
gh_double2scm (linethick),
SCM_UNDEFINED));
- Molecule m;
- m.dim_[X_AXIS] = curve.extent (X_AXIS);
- m.dim_[Y_AXIS] = curve.extent (Y_AXIS);
- m.add_atom (at);
- return m;
+ Box b ( curve.extent (X_AXIS), curve.extent (Y_AXIS));
+ return Molecule (b, at);
}
Molecule
Lookup::staff_bracket (Real height, Paper_def* paper_l)
{
- Molecule m;
SCM at = ( gh_list (ly_symbol2scm ("bracket"),
gh_double2scm (paper_l->get_var("bracket_arch_angle")),
gh_double2scm (paper_l->get_var("bracket_arch_width")),
gh_double2scm (paper_l->get_var("bracket_arch_thick")),
gh_double2scm (paper_l->get_var("bracket_thick")),
SCM_UNDEFINED));
-
- m.add_atom (at);
- m.dim_[Y_AXIS] = Interval (-height/2,height/2);
- m.dim_[X_AXIS] = Interval (0,4 PT);
+
+ Box b ( Interval (-height/2,height/2), Interval (0,4 PT));
+ Molecule m (b, at);
m.translate_axis (- 4. / 3. * m.dim_[X_AXIS].length (), X_AXIS);
return m;
ugh. Rewrite not finished yet. Still must copy atom lists.
*/
+
#include <math.h>
+#include "dimensions.hh"
#include "interval.hh"
#include "string.hh"
#include "molecule.hh"
return dim_[a];
}
+Molecule::Molecule (Box b, SCM func)
+{
+ expr_ = func;
+ dim_ = b ;
+}
+
+Molecule::Molecule()
+{
+ expr_ = SCM_EOL;
+ set_empty (true);
+}
+
void
Molecule::translate (Offset o)
{
- if (isinf (o.length ()))
- {
- programming_error ("Translating infinitely. Ignore.");
- return;
- }
-
- for (SCM ptr = gh_cdr (atom_list_); ptr != SCM_EOL; ptr = gh_cdr(ptr))
+ Axis a = X_AXIS;
+ while (a < NO_AXES)
{
- gh_set_car_x (ptr, translate_atom (o, gh_car (ptr)));
+ if (abs(o[a]) > 30 CM
+ || isinf (o[a]) || isnan (o[a]))
+ {
+ programming_error ("Improbable offset for translation: setting to zero");
+ o[a] = 0.0;
+ }
+ incr (a);
}
+
+ expr_ = gh_list (ly_symbol2scm ("translate-molecule"),
+ to_scm (o),
+ expr_, SCM_UNDEFINED);
if (!empty_b ())
dim_.translate (o);
}
+
void
Molecule::translate_axis (Real x,Axis a)
{
- if (isinf (x))
- {
- programming_error ("Translating infinitely. Ignore.");
- return;
- }
- for (SCM ptr = gh_cdr (atom_list_); ptr != SCM_EOL; ptr = gh_cdr(ptr))
- {
- gh_set_car_x (ptr, translate_atom_axis (x, a, gh_car (ptr)));
- }
+ Offset o(0,0);
+ o[a] = x;
+ translate (o);
+}
+
- if (!dim_[a].empty_b ())
- dim_[a] += x;
-}
void
Molecule::add_molecule (Molecule const &m)
{
- for (SCM ptr = gh_cdr (m.atom_list_); ptr != SCM_EOL; ptr = gh_cdr(ptr))
- {
- add_atom (gh_car (ptr));
- }
+ expr_ = gh_list (ly_symbol2scm ("combine-molecule"),
+ m.expr_,
+ expr_, SCM_UNDEFINED);
dim_.unite (m.dim_);
}
-void
-Molecule::add_atom (SCM atomsmob)
-{
- gh_set_cdr_x (atom_list_,
- gh_cons (atomsmob, gh_cdr (atom_list_)));
-}
-
-void
-Molecule::operator=(Molecule const & src)
-{
- if (&src == this)
- return;
-
- atom_list_ = gh_cons (SCM_EOL,scm_list_copy (gh_cdr (src.atom_list_)));
- dim_= src.dim_;
-}
-
void
Molecule::set_empty (bool e)
{
Molecule::print () const
{
#ifndef NPRINT
- for (SCM ptr = gh_cdr (atom_list_); ptr != SCM_EOL; ptr = gh_cdr(ptr))
- gh_display (gh_car (ptr));
+ gh_display (expr_);
#endif
}
-Molecule::Molecule (Molecule const &s)
-{
- atom_list_ = gh_cons (SCM_EOL, scm_list_copy (gh_cdr (s.atom_list_)));
- dim_ = s.dim_;
-}
-
-Molecule::~Molecule ()
-{
-}
-
-
void
Molecule::align_to (Axis a, Direction d)
{
- if (d == CENTER)
- {
- Interval i (extent (a));
- translate_axis (-i.center (), a);
- }
- else
- {
- translate_axis (-extent (a)[d], a);
- }
-}
-
-Molecule::Molecule ()
-{
- dim_[X_AXIS].set_empty ();
- dim_[Y_AXIS].set_empty ();
- atom_list_ = gh_cons (SCM_EOL, SCM_EOL);
+ Interval i (extent (a));
+ Real r = (d == CENTER) ? i.center () : i[d];
+ translate_axis (-r, a);
}
bool
Molecule::empty_b () const
{
- return gh_cdr (atom_list_) == SCM_EOL;
+ return expr_ == SCM_EOL;
}
}
void
-Paper_outputter::output_molecule (Molecule const*m, Offset o, char const *nm)
+Paper_outputter::output_molecule (SCM expr, Offset o, char const *nm)
{
+#if 0
if (flower_dstream)
{
output_comment (nm);
}
+#endif
+
+ SCM offset_sym = ly_symbol2scm ("translate-molecule");
+ SCM combine_sym = ly_symbol2scm ("combine-molecule");
+enter:
- SCM offset_sym = ly_symbol2scm ("translate-atom");
- for (SCM ptr = gh_cdr (m->atom_list_); ptr != SCM_EOL; ptr = gh_cdr (ptr))
+ if (!gh_pair_p (expr))
+ return;
+
+ SCM head =gh_car (expr);
+ if (head == offset_sym)
{
- SCM func = gh_car (ptr);
- SCM funcptr = func;
-
- Offset a_off (0,0);
- while (gh_pair_p (funcptr))
- {
- if (gh_car (funcptr) == offset_sym)
- {
- SCM quot = gh_cadr (funcptr);
- a_off += ly_scm2offset (gh_cadr (quot));
- }
- funcptr = scm_last_pair (funcptr);
- if (funcptr != SCM_EOL )
- {
- funcptr = gh_car (funcptr);
- }
- }
-
- a_off += o;
-
- Axis a = X_AXIS;
- while (a < NO_AXES)
- {
- if (abs(a_off[a]) > 30 CM
- || isinf (a_off[a]) || isnan (a_off[a]))
- {
- programming_error ("Improbable offset for object: setting to zero");
- a_off[a] = 0.0;
- }
- incr (a);
- }
-
-
- SCM box_scm
- = gh_list (ly_symbol2scm ("placebox"),
- gh_double2scm (a_off[X_AXIS]),
- gh_double2scm (a_off[Y_AXIS]),
- func,
- SCM_UNDEFINED);
+ o += scm_to (gh_cadr (expr), &o);
+ expr = gh_caddr (expr);
+ goto enter;
+ }
+ else if (head == combine_sym)
+ {
+ output_molecule (gh_cadr (expr), o, nm);
+ expr = gh_caddr (expr);
+ goto enter; // tail recursion
+ }
+ else
+ {
+ output_scheme (gh_list (ly_symbol2scm ("placebox"),
+ gh_double2scm (o[X_AXIS]),
+ gh_double2scm (o[Y_AXIS]),
+ expr,
+ SCM_UNDEFINED));
- output_scheme (box_scm);
}
}
#include "molecule.hh"
#include "debug.hh"
#include "box.hh"
-#include "bezier.hh"
#include "bezier-bow.hh"
#include "main.hh"
#include "cross-staff.hh"
#include "group-interface.hh"
+#include "staff-symbol-referencer.hh"
+#include "lily-guile.icc"
+
+
+class Slur_bezier_bow : public Bezier_bow
+{
+public:
+ Slur_bezier_bow (Array<Offset> encompass, Direction dir);
+ Array<Real> area_x_gradients_array (Real area);
+ void blow_fit ();
+ Real enclosed_area_f () const;
+ Real fit_factor () const;
+ void minimise_enclosed_area (Paper_def* paper_l, Real default_height);
+};
+
+Slur_bezier_bow::Slur_bezier_bow (Array<Offset> encompass, Direction dir)
+ : Bezier_bow (encompass, dir)
+{
+}
+
+void
+Slur_bezier_bow::blow_fit ()
+{
+ Real len = curve_.control_[3][X_AXIS];
+ Real h = curve_.control_[1][Y_AXIS] * fit_factor () / len;
+ curve_.control_[1][Y_AXIS] = h * len;
+ curve_.control_[2][Y_AXIS] = h * len;
+ curve_.assert_sanity ();
+}
+
+
+Real
+Slur_bezier_bow::enclosed_area_f () const
+{
+ Real a = 0;
+ for (int i=0; i < encompass_.size (); i++)
+ {
+ Interval x;
+ Interval y;
+ if (i == 0)
+ {
+ x = Interval (0, encompass_[1][X_AXIS] / 2);
+ y = Interval (0,
+ curve_.get_other_coordinate (X_AXIS,
+ encompass_[1][X_AXIS]
+ / 2));
+ }
+ else if (i == encompass_.size () - 1)
+ {
+ x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS])/2,
+ encompass_[i][X_AXIS]);
+ y = Interval (0,
+ (curve_.get_other_coordinate (X_AXIS,
+ (x[MIN] + x[MAX]) / 2)));
+ }
+ else
+ {
+ x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS]) / 2,
+ (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2);
+ y = Interval (encompass_[i][Y_AXIS],
+ (curve_.get_other_coordinate (X_AXIS, x[MIN])
+ + curve_.get_other_coordinate (X_AXIS,
+ (x[MIN] + x[MAX]) / 2)
+ + curve_.get_other_coordinate (X_AXIS, x[MAX])) / 3);
+ }
+
+ Real da = x.length () * y.length ();
+ a += da;
+ }
+ return a;
+}
+
+Array<Real>
+Slur_bezier_bow::area_x_gradients_array (Real area)
+{
+ Real len = curve_.control_[3][X_AXIS];
+ Real grow = len / 10.0;
+ Array<Real> da (2);
+ for (int i=0; i < 2; i++)
+ {
+ Real r = curve_.control_[i+1][X_AXIS];
+ curve_.control_[i+1][X_AXIS] += grow;
+ da[i] = (enclosed_area_f () - area) / grow;
+ curve_.control_[i+1][X_AXIS] = r;
+ }
+ return da;
+}
+
+void
+Slur_bezier_bow::minimise_enclosed_area (Paper_def* paper_l,
+ Real default_height)
+{
+ Real length = curve_.control_[3][X_AXIS];
+ Real bbc = paper_l->get_var ("bezier_beautiful");
+ Real beautiful = length * default_height / bbc;
+
+ DEBUG_OUT << to_str ("Beautiful: %f\n", beautiful);
+ DEBUG_OUT << to_str ("Length: %f\n", length);
+ DEBUG_OUT << to_str ("D-height: %f\n", default_height);
+ DEBUG_OUT << to_str ("FitFac: %f\n", fit_factor ());
+
+ if (fit_factor () > 1.0)
+ blow_fit ();
+
+ Real pct_c0 = paper_l->get_var ("bezier_pct_c0");
+ Real pct_c3 = paper_l->get_var ("bezier_pct_c3");
+ Real pct_in_max = paper_l->get_var ("bezier_pct_in_max");
+ Real pct_out_max = paper_l->get_var ("bezier_pct_out_max");
+ Real steps = paper_l->get_var ("bezier_area_steps");
+
+ for (int i=0; i < steps; i++)
+ {
+ Real area = enclosed_area_f ();
+ if (!i)
+ DEBUG_OUT << to_str ("Init area: %f\n", area);
+
+ if (area <= beautiful)
+ break;
+
+ Array<Real> da = area_x_gradients_array (area);
+
+ // urg
+ Real pct = pct_c0 + pct_c3 * length * length * length;
+ pct *= (steps - i) / steps;
+ if (da[0] > 0 || da[1] < 0)
+ pct = pct <? pct_out_max;
+ else
+ pct = pct <? pct_in_max;
+
+ Real u = (abs (curve_.control_[1][X_AXIS] / da[0])
+ <? abs ((curve_.control_[3][X_AXIS]
+ - curve_.control_[2][X_AXIS]) / da[1]));
+
+ DEBUG_OUT << to_str ("pct: %f\n", pct);
+ DEBUG_OUT << to_str ("u: %f\n", u);
+
+ DEBUG_OUT << to_str ("da: (%f, %f)\n", da[0], da[1]);
+ DEBUG_OUT << to_str ("da*u: (%f, %f)\n", da[0]*u*pct, da[1]*u*pct);
+ DEBUG_OUT << to_str ("cx: (%f, %f)\n", curve_.control_[1][X_AXIS],
+ curve_.control_[2][X_AXIS]);
+
+ curve_.control_[1][X_AXIS] -= da[0] * u * pct;
+ curve_.control_[2][X_AXIS] -= da[1] * u * pct;
+ }
+
+ Real area = enclosed_area_f ();
+ DEBUG_OUT << to_str ("Exarea: %f\n", area);
+}
+
+
+
+/*
+ max ( encompass.y / curve.y )
+
+ */
+Real
+Slur_bezier_bow::fit_factor () const
+{
+ Real x1 = encompass_[0][X_AXIS];
+ Real x2 = encompass_.top ()[X_AXIS];
+
+ Real factor = 0.0;
+ for (int i=1; i < encompass_.size ()-1; i++)
+ {
+ if (encompass_[i][X_AXIS] > x1 && encompass_[i][X_AXIS] < x2)
+ {
+ Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]);
+ if (y>0)
+ {
+ Real f = encompass_[i][Y_AXIS] / y;
+ factor = factor >? f;
+ }
+ }
+ }
+
+
+ return factor;
+}
+
+
+
+
+
+/*
+ Slur
+*/
Slur::Slur ()
{
+ // URG
dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0;
dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0;
+
set_elt_property ("note-columns", SCM_EOL);
+ set_elt_property ("control-points", SCM_EOL);
+
+#if 0
+ /*
+ I still don't understand the merits of this Group_interface.
+ */
+ Group_interface c (this, "control-points");
+ c.set_interface ();
+#endif
}
void
}
}
+void
+Slur::de_uglyfy (Slur_bezier_bow* bb, Real default_height)
+{
+ Real length = bb->curve_.control_[3][X_AXIS] ;
+ Real ff = bb->fit_factor ();
+ for (int i = 1; i < 3; i++)
+ {
+ Real ind = abs (bb->curve_.control_[(i-1)*3][X_AXIS]
+ - bb->curve_.control_[i][X_AXIS]) / length;
+ Real h = bb->curve_.control_[i][Y_AXIS] * ff / length;
+
+ Real f = default_height / length;
+ Real c1 = paper_l ()->get_var ("bezier_control1");
+ Real c2 = paper_l ()->get_var ("bezier_control2");
+ Real c3 = paper_l ()->get_var ("bezier_control3");
+ if (h > c1 * f)
+ {
+ h = c1 * f;
+ }
+ else if (h > c2 + c3 * ind)
+ {
+ h = c2 + c3 * ind;
+ }
+
+ bb->curve_.control_[i][Y_AXIS] = h * length;
+ }
+
+ bb->curve_.assert_sanity ();
+}
+
Direction
Slur::get_default_dir () const
{
if (!stem_l)
{
warning (_ ("Slur over rest?"));
- o[X_AXIS] = col->hpos_f ();
+ o[X_AXIS] = col->hpos_f ();
o[Y_AXIS] = col->extent (Y_AXIS)[dir];
return o;
}
return o;
}
-/*
- ARGRARGRARGRARGAR!
+void
+Slur::do_post_processing ()
+{
+ set_extremities ();
+ set_control_points ();
+}
- Fixme
+/*
+ urg
+ FIXME
*/
void
-Slur::do_post_processing ()
+Slur::set_extremities ()
{
Link_array<Note_column> encompass_arr =
Group_interface__extract_elements (this, (Note_column*)0, "note-columns");
if (!fix_broken_b)
dy_f_drul_[RIGHT] += interstaff_f;
-
-
-
- return;
-
- /*
- Now we've got a fine slur
- Catch and correct some ugly cases
- */
- String infix = interstaff_b ? "interstaff_" : "";
- Real height_damp_f = paper_l ()->get_var ("slur_"+infix +"height_damping");
- Real slope_damp_f = paper_l ()->get_var ("slur_"+infix +"slope_damping");
- Real snap_f = paper_l ()->get_var ("slur_"+infix +"snap_to_stem");
- Real snap_max_dy_f = paper_l ()->get_var ("slur_"+infix +"snap_max_slope_change");
-
- Real dx_f = spanner_length ()+ dx_f_drul_[RIGHT] - dx_f_drul_[LEFT];
- Real dy_f = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT];
- if (!fix_broken_b)
- dy_f -= interstaff_f;
-
- /*
- Avoid too steep slurs.
- */
- Real slope_ratio_f = abs (dy_f / dx_f);
- if (slope_ratio_f > slope_damp_f)
- {
- Direction d = (Direction)(- my_dir * (sign (dy_f)));
- if (!d)
- d = LEFT;
- Real damp_f = (slope_ratio_f - slope_damp_f) * dx_f;
- /*
- must never change sign of dy
- */
- damp_f = damp_f <? abs (dy_f);
- dy_f_drul_[d] += my_dir * damp_f;
- }
-
- /*
- Avoid too high slurs
-
- Wierd slurs may look a lot better after they have been
- adjusted a bit.
- So, we'll do this in 3 steps
- */
- for (int i = 0; i < 3; i++)
- {
- Bezier c (get_curve ());
-
- Offset size (c.extent (X_AXIS).length (),
- c.extent (Y_AXIS).length ());
-
- dy_f = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT];
- if (!fix_broken_b)
- dy_f -= interstaff_f;
-
- Real height_ratio_f = abs (size[Y_AXIS] / size[X_AXIS]);
- if (height_ratio_f > height_damp_f)
- {
- Direction d = (Direction)(- my_dir * (sign (dy_f)));
- if (!d)
- d = LEFT;
- /* take third step */
- Real damp_f = (height_ratio_f - height_damp_f) * size[X_AXIS] / 3;
- /*
- if y positions at about the same height, correct both ends
- */
- if (abs (dy_f / dx_f ) < slope_damp_f)
- {
- dy_f_drul_[-d] += my_dir * damp_f;
- dy_f_drul_[d] += my_dir * damp_f;
- }
- /*
- don't change slope too much, would have been catched by slope damping
- */
- else
- {
- damp_f = damp_f <? abs (dy_f/2);
- dy_f_drul_[d] += my_dir * damp_f;
- }
- }
- }
-
- /*
- If, after correcting, we're close to stem-end...
- */
- Drul_array<Real> snapy_f_drul;
- snapy_f_drul[LEFT] = snapy_f_drul[RIGHT] = 0;
- Drul_array<Real> snapx_f_drul;
- snapx_f_drul[LEFT] = snapx_f_drul[RIGHT] = 0;
- Drul_array<bool> snapped_b_drul;
- snapped_b_drul[LEFT] = snapped_b_drul[RIGHT] = false;
- do
- {
- Note_column * nc = note_column_drul[d];
- if (nc == spanned_drul_[d]
- && nc->stem_l ()
- && nc->stem_l ()->get_direction () == my_dir
- && abs (nc->stem_l ()->extent (Y_AXIS)[my_dir]
- - dy_f_drul_[d] + (d == LEFT ? 0 : interstaff_f))
- <= snap_f)
- {
- /*
- prepare to attach to stem-end
- */
- snapx_f_drul[d] = nc->stem_l ()->hpos_f ()
- - spanned_drul_[d]->relative_coordinate (0, X_AXIS);
-
- snapy_f_drul[d] = nc->stem_l ()->extent (Y_AXIS)[my_dir]
- + interstaff_interval[d]
- + my_dir * 2 * y_gap_f;
-
- snapped_b_drul[d] = true;
- }
- }
- while (flip (&d) != LEFT);
-
- /*
- only use snapped positions if sign (dy) will not change
- and dy doesn't change too much
- */
- if (!fix_broken_b)
- dy_f += interstaff_f;
-
-
- /*
- (sigh)
-
- More refactoring could be done.
- */
- Real maxsnap = abs (dy_f * snap_max_dy_f);
- if (snapped_b_drul[LEFT] && snapped_b_drul[RIGHT]
- && ((sign (snapy_f_drul[RIGHT] - snapy_f_drul[LEFT]) == sign (dy_f)))
- && (!dy_f || (abs (snapy_f_drul[RIGHT] - snapy_f_drul[LEFT] - dy_f)
- < maxsnap)))
- {
- dy_f_drul_ = snapy_f_drul;
- dx_f_drul_ = snapx_f_drul;
- }
- else
- do
- {
- Direction od = (Direction)-d;
- if (snapped_b_drul[d]
- && d * sign (snapy_f_drul[d] - dy_f_drul_[od]) == sign (dy_f)
- && (!dy_f || (abs (snapy_f_drul[d] - dy_f_drul_[od] - d * dy_f)
- < maxsnap)))
- {
- dy_f_drul_[d] = snapy_f_drul[d];
- dx_f_drul_[d] = snapx_f_drul[d];
- }
- }
- while (flip (&d) != LEFT);
}
/*
Ugh should have dash-length + dash-period
*/
-Molecule*
-Slur::do_brew_molecule_p () const
+Molecule
+Slur::do_brew_molecule () const
{
Real thick = paper_l ()->get_var ("slur_thickness");
Bezier one = get_curve ();
a.add_molecule (mark);
}
#endif
- return new Molecule (a);
+ return a;
}
+void
+Slur::set_control_points ()
+{
+ Slur_bezier_bow bb (get_encompass_offset_arr (),
+ directional_element (this).get ());
+
+ Real staff_space = Staff_symbol_referencer_interface (this).staff_space ();
+ Real h_inf = paper_l ()->get_var ("slur_height_limit_factor") * staff_space;
+ Real r_0 = paper_l ()->get_var ("slur_ratio");
+ bb.set_default_bezier (h_inf, r_0);
+ if (bb.fit_factor () > 1.0)
+ {
+ Real length = bb.curve_.control_[3][X_AXIS];
+ Real default_height = bb.get_default_height (h_inf, r_0, length);
+ bb.minimise_enclosed_area (paper_l(), default_height);
+
+ Real bff = paper_l ()->get_var ("slur_force_blowfit");
+ bb.curve_.control_[1][Y_AXIS] *= bff;
+ bb.curve_.control_[2][Y_AXIS] *= bff;
+ bb.blow_fit ();
+
+ Real sb = paper_l ()->get_var ("slur_beautiful");
+ Real beautiful = length * default_height * sb;
+ Real area = bb.enclosed_area_f ();
+
+ /*
+ Slurs that fit beautifully are not ugly
+ */
+ if (area > beautiful)
+ de_uglyfy (&bb, default_height);
+ }
+
+ Bezier b = bb.get_bezier ();
+ SCM controls = array_to_scm (b.control_);
+ set_elt_property ("control-points", controls);
+}
+
+
Bezier
Slur::get_curve () const
{
+ Bezier b;
+ Array<Offset> controls (4);
+ scm_to_array (get_elt_property ("control-points"), &controls);
+ b.control_ = controls;
+
Array<Offset> enc (get_encompass_offset_arr ());
- Direction dir = directional_element (this).get ();
- Bezier_bow b (enc,dir);
-
- b.ratio_ = paper_l ()->get_var ("slur_ratio");
- b.height_limit_ = paper_l ()->get_var ("slur_height_limit");
- b.rc_factor_ = paper_l ()->get_var ("slur_rc_factor");
-
- b.calculate ();
-
- Bezier curve = b.get_curve ();
-
+ Direction dir = directional_element (this).get ();
+
Real x1 = enc[0][X_AXIS];
Real x2 = enc.top ()[X_AXIS];
Real x = enc[i][X_AXIS];
if (x > x1 && x <x2)
{
- Real y = curve.get_other_coordinate (X_AXIS, x);
+ Real y = b.get_other_coordinate (X_AXIS, x);
off = off >? dir * (enc[i][Y_AXIS] - y);
}
}
- curve.translate (Offset (0, dir * off));
- return curve;
+ b.translate (Offset (0, dir * off));
+ return b;
}
-
if (!directional_element (this).get ())
directional_element (this).set (get_default_dir ());
- Real staff_space = paper_l ()->get_var ("interline");
- Real half_staff_space = staff_space / 2;
+ Real staff_space = staff_symbol_referencer (this).staff_space ();
+ Real half_space = staff_space / 2;
Real x_gap_f = paper_l ()->get_var ("tie_x_gap");
Real y_gap_f = paper_l ()->get_var ("tie_y_gap");
Real ypos = position_f ();
- Real y_f = half_staff_space * ypos;
+ Real y_f = half_space * ypos;
int ypos_i = int (ypos);
Real dx_f = extent (X_AXIS).length () + dx_f_drul_[RIGHT] - dx_f_drul_[LEFT];
if (dx_f < paper_l ()->get_var ("tie_staffspace_length"))
{
if (abs (ypos_i) % 2)
- y_f += dir * half_staff_space;
+ y_f += dir * half_space;
y_f += dir * y_gap_f;
}
else
{
if (! (abs (ypos_i) % 2))
- y_f += dir * half_staff_space;
- y_f += dir * half_staff_space;
+ y_f += dir * half_space;
+ y_f += dir * half_space;
y_f -= dir * y_gap_f;
}
-Molecule*
-Tie::do_brew_molecule_p () const
+Molecule
+Tie::do_brew_molecule () const
{
Real thick = paper_l ()->get_var ("tie_thickness");
Bezier one = get_curve ();
else
a = lookup_l ()->slur (one, directional_element (this).get () * thick, thick);
- return new Molecule (a);
+ return a;
}
Direction d (directional_element (this).get ());
Bezier_bow b (get_encompass_offset_arr (), d);
- b.ratio_ = paper_l ()->get_var ("slur_ratio");
- b.height_limit_ = paper_l ()->get_var ("slur_height_limit");
- b.rc_factor_ = paper_l ()->get_var ("slur_rc_factor");
+ Real staff_space = staff_symbol_referencer (this).staff_space ();
+ Real h_inf = paper_l ()->get_var ("tie_height_limit_factor") * staff_space;
+ Real r_0 = paper_l ()->get_var ("tie_ratio");
- b.calculate ();
- Bezier c (b.get_curve ());
+ b.set_default_bezier (h_inf, r_0);
+ Bezier c = b.get_bezier ();
/* should do this for slurs as well. */
Array<Real> horizontal (c.solve_derivative (Offset (1,0)));
/*
ugh. Doesnt work for non-horizontal curves.
*/
- Real space = staff_symbol_referencer (this).staff_space ();
Real y = c.curve_point (horizontal[0])[Y_AXIS];
- Real ry = rint (y/space) * space;
+ Real ry = rint (y/staff_space) * staff_space;
Real diff = ry - y;
Real newy = y;
if (fabs (diff) < paper_l ()->get_var ("tie_staffline_clearance"))
{
- newy = ry - 0.5 * space * sign (diff) ;
+ newy = ry - 0.5 * staff_space * sign (diff) ;
}
Real y0 = c.control_ [0][Y_AXIS];
;;;
;;; source file of the GNU LilyPond music typesetter
;;;
-;;; (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+;;; (c) 1999--2000 Jan Nieuwenhuizen <janneke@gnu.org>
;;; All dimensions are measured in staff-spaces
(define stem-shorten '(0.5))
(define grace-stem-shorten '(0.0))
+
+;; urg
+(define pi (* 2 (acos 0)))
+
+(define (slur-default-height h-inf r-0 b)
+ (let ((alpha (/ (* 2.0 h-inf) pi))
+ (beta (/ (* pi r-0) (* 2.0 h-inf))))
+ (* alpha (atan (* beta b)))))
+