From f1b93c0d52ef9229f8b58acc2ec8207ed50f5bee Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 4 Sep 2005 11:36:40 +0000 Subject: [PATCH] * input/regression/tie-chord.ly (testLong): add a chord in 4ths * lily/tie.cc (get_configuration): update bezier shape as we change Y positions. (get_configuration): don't move large ties if we're outside of the staff. --- ChangeLog | 16 ++++++- flower/include/offset.hh | 2 +- flower/offset.cc | 9 ++++ input/regression/tie-chord.ly | 7 +-- lily/include/stem.hh | 2 +- lily/include/tie.hh | 3 ++ lily/tie-column.cc | 69 +++++++++++++++++++++++------ lily/tie-helper.cc | 16 +++++-- lily/tie.cc | 80 +++++++++++++++++++++++++++------- scm/define-grob-properties.scm | 3 +- scm/define-markup-commands.scm | 3 +- 11 files changed, 169 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index c92ad647d4..ef3f9b786c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-09-04 Han-Wen Nienhuys + + * input/regression/tie-chord.ly (testLong): add a chord in 4ths + + * lily/tie.cc (get_configuration): update bezier shape as we + change Y positions. + (get_configuration): don't move large ties if we're outside of the + staff. + +2005-09-01 Han-Wen Nienhuys + + * scm/define-markup-commands.scm (strut): swap X and Y dims. + 2005-09-03 Jan Nieuwenhuizen * .cvsignore: Add auto-generated configure files and then some. @@ -52,7 +65,8 @@ * lily/tie-column.cc (new_directions): put Tie down on center staff line. - * lily/script-interface.cc (before_line_breaking): use Grob::programming_error + * lily/script-interface.cc (before_line_breaking): use + Grob::programming_error * scm/ps-to-png.scm (make-ps-images): use pngalpha device. diff --git a/flower/include/offset.hh b/flower/include/offset.hh index bf05ab95b6..7929573ee7 100644 --- a/flower/include/offset.hh +++ b/flower/include/offset.hh @@ -95,7 +95,7 @@ public: Real arg () const; Real length () const; - + bool is_sane () const; Offset operator *= (Offset z2) { *this = complex_multiply (*this, z2); diff --git a/flower/offset.cc b/flower/offset.cc index d6d62d44e5..d378d16bdf 100644 --- a/flower/offset.cc +++ b/flower/offset.cc @@ -84,3 +84,12 @@ Offset::length () const { return sqrt (sqr (coordinate_a_[X_AXIS]) + sqr (coordinate_a_[Y_AXIS])); } + +bool +Offset::is_sane () const +{ + return !isnan (coordinate_a_[X_AXIS]) + && !isnan (coordinate_a_ [Y_AXIS]) + && !isinf (coordinate_a_[X_AXIS]) + && !isnan (coordinate_a_[Y_AXIS]); +} diff --git a/input/regression/tie-chord.ly b/input/regression/tie-chord.ly index a06cade46a..2df39cbe0b 100644 --- a/input/regression/tie-chord.ly +++ b/input/regression/tie-chord.ly @@ -39,7 +39,7 @@ testShort = ~ ~ - ~ + 4 ~ } } @@ -58,8 +58,9 @@ testLong = \relative c' { 2 ~ 8 2 ~ 8 - 2 ~ 8 - 2 ~ 8 + 2 ~ 8 + 2 ~ 8 + 2 ~ 8 } } diff --git a/lily/include/stem.hh b/lily/include/stem.hh index 3e498c2a36..fa9f65bccc 100644 --- a/lily/include/stem.hh +++ b/lily/include/stem.hh @@ -29,7 +29,7 @@ public: static Direction get_direction (Grob *); static void set_stemend (Grob *, Real); static Direction get_default_dir (Grob *); - static Slice Stem::beam_multiplicity (Grob *); + static Slice beam_multiplicity (Grob *); static Real thickness (Grob *); static int head_count (Grob *); static bool is_invisible (Grob *); diff --git a/lily/include/tie.hh b/lily/include/tie.hh index 13ce284f4b..0f407b0ea5 100644 --- a/lily/include/tie.hh +++ b/lily/include/tie.hh @@ -72,6 +72,9 @@ public: static int compare (Grob *const &s1, Grob *const &s2); + static + Interval get_default_attachments (Spanner *me, Grob *common, Real gap, + int *staff_position, bool *in_between); }; diff --git a/lily/tie-column.cc b/lily/tie-column.cc index 0e57b3bf76..38ac0c0a8a 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -6,16 +6,19 @@ (c) 2000--2005 Han-Wen Nienhuys */ +#include "tie-column.hh" + #include #include #include + +#include "stencil.hh" #include "stem.hh" #include "skyline.hh" #include "staff-symbol-referencer.hh" #include "warn.hh" -#include "tie-column.hh" #include "paper-column.hh" #include "spanner.hh" #include "pointer-group-interface.hh" @@ -140,6 +143,36 @@ set_chord_outlines (Drul_array< Array > *skyline_drul, for (int i = 0; i < boxes.size (); i++) insert_extent_into_skyline (&skyline_drul->elem_ref (d), boxes[i], Y_AXIS, -d); + if (stem + && !Stem::is_invisible (stem)) + { + Interval x; + x.add_point (stem->relative_coordinate (common, X_AXIS)); + x.widen (staff_space / 20); // ugh. + Interval y; + y.add_point (Stem::stem_end_position (stem) * staff_space * .5); + + Direction stemdir = Stem::get_direction (stem); + y.add_point (Stem::head_positions (stem)[-stemdir] + * staff_space * .5); + + insert_extent_into_skyline (&skyline_drul->elem_ref (d), + Box (x,y), Y_AXIS, -d); + + + + if (d == LEFT) + { + Box flag_box = Stem::get_translated_flag (stem).extent_box (); + flag_box.translate( Offset (x[RIGHT], X_AXIS)); + insert_extent_into_skyline (&skyline_drul->elem_ref (d), + flag_box, + Y_AXIS, -d); + } + } + + + Direction updowndir = DOWN; do @@ -152,11 +185,6 @@ set_chord_outlines (Drul_array< Array > *skyline_drul, x[-d] = b[X_AXIS].linear_combination (-d / 2); } - if (stem - && !Stem::is_invisible (stem) - && updowndir == get_grob_direction (stem)) - x.unite (robust_relative_extent (stem, common, X_AXIS)); - if (!x.is_empty ()) (*skyline_drul)[d].boundary (updowndir, 0).height_ = x[-d]; } @@ -318,6 +346,7 @@ Tie_column::new_directions (Grob *me) conf.attachment_x_.intersect (get_skyline_attachment (skylines, y + conf.dir_ * staff_space * .5)); + conf.delta_y_ += line_dy; conf.attachment_x_.widen (-gap); if (!on_line @@ -339,14 +368,26 @@ Tie_column::new_directions (Grob *me) for (int i = 0; i < tie_configs.size (); i++) { Tie_configuration * conf = &tie_configs.elem_ref (i); - if (Staff_symbol_referencer::on_staffline (ties[0], int (rint (conf->position_))) - && conf->height (details) < 0.4 * staff_space - && (positions_taken.find (int (rint (conf->position_ + conf->dir_))) - == positions_taken.end ())) - { - positions_taken.insert (int (rint (conf->position_ + conf->dir_))); - conf->delta_y_ += 0.2 * staff_space * conf->dir_; - } + + /* + on staff line and small enough, translate a little further + */ + Real h = conf->height (details); + bool next_free = positions_taken.find (int (rint (conf->position_ + conf->dir_))) + == positions_taken.end (); + bool on_line = Staff_symbol_referencer::on_staffline (ties[0], + int (rint (conf->position_ + conf->delta_y_))); + if (next_free) + if (on_line && h < 0.4 * staff_space) + { + positions_taken.insert (int (rint (conf->position_ + conf->dir_))); + conf->delta_y_ += 0.2 * staff_space * conf->dir_; + } + else if (!on_line && h > 0.6 * staff_space) + { + positions_taken.insert (int (rint (conf->position_ + conf->dir_))); + conf->delta_y_ += 0.5 * staff_space * conf->dir_; + } } } diff --git a/lily/tie-helper.cc b/lily/tie-helper.cc index 83f33f06b3..1d49dd5aab 100644 --- a/lily/tie-helper.cc +++ b/lily/tie-helper.cc @@ -7,11 +7,13 @@ */ +#include + #include "tie.hh" #include "bezier.hh" #include "grob.hh" #include "staff-symbol-referencer.hh" - +#include "warn.hh" int Tie_configuration::compare (Tie_configuration const &a, @@ -50,7 +52,13 @@ Tie_configuration::center_tie_vertically (Tie_details const &details) Bezier Tie_configuration::get_bezier (Tie_details const &details) const { - return slur_shape (attachment_x_.length(), + Real l = attachment_x_.length(); + if (isnan (l) || isnan (l)) + { + programming_error ("Inf or NaN encountered"); + l = 1.0; + } + return slur_shape (l, details.height_limit_, details.ratio_); } @@ -70,7 +78,9 @@ Tie_configuration::distance (Tie_configuration const &a, Real Tie_configuration::height (Tie_details const &details) const { - return slur_shape (attachment_x_.length(), + Real l = attachment_x_.length(); + + return slur_shape (l, details.height_limit_, details.ratio_).curve_point (0.5)[Y_AXIS]; } diff --git a/lily/tie.cc b/lily/tie.cc index 65be94ea35..8a105688be 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -115,10 +115,10 @@ Tie::set_direction (Grob *me) } Interval -get_default_attachments (Spanner *me, Grob *common, Real gap, - int *staff_position, - bool *in_between - ) +Tie::get_default_attachments (Spanner *me, Grob *common, Real gap, + int *staff_position, + bool *in_between + ) { Real staff_space = Staff_symbol_referencer::staff_space (me); Direction dir = get_grob_direction (me); @@ -204,6 +204,9 @@ Tie::get_configuration (Grob *me_grob, Grob *common, return ; } + /* + UGH. Don't mirror Tie_configuration. + */ Direction dir = CENTER; int tie_position = (int) Tie::get_position (me); @@ -264,12 +267,26 @@ Tie::get_configuration (Grob *me_grob, Grob *common, { staff_position += dir; in_space = false; + + if (skylines) + { + Real y = staff_space * 0.5 * staff_position; + attachments = get_skyline_attachment (*skylines, y); + attachments.widen (-gap); + Bezier b = slur_shape (attachments.length(), + details.height_limit_, + details.ratio_); + Offset middle = b.curve_point (0.5); + Offset edge = b.curve_point (0.0); + dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]); + fits_in_space = + (dy < 0.6 * staff_space); + } } } - /* Avoid flag. - */ + */ Grob *left_stem = unsmob_grob (me->get_bound (LEFT)->get_object ("stem")); if (left_stem) { @@ -293,6 +310,25 @@ Tie::get_configuration (Grob *me_grob, Grob *common, in_space = true; staff_position += dir; } + + /* + ugh: code dup. + */ + if (skylines) + { + Real y = staff_space * 0.5 * staff_position; + attachments = get_skyline_attachment (*skylines, y); + attachments.widen (-gap); + + Bezier b = slur_shape (attachments.length(), + details.height_limit_, + details.ratio_); + Offset middle = b.curve_point (0.5); + Offset edge = b.curve_point (0.0); + dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]); + fits_in_space = + (dy < 0.6 * staff_space); + } } @@ -302,6 +338,7 @@ Tie::get_configuration (Grob *me_grob, Grob *common, */ if (staff_position == tie_position && in_space + && Staff_symbol_referencer::staff_radius (me) > fabs (staff_position) / 2 && dy > 0.3 * staff_space) { staff_position += 2 * dir; @@ -313,16 +350,21 @@ Tie::get_configuration (Grob *me_grob, Grob *common, staff_position += 2*dir; + conf->dir_ = dir; + conf->position_ = staff_position; if (in_space) { - if (fabs (dy) < 0.45 * staff_space) + if ((fabs (staff_position - tie_position) <= 1 + && fabs (dy) < 0.45 * staff_space) + || fabs (dy) < 0.6 * staff_space) { /* vertically center in space. */ - conf->dir_ = dir; + conf->dir_ = dir; + conf->position_ = staff_position; conf->attachment_x_ = attachments; - conf->center_tie_vertically(details); + conf->center_tie_vertically (details); } else { @@ -337,13 +379,18 @@ Tie::get_configuration (Grob *me_grob, Grob *common, Real rounding_dy = (where - middle[Y_AXIS]); conf->delta_y_ = rounding_dy; - if (dir * b.curve_point (0.0)[Y_AXIS] < + if (dir * (b.curve_point (0.0)[Y_AXIS] + + conf->position_ * staff_space * 0.5 + + conf->delta_y_) < dir * tie_position * 0.5 * staff_space) - conf->delta_y_ += staff_space * dir; + { + if (Staff_symbol_referencer::staff_radius (me) > fabs (tie_position) / 2) + conf->position_ += 2 * dir; + else + conf->position_ += dir; + } } - conf->dir_ = dir; - conf->position_ = staff_position; if (skylines) { @@ -396,8 +443,11 @@ Tie::set_control_points (Grob *me, SCM controls = SCM_EOL; for (int i = 4; i--;) - controls = scm_cons (ly_offset2scm (b.control_[i]), controls); - + { + if (!b.control_[i].is_sane ()) + programming_error ("Insane offset"); + controls = scm_cons (ly_offset2scm (b.control_[i]), controls); + } me->set_property ("control-points", controls); } diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 10d401489e..293f818aff 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -482,8 +482,7 @@ to their durations. This looks better in complex polyphonic patterns") (used ,boolean? "If set, this spacing column is kept in the spacing problem") (when ,ly:moment? "Global time step associated with this column happen?") - (word-space ,ly:dimension? "space to insert between lyrics or -words in texts.") + (word-space ,ly:dimension? "space to insert between words in texts.") (width ,ly:dimension? "The width of a grob measured in staff space.") (x-gap ,ly:dimension? "The horizontal gap between note head and tie.") (zigzag-length ,ly:dimension? "The length of the lines of a diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm index 52e974ac50..6e00f7a3d7 100644 --- a/scm/define-markup-commands.scm +++ b/scm/define-markup-commands.scm @@ -147,8 +147,9 @@ thickness and padding around the markup." "Create a box of the same height as the space in the current font." (let ((m (Text_interface::interpret_markup layout props " "))) (ly:make-stencil (ly:stencil-expr m) + '(1000 . -1000) (ly:stencil-extent m X) - '(1000 . -1000)))) + ))) ;; todo: fix negative space -- 2.39.2