X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie-formatting-problem.cc;h=a55f31373519f6519131a5c5fd76bb8724c55cdd;hb=424dee2dd114c4b69c3b58d2ef61e310e5d492f8;hp=1d42902a4fd32d81386f8e4ac2d7814feb80b21c;hpb=ac73b9ae4bcfa0e596fe05ed804fc8c3b3abbe8d;p=lilypond.git diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index 1d42902a4f..a55f313735 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -12,7 +12,6 @@ #include "paper-column.hh" #include "bezier.hh" #include "directional-element-interface.hh" -#include "item.hh" #include "libc-extension.hh" #include "misc.hh" #include "note-head.hh" @@ -51,7 +50,7 @@ Tie_formatting_problem::get_attachment (Real y, Drul_array columns) const if (i == chord_outlines_.end ()) programming_error ("Can't find chord outline"); else - attachments[d] = skyline_height ((*i).second, y, -d); + attachments[d] = i->second.height (y); } while (flip (&d) != LEFT); @@ -115,28 +114,6 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, } Tuple2 key (column_rank, int (dir)); - - chord_outlines_[key] = empty_skyline (-dir); - - if (bounds[0]->break_status_dir ()) - { - Real x = robust_relative_extent (bounds[0], x_refpoint_, X_AXIS)[-dir]; - chord_outlines_[key].at (0).height_ = x; - } - else - { - Interval x; - for (vsize j = 0; j < head_boxes.size (); j++) - { - x.unite (head_boxes[j][X_AXIS]); - } - - chord_outlines_[key].at (0).height_ = x[dir]; - } - - for (vsize i = 0; i < boxes.size (); i++) - insert_extent_into_skyline (&chord_outlines_[key] , - boxes[i], Y_AXIS, -dir); if (stem && !Stem::is_invisible (stem)) @@ -150,8 +127,8 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, Direction stemdir = get_grob_direction (stem); y.add_point (Stem::head_positions (stem)[-stemdir] * staff_space * .5); - - insert_extent_into_skyline (&chord_outlines_[key], Box (x,y), Y_AXIS, -dir); + + boxes.push_back (Box (x, y)); stem_extents_[key].unite (Box (x,y)); @@ -159,8 +136,7 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, { Box flag_box = Stem::get_translated_flag (stem).extent_box (); flag_box.translate( Offset (x[RIGHT], X_AXIS)); - insert_extent_into_skyline (&chord_outlines_[key], flag_box, - Y_AXIS, -dir); + boxes.push_back (flag_box); } } else if (stem) @@ -176,10 +152,8 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, Interval y_ext; for (vsize j = 0; j < head_boxes.size (); j++) y_ext.unite (head_boxes[j][Y_AXIS]); - - insert_extent_into_skyline (&chord_outlines_[key], - Box (x_ext, y_ext), - Y_AXIS, -dir); + + boxes.push_back (Box (x_ext, y_ext)); } Direction updowndir = DOWN; @@ -197,12 +171,28 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, } if (!x.is_empty ()) - insert_extent_into_skyline (&chord_outlines_[key], - Box (x,y), - Y_AXIS, -dir); + boxes.push_back (Box (x, y)); } while (flip (&updowndir) != DOWN); - + + /* todo: the horizon_padding is somewhat arbitrary */ + chord_outlines_[key] = Skyline (boxes, 0.1, Y_AXIS, -dir); + if (bounds[0]->break_status_dir ()) + { + Real x = robust_relative_extent (bounds[0], x_refpoint_, X_AXIS)[-dir]; + chord_outlines_[key].set_minimum_height (x); + } + else + { + Interval x; + for (vsize j = 0; j < head_boxes.size (); j++) + { + x.unite (head_boxes[j][X_AXIS]); + } + + chord_outlines_[key].set_minimum_height (x[dir]); + } + head_extents_[key].set_empty (); for (vsize i = 0; i < head_boxes.size (); i++) { @@ -219,7 +209,7 @@ Tie_formatting_problem::set_chord_outline (vector bounds, for (vsize i = 0; i < bounds.size (); i++) ranks.push_back (bounds[i]->get_column ()->get_rank ()); - vector_sort (ranks, default_compare); + vector_sort (ranks, less ()); uniq (ranks); for (vsize i = 0; i < ranks.size (); i++) @@ -288,20 +278,10 @@ Tie_formatting_problem::from_ties (vector const &ties) for (vsize i = 0; i < ties.size (); i++) { Tie_specification spec; + + spec.get_tie_manual_settings (ties[i]); - if (scm_is_number (ties[i]->get_property_data (ly_symbol2scm ("direction")))) - { - spec.manual_dir_ = to_dir (ties[i]->get_property ("direction")); - spec.has_manual_dir_ = true; - } - - spec.position_ = Tie::get_position (ties[i]); - if (scm_is_number (ties[i]->get_property ("staff-position"))) - { - spec.manual_position_ = scm_to_double (ties[i]->get_property ("staff-position")); - spec.has_manual_position_ = true; - spec.position_ = int (my_round (spec.manual_position_)); - } + do { @@ -315,19 +295,19 @@ Tie_formatting_problem::from_ties (vector const &ties) } void -Tie_formatting_problem::from_semi_ties (vector const &lv_ties, Direction head_dir) +Tie_formatting_problem::from_semi_ties (vector const &semi_ties, Direction head_dir) { - if (lv_ties.empty ()) + if (semi_ties.empty ()) return; - details_.from_grob (lv_ties[0]); + details_.from_grob (semi_ties[0]); vector heads; int column_rank = -1; - for (vsize i = 0; i < lv_ties.size (); i++) + for (vsize i = 0; i < semi_ties.size (); i++) { Tie_specification spec; - Item *head = unsmob_item (lv_ties[i]->get_object ("note-head")); + Item *head = unsmob_item (semi_ties[i]->get_object ("note-head")); if (!head) programming_error ("LV tie without head?!"); @@ -336,8 +316,9 @@ Tie_formatting_problem::from_semi_ties (vector const &lv_ties, Direction { spec.position_ = int (Staff_symbol_referencer::get_position (head)); } - + spec.get_tie_manual_settings (semi_ties[i]); + spec.note_head_drul_[head_dir] = head; column_rank = dynamic_cast (head)->get_column ()->get_rank (); spec.column_ranks_ = Drul_array (column_rank, column_rank); @@ -345,30 +326,20 @@ Tie_formatting_problem::from_semi_ties (vector const &lv_ties, Direction specifications_.push_back (spec); } - x_refpoint_ = lv_ties [0]; - for (vsize i = 0; i < lv_ties.size (); i++) - x_refpoint_ = lv_ties[i]->common_refpoint (x_refpoint_, X_AXIS); + x_refpoint_ = semi_ties [0]; + for (vsize i = 0; i < semi_ties.size (); i++) + x_refpoint_ = semi_ties[i]->common_refpoint (x_refpoint_, X_AXIS); for (vsize i = 0; i < heads.size (); i++) x_refpoint_ = heads[i]->common_refpoint (x_refpoint_, X_AXIS); set_chord_outline (heads, head_dir); - Real extremal = head_dir * infinity_f; - Tuple2 head_key (column_rank, head_dir); Tuple2 open_key (column_rank, -head_dir); - - for (vsize i = 0; i < chord_outlines_[head_key].size (); i++) - { - extremal = head_dir * min (head_dir * extremal, - head_dir * chord_outlines_[head_key][i].height_); - } + Real extremal = chord_outlines_[head_key].max_height (); - Skyline_entry right_entry; - right_entry.width_.set_full (); - right_entry.height_ = extremal - head_dir * 1.5; - - chord_outlines_[open_key].push_back (right_entry); + chord_outlines_[open_key] = Skyline (head_dir); + chord_outlines_[open_key].set_minimum_height (extremal - head_dir * 1.5); } @@ -494,33 +465,50 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir, conf->attachment_x_.widen ( - details_.x_gap_); - Direction d = LEFT; - do + if (conf->column_span_length ()) { - Real y = conf->position_ * details_.staff_space_ * 0.5 + conf->delta_y_; - if (get_stem_extent (conf->column_ranks_[d], d, X_AXIS).is_empty () - || !get_stem_extent (conf->column_ranks_[d], d, Y_AXIS).contains (y)) - continue; + /* + avoid the stems that we attach to as well. We don't do this + for semities (span length = 0) - conf->attachment_x_[d] = - d * min (d * conf->attachment_x_[d], - d * (get_stem_extent (conf->column_ranks_[d], d, X_AXIS)[-d] - d * details_.stem_gap_)); - } - while (flip (&d) != LEFT); - + It would be better to check D against HEAD-DIRECTION if + applicable. + */ + Direction d = LEFT; + do + { + Real y = conf->position_ * details_.staff_space_ * 0.5 + conf->delta_y_; + if (get_stem_extent (conf->column_ranks_[d], d, X_AXIS).is_empty () + || !get_stem_extent (conf->column_ranks_[d], d, Y_AXIS).contains (y)) + continue; + + conf->attachment_x_[d] = + d * min (d * conf->attachment_x_[d], + d * (get_stem_extent (conf->column_ranks_[d], d, X_AXIS)[-d] - d * details_.stem_gap_)); + } + while (flip (&d) != LEFT); + } return conf; } Interval Tie_formatting_problem::get_head_extent (int col, Direction d, Axis a) const { - return (*head_extents_.find (Tuple2 (col, int (d)))).second[a]; + Column_extent_map::const_iterator i = head_extents_.find (Tuple2 (col, int (d))); + if (i != head_extents_.end ()) + return (*i).second[a]; + else + return Interval (); } Interval Tie_formatting_problem::get_stem_extent (int col, Direction d, Axis a) const { - return (*stem_extents_.find (Tuple2 (col, int (d)))).second[a]; + Column_extent_map::const_iterator i = stem_extents_.find (Tuple2 (col, int (d))); + if (i != stem_extents_.end ()) + return (*i).second[a]; + else + return Interval (); } /** @@ -709,6 +697,25 @@ Tie_specification::Tie_specification () column_ranks_[LEFT] = 0; } + +void +Tie_specification::get_tie_manual_settings (Grob *tie) +{ + if (scm_is_number (tie->get_property_data ("direction"))) + { + manual_dir_ = to_dir (tie->get_property ("direction")); + has_manual_dir_ = true; + } + + position_ = Tie::get_position (tie); + if (scm_is_number (tie->get_property ("staff-position"))) + { + manual_position_ = scm_to_double (tie->get_property ("staff-position")); + has_manual_position_ = true; + position_ = int (my_round (manual_position_)); + } +} + int Tie_specification::column_span () const { @@ -885,7 +892,6 @@ Tie_formatting_problem::find_best_variation (Ties_configuration const &base, Ties_configuration Tie_formatting_problem::generate_optimal_chord_configuration () { - Ties_configuration base = generate_base_chord_configuration (); vector vars = generate_collision_variations (base); @@ -902,9 +908,16 @@ Tie_formatting_problem::set_ties_config_standard_directions (Ties_configuration { if (tie_configs->empty ()) return ; - + if (!tie_configs->at (0).dir_) - tie_configs->at (0).dir_ = DOWN; + { + if (tie_configs->size () == 1) + tie_configs->at (0).dir_ = Direction (sign (tie_configs->at (0).position_)); + + if (!tie_configs->at (0).dir_) + tie_configs->at (0).dir_ = DOWN; + } + if (!tie_configs->back ().dir_) tie_configs->back ().dir_ = UP;