CVSROOT: /cvsroot/lilypond Module name: lilypond Branch: Changes by: Han-Wen Nienhuys <[EMAIL PROTECTED]> 05/09/12 10:29:33
Modified files: lily : tie-column.cc tie-helper.cc tie.cc lily/include : tie.hh Log message: * lily/include/tie.hh (struct Tie_details): add x_gap_ (struct Tie_configuration): add head_position_ * lily/tie-column.cc (set_chord_outline): new function. CVSWeb URLs: http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/tie-column.cc.diff?tr1=1.59&tr2=1.60&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/tie-helper.cc.diff?tr1=1.2&tr2=1.3&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/tie.cc.diff?tr1=1.158&tr2=1.159&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/include/tie.hh.diff?tr1=1.57&tr2=1.58&r1=text&r2=text Patches: Index: lilypond/lily/include/tie.hh diff -u lilypond/lily/include/tie.hh:1.57 lilypond/lily/include/tie.hh:1.58 --- lilypond/lily/include/tie.hh:1.57 Sun Sep 4 11:36:40 2005 +++ lilypond/lily/include/tie.hh Mon Sep 12 10:29:33 2005 @@ -24,6 +24,7 @@ Real height_limit_; Real ratio_; Real staff_space_; + Real x_gap_; Tie_details (); void init (Grob *); @@ -31,7 +32,9 @@ struct Tie_configuration { - Real position_; + int head_position_; + int position_; + Direction dir_; Interval attachment_x_; Real delta_y_; Index: lilypond/lily/tie-column.cc diff -u lilypond/lily/tie-column.cc:1.59 lilypond/lily/tie-column.cc:1.60 --- lilypond/lily/tie-column.cc:1.59 Sun Sep 11 09:59:49 2005 +++ lilypond/lily/tie-column.cc Mon Sep 12 10:29:31 2005 @@ -9,12 +9,10 @@ #include "tie-column.hh" #include <math.h> - #include <map> #include <set> - -#include "stencil.hh" +#include "note-head.hh" #include "stem.hh" #include "skyline.hh" #include "staff-symbol-referencer.hh" @@ -93,134 +91,242 @@ } - void -set_chord_outlines (Drul_array< Array<Skyline_entry> > *skyline_drul, - Link_array<Grob> ties, - Grob *common) +set_chord_outline (Array<Skyline_entry> *skyline, + Link_array<Item> bounds, + Grob *common, + Direction d) { - Direction d = LEFT; - - Real staff_space = Staff_symbol_referencer::staff_space (ties[0]); - do - { - Array<Box> boxes; - Interval x_union; + Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]); - Grob *stem = 0; - for (int i = 0; i < ties.size (); i++) - { - Spanner *tie = dynamic_cast<Spanner*> (ties[i]); + Array<Box> boxes; + Interval x_union; - Grob *head = Tie::head (tie, d); - if (!head) - continue; - - if (!stem) - stem = unsmob_grob (head->get_object ("stem")); + Grob *stem = 0; + for (int i = 0; i < bounds.size (); i++) + { + Grob *head = bounds[i]; + if (!Note_head::has_interface (head)) + continue; + + if (!stem) + stem = unsmob_grob (head->get_object ("stem")); - Real p = Tie::get_position (tie); - Interval y ((p-1) * 0.5 * staff_space, - (p+1) * 0.5 * staff_space); - - Interval x = head->extent (common, X_AXIS); - boxes.push (Box (x, y)); - x_union.unite (x); - } + Real p = Staff_symbol_referencer::get_position (head); + Interval y ((p-1) * 0.5 * staff_space, + (p+1) * 0.5 * staff_space); - (*skyline_drul)[d] = empty_skyline (-d); - - Spanner *tie = dynamic_cast<Spanner*> (ties[0]); - if (tie->get_bound (d)->break_status_dir ()) - { - Real x = robust_relative_extent (tie->get_bound (d), - common, - X_AXIS)[-d]; + Interval x = head->extent (common, X_AXIS); + boxes.push (Box (x, y)); + x_union.unite (x); + } - (*skyline_drul)[d].elem_ref (0).height_ = x; - } + (*skyline) = empty_skyline (-d); + + if (bounds[0]->break_status_dir ()) + { + Real x = robust_relative_extent (bounds[0], common, X_AXIS)[-d]; + skyline->elem_ref (0).height_ = x; + } - 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); + for (int i = 0; i < boxes.size (); i++) + insert_extent_into_skyline (skyline, + 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); + insert_extent_into_skyline (skyline, 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); - } + 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, flag_box, + Y_AXIS, -d); + } + } + + Direction updowndir = DOWN; + do + { + Interval x ; + Interval y; + if (boxes.size()) + { + Box b = boxes.boundary (updowndir, 0); + x = b[X_AXIS]; + x[-d] = b[X_AXIS].linear_combination (-d / 2); + y[-updowndir] = b[Y_AXIS][updowndir]; + y[updowndir] = updowndir * infinity_f; } - + if (!x.is_empty ()) + insert_extent_into_skyline (skyline, + Box (x,y), + Y_AXIS, -d); + } + while (flip (&updowndir) != DOWN); + for (int i = 0; i < bounds.size (); i++) + { + if (!Note_head::has_interface (bounds[i])) + continue; - Direction updowndir = DOWN; - do + + Grob *dots = unsmob_grob (bounds[i]->get_object ("dot")); + if (dots && d == LEFT) { - Interval x ; - Interval y; - if (boxes.size()) - { - Box b = boxes.boundary (updowndir, 0); - x = b[X_AXIS]; - x[-d] = b[X_AXIS].linear_combination (-d / 2); - y[-updowndir] = b[Y_AXIS][updowndir]; - y[updowndir] = updowndir * infinity_f; - } - - if (!x.is_empty ()) - insert_extent_into_skyline (&skyline_drul->elem_ref (d), - Box (x,y), - Y_AXIS, -d); + Interval x = dots->extent (common, X_AXIS); + Real p = Staff_symbol_referencer::get_position (dots); + + Interval y (-1,1); + y *= (staff_space /4); + y.translate (p * staff_space * .5); + + insert_extent_into_skyline (skyline, + Box (x,y), Y_AXIS, -d); } - while (flip (&updowndir) != DOWN); + } +} + +void +set_chord_outlines (Drul_array< Array<Skyline_entry> > *skyline_drul, + Link_array<Grob> ties, + Grob *common) +{ + Direction d = LEFT; + do + { + Link_array<Item> bounds; + for (int i = 0; i < ties.size (); i++) { - Spanner *tie = dynamic_cast<Spanner*> (ties[i]); - Grob *head = Tie::head (tie, d); - if (!head) - continue; - - Grob *dots = unsmob_grob (head->get_object ("dot")); - if (dots && d == LEFT) - { - Interval x = dots->extent (common, X_AXIS); - Real p = Staff_symbol_referencer::get_position (dots); - - Interval y (-1,1); - y *= (staff_space /4); - y.translate (p * staff_space * .5); - - insert_extent_into_skyline (&skyline_drul->elem_ref (d), - Box (x,y), Y_AXIS, -d); - } + Item *it = dynamic_cast<Spanner*> (ties[i])->get_bound (d); + + bounds.push (it); } + set_chord_outline (&skyline_drul->elem_ref (d), + bounds, common, d); } while (flip (&d) != LEFT); } +void +shift_small_ties (Array<Tie_configuration> *tie_configs, + Grob *staff_referencer, + Tie_details const &details) +{ + set<int> positions_taken; + for (int i = 0; i < tie_configs->size (); i++) + positions_taken.insert (int (rint (tie_configs->elem (i).position_))); + + for (int i = 0; i < tie_configs->size (); i++) + { + Tie_configuration * conf = &tie_configs->elem_ref (i); + + /* + 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 (); + + int rounded_pos = int (rint (conf->position_ + conf->delta_y_ / details.staff_space_)); + bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer, rounded_pos); + + if (next_free) + if (on_line && h < 0.4 * details.staff_space_) + { + positions_taken.insert (int (rint (conf->position_ + conf->dir_))); + conf->delta_y_ += 0.2 * details.staff_space_ * conf->dir_; + } + else if (!on_line && h > 0.6 * details.staff_space_) + { + positions_taken.insert (int (rint (conf->position_ + conf->dir_))); + conf->delta_y_ += 0.5 * details.staff_space_ * conf->dir_; + } + } +} + + +void +final_shape_adjustment (Tie_configuration &conf, + Drul_array< Array<Skyline_entry> > const &skylines, + Grob *staff_referencer, + Tie_details const &details) +{ + Real line_dy = 0.0; + bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer, + int (rint (conf.position_))); + if (on_line) + line_dy = - sign (conf.height (details) - 0.6 * details.staff_space_) + * 0.2 * details.staff_space_ * conf.dir_; + + Real y = conf.position_ * details.staff_space_ * 0.5 + + line_dy; + + conf.attachment_x_ = get_skyline_attachment (skylines, y); + conf.attachment_x_.intersect (get_skyline_attachment (skylines, + y + conf.dir_ * details.staff_space_ * 0.5)); + + conf.delta_y_ += line_dy; + conf.attachment_x_.widen (-details.x_gap_); + if (!on_line + && Staff_symbol_referencer::staff_radius (staff_referencer) * details.staff_space_ > y) + conf.center_tie_vertically (details); +} + +void +set_tie_config_directions (Array<Tie_configuration> *tie_configs_ptr) +{ + Array<Tie_configuration> &tie_configs (*tie_configs_ptr); + + if (!tie_configs[0].dir_) + tie_configs[0].dir_ = DOWN; + if (!tie_configs.top().dir_) + tie_configs.top().dir_ = UP; + + /* + Seconds + */ + for (int i = 1; i < tie_configs.size(); i++) + { + if (fabs (tie_configs[i-1].position_ - tie_configs[i].position_) <= 1) + { + if (!tie_configs[i-1].dir_) + tie_configs[i-1].dir_ = DOWN; + if (!tie_configs[i].dir_) + tie_configs[i].dir_ = UP; + } + } + + for (int i = 1; i < tie_configs.size() - 1; i++) + { + if (tie_configs[i].dir_) + continue; + + Direction position_dir = (Direction) sign (tie_configs[i].position_); + if (!position_dir) + position_dir = DOWN; + + tie_configs[i].dir_ = position_dir; + } +} + void Tie_column::new_directions (Grob *me) @@ -258,41 +364,15 @@ continue; manual_override = true; - tie_configs[k].position_ = robust_scm2double (scm_car (entry), tie_configs[k].position_); + Real complete_pos = robust_scm2double (scm_car (entry), tie_configs[k].position_); + + tie_configs[k].position_ = int (rint (complete_pos)); + tie_configs[k].delta_y_ = complete_pos - tie_configs[k].position_; tie_configs[k].dir_ = Direction (robust_scm2int (scm_cdr (entry), tie_configs[k].dir_)); k ++; } - if (!tie_configs[0].dir_) - tie_configs[0].dir_ = DOWN; - if (!tie_configs.top().dir_) - tie_configs.top().dir_ = UP; - - /* - Seconds - */ - for (int i = 1; i < tie_configs.size(); i++) - { - if (fabs (tie_configs[i-1].position_ - tie_configs[i].position_) <= 1) - { - if (!tie_configs[i-1].dir_) - tie_configs[i-1].dir_ = DOWN; - if (!tie_configs[i].dir_) - tie_configs[i].dir_ = UP; - } - } - - for (int i = 1; i < tie_configs.size() - 1; i++) - { - if (tie_configs[i].dir_) - continue; - - Direction position_dir = (Direction) sign (tie_configs[i].position_); - if (!position_dir) - position_dir = DOWN; - - tie_configs[i].dir_ = position_dir; - } + set_tie_config_directions (&tie_configs); Grob *common = me; for (int i = 0; i < ties.size (); i++) @@ -326,74 +406,26 @@ /* Calculate final width and shape of the ties. */ - Real staff_space = Staff_symbol_referencer::staff_space (ties[0]); - Real gap = robust_scm2double (ties[0]->get_property ("x-gap"), 0.2); for (int i = 0; i < ties.size(); i++) { if (!manual_override && (i == 0 || i == ties.size () -1)) continue; - - Tie_configuration conf = tie_configs[i]; - conf = tie_configs[i]; - Real line_dy = 0.0; - bool on_line = Staff_symbol_referencer::on_staffline (ties[0], - int (rint (conf.position_))); - if (on_line) - line_dy = - sign (conf.height (details) - 0.6 * staff_space) - * 0.2 * staff_space * conf.dir_; - - Real y = conf.position_ * staff_space * 0.5 - + line_dy; - conf.attachment_x_ - = get_skyline_attachment (skylines, y); - 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 - && Staff_symbol_referencer::staff_radius (ties[0]) * staff_space > y) - conf.center_tie_vertically (details); - - tie_configs[i] = conf; + + final_shape_adjustment (tie_configs[i], + skylines, + ties[0], + details); } + /* Try to shift small ties into available spaces. */ if (!manual_override) { - set<int> positions_taken; - for (int i = 0; i < tie_configs.size (); i++) - positions_taken.insert (int (rint (tie_configs[i].position_))); - - for (int i = 0; i < tie_configs.size (); i++) - { - Tie_configuration * conf = &tie_configs.elem_ref (i); - - /* - 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_; - } - } + shift_small_ties (&tie_configs, ties[0], details); } for (int i = 0; i < ties.size(); i++) @@ -408,6 +440,8 @@ ADD_INTERFACE (Tie_column, "tie-column-interface", "Object that sets directions of multiple ties in a tied chord", + + /* properties */ "positioning-done " "tie-configuration " ); Index: lilypond/lily/tie-helper.cc diff -u lilypond/lily/tie-helper.cc:1.2 lilypond/lily/tie-helper.cc:1.3 --- lilypond/lily/tie-helper.cc:1.2 Sun Sep 4 11:36:40 2005 +++ lilypond/lily/tie-helper.cc Mon Sep 12 10:29:32 2005 @@ -96,6 +96,9 @@ height_limit_ = robust_scm2double (scm_cdr (limit), 0.75) * staff_space_; ratio_ = robust_scm2double (scm_cdr (scm_assq (ly_symbol2scm ("ratio"), details)), .333); + + x_gap_ = robust_scm2double (me->get_property ("x-gap"), 0.2); + } Tie_details::Tie_details () Index: lilypond/lily/tie.cc diff -u lilypond/lily/tie.cc:1.158 lilypond/lily/tie.cc:1.159 --- lilypond/lily/tie.cc:1.158 Thu Sep 8 21:58:29 2005 +++ lilypond/lily/tie.cc Mon Sep 12 10:29:32 2005 @@ -207,53 +207,43 @@ /* UGH. Don't mirror Tie_configuration. */ - Direction dir = CENTER; - - int tie_position = (int) Tie::get_position (me); - int staff_position = (int) conf->position_; - - if (conf->dir_) - { - dir = conf->dir_; - } - else - { - dir = get_grob_direction (me); - if (!dir) - dir = get_default_dir (me); - } + conf->head_position_ = (int) Tie::get_position (me); + if (!conf->dir_) + conf->dir_ = get_grob_direction (me); + if (!conf->dir_) + conf->dir_ = get_default_dir (me); + Real staff_space = details.staff_space_; - bool in_between = true; - Interval attachments = conf->attachment_x_; Real gap = robust_scm2double (me->get_property ("x-gap"), 0.2); - if (attachments.is_empty()) + + if (conf->attachment_x_.is_empty()) { if (!skylines) - attachments = get_default_attachments (me, common, gap, - &staff_position, + conf->attachment_x_ = get_default_attachments (me, common, gap, + &conf->position_, &in_between); else { - Real y = staff_space * 0.5 * staff_position; - attachments = get_skyline_attachment (*skylines, y); - attachments.widen (-gap); + Real y = staff_space * 0.5 * conf->position_; + conf->attachment_x_ = get_skyline_attachment (*skylines, y); + conf->attachment_x_.widen (-gap); } } - Bezier b = slur_shape (attachments.length(), + Bezier b = slur_shape (conf->attachment_x_.length(), details.height_limit_, details.ratio_); - b.scale (1, dir); + b.scale (1, conf->dir_); Offset middle = b.curve_point (0.5); Offset edge = b.curve_point (0.0); - staff_position = int (rint (staff_position)); + conf->position_ = int (rint (conf->position_)); Real dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]); - bool in_space = !(Staff_symbol_referencer::on_staffline (me, (int) staff_position)); + bool in_space = !(Staff_symbol_referencer::on_staffline (me, (int) conf->position_)); bool fits_in_space = (dy < 0.6 * staff_space); @@ -265,18 +255,18 @@ ? int (Staff_symbol_referencer::get_position (left_dot)) : 0; if (left_dot - && (staff_position == dot_pos - || staff_position + dir == dot_pos)) + && (conf->position_ == dot_pos + || conf->position_ + conf->dir_ == dot_pos)) { - staff_position += dir; + conf->position_ += conf->dir_; in_space = !in_space; 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(), + Real y = staff_space * 0.5 * conf->position_; + conf->attachment_x_ = get_skyline_attachment (*skylines, y); + conf->attachment_x_.widen (-gap); + Bezier b = slur_shape (conf->attachment_x_.length(), details.height_limit_, details.ratio_); Offset middle = b.curve_point (0.5); @@ -294,10 +284,10 @@ if (left_stem) { Stencil flag = Stem::get_translated_flag (left_stem); - Real y = staff_position * staff_space * 0.5; + Real y = conf->position_ * staff_space * 0.5; if (flag.extent (Y_AXIS).contains (y)) { - staff_position += dir; + conf->position_ += conf->dir_; in_space = !in_space; } } @@ -306,12 +296,12 @@ { if (in_space) { - staff_position += dir; + conf->position_ += conf->dir_; } else { in_space = true; - staff_position += dir; + conf->position_ += conf->dir_; } /* @@ -319,11 +309,11 @@ */ if (skylines) { - Real y = staff_space * 0.5 * staff_position; - attachments = get_skyline_attachment (*skylines, y); - attachments.widen (-gap); + Real y = staff_space * 0.5 * conf->position_; + conf->attachment_x_ = get_skyline_attachment (*skylines, y); + conf->attachment_x_.widen (-gap); - Bezier b = slur_shape (attachments.length(), + Bezier b = slur_shape (conf->attachment_x_.length(), details.height_limit_, details.ratio_); Offset middle = b.curve_point (0.5); @@ -339,58 +329,53 @@ Putting larger in-space ties next to the notes forces the edges to be opposite (Y-wise) to the tie direction. */ - if (staff_position == tie_position + if (conf->position_ == conf->head_position_ && in_space - && Staff_symbol_referencer::staff_radius (me) > fabs (staff_position) / 2 + && Staff_symbol_referencer::staff_radius (me) > fabs (conf->position_) / 2 && dy > 0.3 * staff_space) { - staff_position += 2 * dir; + conf->position_ += 2 * conf->dir_; } if (!in_between && in_space - && fabs (staff_position - tie_position) <= 1) - staff_position += 2*dir; + && fabs (conf->position_ - conf->head_position_) <= 1) + conf->position_ += 2*conf->dir_; - conf->dir_ = dir; - conf->position_ = staff_position; if (in_space) { - if ((fabs (staff_position - tie_position) <= 1 + if ((fabs (conf->position_ - conf->head_position_) <= 1 && fabs (dy) < 0.45 * staff_space) || fabs (dy) < 0.6 * staff_space) { /* vertically center in space. */ - conf->dir_ = dir; - conf->position_ = staff_position; - conf->attachment_x_ = attachments; conf->center_tie_vertically (details); } else { conf->delta_y_ = - dir * staff_space * (- 0.3); + conf->dir_ * staff_space * (- 0.3); } } else { - Real where = 0.5 * dir; + Real where = 0.5 * conf->dir_; Real rounding_dy = (where - middle[Y_AXIS]); conf->delta_y_ = rounding_dy; - if (dir * (b.curve_point (0.0)[Y_AXIS] + if (conf->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->dir_ * conf->head_position_ * 0.5 * staff_space) { - if (Staff_symbol_referencer::staff_radius (me) > fabs (tie_position) / 2) - conf->position_ += 2 * dir; + if (Staff_symbol_referencer::staff_radius (me) > fabs (conf->head_position_) / 2) + conf->position_ += 2 * conf->dir_; else - conf->position_ += dir; + conf->position_ += conf->dir_; } } @@ -398,13 +383,11 @@ if (skylines) { Real half_space = 0.5 * staff_space; - Real y = staff_position * half_space; + Real y = conf->position_ * half_space; - attachments = get_skyline_attachment (*skylines, y); - - attachments.widen (-gap); + conf->attachment_x_ = get_skyline_attachment (*skylines, y); + conf->attachment_x_.widen (-gap); } - conf->attachment_x_ = attachments; } @@ -524,7 +507,8 @@ "tie-interface", "A tie connecting two noteheads.\n", - + + /* properties */ "control-points " "dash-fraction " "dash-period " _______________________________________________ Lilypond-cvs mailing list Lilypond-cvs@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-cvs