From: fred Date: Tue, 26 Mar 2002 22:46:23 +0000 (+0000) Subject: lilypond-1.3.29 X-Git-Tag: release/1.5.59~1858 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=fa061454f32b0d6d7a704e2cd48cc041fb712ed1;p=lilypond.git lilypond-1.3.29 --- diff --git a/lily/atom.cc b/lily/atom.cc index 9dd82bc754..f44d4d2c4e 100644 --- a/lily/atom.cc +++ b/lily/atom.cc @@ -29,7 +29,7 @@ SCM 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); } @@ -41,7 +41,7 @@ translate_atom_axis (Real r, Axis a, SCM func) 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); } diff --git a/lily/bezier-bow.cc b/lily/bezier-bow.cc index 3565cddb31..0a51f93614 100644 --- a/lily/bezier-bow.cc +++ b/lily/bezier-bow.cc @@ -15,259 +15,19 @@ #include "debug.hh" #include "main.hh" #include "lily-guile.hh" - -void -flipy (Array &c) -{ - for (int i = c.size (); i--;) - c[i][Y_AXIS] = - c[i][Y_AXIS]; -} - -void -rotate (Array &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 &c, Offset o) -{ - for (int i = 0; i < c.size (); i++) - c[i] += o; -} +#include "paper-def.hh" -Bezier_bow::Bezier_bow (Array points, Direction dir) +Bezier_bow::Bezier_bow (Array 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 -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 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 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) 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) @@ -281,191 +41,81 @@ Bezier_bow::get_curve ()const 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 disturb; - Drul_array 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 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 +} + diff --git a/lily/bezier.cc b/lily/bezier.cc index 28634b473c..6b388e1d8f 100644 --- a/lily/bezier.cc +++ b/lily/bezier.cc @@ -10,6 +10,45 @@ #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* 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* 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* arr_p, Offset o) +{ + for (int i = 0; i < arr_p->size (); i++) + (*arr_p)[i] += o; +} + /* Formula of the bezier 3-spline @@ -18,6 +57,7 @@ */ Bezier::Bezier () + : control_ (CONTROL_COUNT) { } @@ -33,20 +73,6 @@ Bezier::get_other_coordinate (Axis a, Real x) const 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 @@ -151,27 +177,23 @@ Bezier::extent (Axis a)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 ()) diff --git a/lily/include/bezier-bow.hh b/lily/include/bezier-bow.hh index d442124a5c..4c2ea55fc9 100644 --- a/lily/include/bezier-bow.hh +++ b/lily/include/bezier-bow.hh @@ -19,36 +19,27 @@ from bow paratime_signatures. */ class Bezier_bow { - Bezier curve_; - Array 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 area_gradient_offset_arr (); +public: + Bezier_bow (Array 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 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 points, Direction dir); - void calculate (); - Bezier get_curve () const; }; diff --git a/lily/include/bezier.hh b/lily/include/bezier.hh index 47890afca2..3ac97b7170 100644 --- a/lily/include/bezier.hh +++ b/lily/include/bezier.hh @@ -24,10 +24,12 @@ class Bezier 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 solve_point (Axis, Real coordinate) const; Array solve_derivative (Offset) const; @@ -35,12 +37,13 @@ public: Polynomial polynomial (Axis)const; Offset curve_point (Real t) const; - void reverse (); - static const int CONTROL_COUNT = 4; - Offset control_[CONTROL_COUNT]; + Array control_; }; +void flip (Array* arr_p, Axis a); +void rotate (Array* arr_p, Real phi); +void translate (Array* arr_p, Offset o); #endif // BEZIER_HH diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index 8d808ac403..b79ffbf895 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -20,8 +20,6 @@ SCM ly_eval_str (String s); 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); @@ -54,6 +52,9 @@ int scm_to (SCM s, int* i); 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. */ diff --git a/lily/include/slur.hh b/lily/include/slur.hh index 2fc37f1df8..4f14512047 100644 --- a/lily/include/slur.hh +++ b/lily/include/slur.hh @@ -15,8 +15,6 @@ */ class Slur : public Spanner { - int cross_staff_count () const; - Offset encompass_offset (Note_column const* )const; public: Slur (); VIRTUAL_COPY_CONS(Score_element); @@ -25,7 +23,7 @@ public: protected: - virtual Molecule* do_brew_molecule_p () const; + virtual Molecule do_brew_molecule () const; virtual Array get_encompass_offset_arr () const; Bezier get_curve () const; Drul_array dy_f_drul_; @@ -35,6 +33,13 @@ protected: virtual void do_post_processing (); virtual void do_add_processing (); Array 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 diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index 0ed09ec2de..ccca3060e9 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -328,13 +328,13 @@ appendable_list_append (SCM l, SCM elt) 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))); diff --git a/lily/lookup.cc b/lily/lookup.cc index 28a50a073e..f1d1189b24 100644 --- a/lily/lookup.cc +++ b/lily/lookup.cc @@ -59,9 +59,10 @@ Lookup::afm_find (String s, bool warn) const } } AFM_CharMetricInfo const *cm = afm_l_->find_char_metric (s, warn); - Molecule m; + if (!cm) { + Molecule m; m.set_empty (false); return m; } @@ -71,9 +72,7 @@ Lookup::afm_find (String s, bool warn) const 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 @@ -177,19 +176,17 @@ Lookup::beam (Real slope, Real width, Real thick) 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); } @@ -198,9 +195,10 @@ Molecule 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"), @@ -208,9 +206,9 @@ Lookup::dashed_slur (Bezier b, Real thick, Real dash) 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); } @@ -228,8 +226,6 @@ Lookup::fill (Box b) 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]), @@ -237,9 +233,7 @@ Lookup::filledbox (Box b ) gh_double2scm (b[Y_AXIS][UP]), SCM_UNDEFINED)); - m.dim_ = b; - m.add_atom (at); - return m; + return Molecule ( b,at); } Molecule @@ -320,7 +314,6 @@ sanitise_PS_string (String t) Molecule Lookup::text (String style, String text, Paper_def *paper_l) { - Molecule m; if (style.empty_b ()) style = "roman"; @@ -361,15 +354,14 @@ Lookup::text (String style, String text, Paper_def *paper_l) 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); } @@ -377,8 +369,6 @@ Lookup::text (String style, String text, Paper_def *paper_l) Molecule Lookup::staff_brace (Real y, int staff_size) { - Molecule m; - // URG Real step = 1.0; int minht = 2 * staff_size; @@ -396,10 +386,9 @@ Lookup::staff_brace (Real y, int 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); } @@ -417,10 +406,11 @@ Lookup::slur (Bezier curve, Real curvethick, Real linethick) 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 @@ -438,17 +428,13 @@ Lookup::slur (Bezier curve, Real curvethick, Real linethick) 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")), @@ -458,10 +444,9 @@ Lookup::staff_bracket (Real height, Paper_def* paper_l) 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; diff --git a/lily/molecule.cc b/lily/molecule.cc index f447d542d6..cd4d048206 100644 --- a/lily/molecule.cc +++ b/lily/molecule.cc @@ -10,8 +10,10 @@ ugh. Rewrite not finished yet. Still must copy atom lists. */ + #include +#include "dimensions.hh" #include "interval.hh" #include "string.hh" #include "molecule.hh" @@ -32,67 +34,60 @@ Molecule::extent(Axis a) const 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) { @@ -112,41 +107,16 @@ void 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); } @@ -168,5 +138,5 @@ Molecule::add_at_edge (Axis a, Direction d, Molecule const &m, Real padding) bool Molecule::empty_b () const { - return gh_cdr (atom_list_) == SCM_EOL; + return expr_ == SCM_EOL; } diff --git a/lily/paper-outputter.cc b/lily/paper-outputter.cc index f3863b13bd..fc5630d9ac 100644 --- a/lily/paper-outputter.cc +++ b/lily/paper-outputter.cc @@ -73,57 +73,43 @@ Paper_outputter::output_header () } 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); } } diff --git a/lily/slur.cc b/lily/slur.cc index bc64fd20c4..679ece65b5 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -24,17 +24,213 @@ #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 encompass, Direction dir); + Array 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 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 +Slur_bezier_bow::area_x_gradients_array (Real area) +{ + Real len = curve_.control_[3][X_AXIS]; + Real grow = len / 10.0; + Array 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 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 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 @@ -50,6 +246,36 @@ Slur::add_column (Note_column*n) } } +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 { @@ -94,7 +320,7 @@ Slur::encompass_offset (Note_column const* col) 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; } @@ -125,13 +351,19 @@ Slur::encompass_offset (Note_column const* col) const 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 encompass_arr = Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); @@ -287,158 +519,6 @@ Slur::do_post_processing () 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 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 snapy_f_drul; - snapy_f_drul[LEFT] = snapy_f_drul[RIGHT] = 0; - Drul_array snapx_f_drul; - snapx_f_drul[LEFT] = snapx_f_drul[RIGHT] = 0; - Drul_array 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); } @@ -560,8 +640,8 @@ ugly_scm (Bezier b) /* 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 (); @@ -586,26 +666,60 @@ Slur::do_brew_molecule_p () const 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 controls (4); + scm_to_array (get_elt_property ("control-points"), &controls); + b.control_ = controls; + Array 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]; @@ -615,12 +729,11 @@ Slur::get_curve () const Real x = enc[i][X_AXIS]; if (x > x1 && x ? dir * (enc[i][Y_AXIS] - y); } } - curve.translate (Offset (0, dir * off)); - return curve; + b.translate (Offset (0, dir * off)); + return b; } - diff --git a/lily/tie.cc b/lily/tie.cc index b96a815dfa..7f1befbf66 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -106,8 +106,8 @@ Tie::do_post_processing() 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"); @@ -150,7 +150,7 @@ Tie::do_post_processing() 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]; @@ -158,14 +158,14 @@ Tie::do_post_processing() 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; } @@ -188,8 +188,8 @@ Tie::get_rods () const -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 (); @@ -201,7 +201,7 @@ Tie::do_brew_molecule_p () const else a = lookup_l ()->slur (one, directional_element (this).get () * thick, thick); - return new Molecule (a); + return a; } @@ -212,12 +212,12 @@ Tie::get_curve () const 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 horizontal (c.solve_derivative (Offset (1,0))); @@ -227,15 +227,14 @@ Tie::get_curve () const /* 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]; diff --git a/scm/paper.scm b/scm/paper.scm index 36ccac9622..9a6b05a8c0 100644 --- a/scm/paper.scm +++ b/scm/paper.scm @@ -2,7 +2,7 @@ ;;; ;;; source file of the GNU LilyPond music typesetter ;;; -;;; (c) 1999 Jan Nieuwenhuizen +;;; (c) 1999--2000 Jan Nieuwenhuizen ;;; All dimensions are measured in staff-spaces @@ -125,3 +125,12 @@ (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))))) +