X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie-formatting-problem.cc;h=882dd7ae8baa86cded287ba532e4a4dc2b00afc1;hb=d0ac289571b1621a86918939b098607ca67b75fb;hp=439e76cf5069ea5023c0ca5c96b354114876fc2e;hpb=337f1aee4be0e4818f58cdfac1432327fd290ead;p=lilypond.git diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index 439e76cf50..882dd7ae8b 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -9,6 +9,7 @@ #include "tie-formatting-problem.hh" +#include "paper-column.hh" #include "bezier.hh" #include "directional-element-interface.hh" #include "item.hh" @@ -39,13 +40,14 @@ Tie_formatting_problem::print_ties_configuration (Ties_configuration const *ties } Interval -Tie_formatting_problem::get_attachment (Real y) const +Tie_formatting_problem::get_attachment (Real y, Drul_array columns) const { Interval attachments; Direction d = LEFT; do { - attachments[d] = skyline_height (chord_outlines_[d], y, -d); + Chord_outline_map::const_iterator i (chord_outlines_.find (columns[d])); + attachments[d] = skyline_height ((*i).second, y, -d); } while (flip (&d) != LEFT); @@ -65,8 +67,9 @@ Tie_formatting_problem::~Tie_formatting_problem () } void -Tie_formatting_problem::set_chord_outline (vector bounds, - Direction dir) +Tie_formatting_problem::set_column_chord_outline (vector bounds, + Direction dir, + int column_rank) { Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]); @@ -79,7 +82,7 @@ Tie_formatting_problem::set_chord_outline (vector bounds, Grob *head = bounds[i]; if (!Note_head::has_interface (head)) continue; - + if (!stem) stem = unsmob_grob (head->get_object ("stem")); @@ -106,26 +109,27 @@ Tie_formatting_problem::set_chord_outline (vector bounds, boxes.push_back (Box (x, y)); } } - - chord_outlines_[dir] = empty_skyline (-dir); + + chord_outlines_[column_rank] = empty_skyline (-dir); + if (bounds[0]->break_status_dir ()) { Real x = robust_relative_extent (bounds[0], x_refpoint_, X_AXIS)[-dir]; - chord_outlines_[dir].at (0).height_ = x; + chord_outlines_[column_rank].at (0).height_ = x; } else { - Interval x; - for (vsize i = 0; i < head_boxes.size (); i++) + Interval x; + for (vsize j = 0; j < head_boxes.size (); j++) { - x.unite (head_boxes[i][X_AXIS]); + x.unite (head_boxes[j][X_AXIS]); } - - chord_outlines_[dir].at (0).height_ = x[dir]; + + chord_outlines_[column_rank].at (0).height_ = x[dir]; } - + for (vsize i = 0; i < boxes.size (); i++) - insert_extent_into_skyline (&chord_outlines_[dir] , + insert_extent_into_skyline (&chord_outlines_[column_rank] , boxes[i], Y_AXIS, -dir); if (stem @@ -141,7 +145,7 @@ Tie_formatting_problem::set_chord_outline (vector bounds, y.add_point (Stem::head_positions (stem)[-stemdir] * staff_space * .5); - insert_extent_into_skyline (&chord_outlines_[dir], Box (x,y), Y_AXIS, -dir); + insert_extent_into_skyline (&chord_outlines_[column_rank], Box (x,y), Y_AXIS, -dir); stem_extents_[dir].unite (Box (x,y)); @@ -149,7 +153,7 @@ Tie_formatting_problem::set_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_[dir], flag_box, + insert_extent_into_skyline (&chord_outlines_[column_rank], flag_box, Y_AXIS, -dir); } } @@ -169,7 +173,7 @@ Tie_formatting_problem::set_chord_outline (vector bounds, } if (!x.is_empty ()) - insert_extent_into_skyline (&chord_outlines_[dir], + insert_extent_into_skyline (&chord_outlines_[column_rank], Box (x,y), Y_AXIS, -dir); } @@ -182,6 +186,32 @@ Tie_formatting_problem::set_chord_outline (vector bounds, } } +void +Tie_formatting_problem::set_chord_outline (vector bounds, + Direction dir) + +{ + vector ranks; + for (vsize i = 0; i < bounds.size (); i++) + ranks.push_back (bounds[i]->get_column ()->get_rank ()); + + vector_sort (ranks, default_compare); + uniq (ranks); + + for (vsize i = 0; i < ranks.size (); i++) + { + vector col_items; + for (vsize j = 0; j < bounds.size (); j ++) + { + if (bounds[j]->get_column ()->get_rank () == ranks[i]) + col_items.push_back (bounds[j]); + } + + set_column_chord_outline (col_items, dir, ranks[i]); + } +} + + void Tie_formatting_problem::from_tie (Grob *tie) @@ -252,9 +282,10 @@ Tie_formatting_problem::from_ties (vector const &ties) do { spec.note_head_drul_[d] = Tie::head (ties[i], d); + spec.column_ranks_[d] = + dynamic_cast (ties[i])->get_bound (d)->get_column ()->get_rank (); } while (flip (&d) != LEFT); - specifications_.push_back (spec); } } @@ -317,40 +348,47 @@ Tie_formatting_problem::get_tie_specification (int i) const } +/* + Return configuration, create it if necessary. +*/ Tie_configuration* -Tie_formatting_problem::get_configuration (int pos, Direction dir) const +Tie_formatting_problem::get_configuration (int pos, Direction dir, Drul_array columns) const { - pair key (pos, dir); + int key_components[] = { + pos, dir, columns[LEFT], columns[RIGHT] + }; + Tuple key (key_components); + Tie_configuration_map::const_iterator f = possibilities_.find (key); - if (f != possibilities_.end ()) { return (*f).second; } - Tie_configuration *conf = generate_configuration (pos, dir); + Tie_configuration *conf = generate_configuration (pos, dir, columns); ((Tie_formatting_problem*) this)->possibilities_[key] = conf; return conf; } Tie_configuration* -Tie_formatting_problem::generate_configuration (int pos, Direction dir) const +Tie_formatting_problem::generate_configuration (int pos, Direction dir, + Drul_array columns) const { Tie_configuration *conf = new Tie_configuration; conf->position_ = pos; conf->dir_ = dir; + + conf->column_ranks_ = columns; + Real y = conf->position_ * 0.5 * details_.staff_space_; - bool y_tune = true; if (dot_positions_.find (pos) != dot_positions_.end ()) { conf->delta_y_ += dir * 0.25 * details_.staff_space_; y_tune = false; } - - if (y_tune && max (fabs (head_extents_[LEFT][Y_AXIS][dir] - y), @@ -364,7 +402,7 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir) const if (y_tune) { - conf->attachment_x_ = get_attachment (y + conf->delta_y_); + conf->attachment_x_ = get_attachment (y + conf->delta_y_, conf->column_ranks_); Real h = conf->height (details_); /* @@ -407,7 +445,7 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir) const } } - conf->attachment_x_ = get_attachment (y + conf->delta_y_); + conf->attachment_x_ = get_attachment (y + conf->delta_y_, conf->column_ranks_); if (conf->height (details_) < details_.intra_space_threshold_ * 0.5 * details_.staff_space_) { /* @@ -417,7 +455,8 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir) const Interval close_by = get_attachment (y + conf->delta_y_ + (dir * details_.intra_space_threshold_ * 0.25 - * details_.staff_space_)); + * details_.staff_space_), + conf->column_ranks_); conf->attachment_x_.intersect (close_by); } @@ -433,10 +472,11 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir) const continue; conf->attachment_x_[d] = - d* min (d * conf->attachment_x_[d], - d * (stem_extents_[d][X_AXIS][-d] - d * details_.stem_gap_)); + d * min (d * conf->attachment_x_[d], + d * (stem_extents_[d][X_AXIS][-d] - d * details_.stem_gap_)); } while (flip (&d) != LEFT); + return conf; } @@ -571,7 +611,8 @@ Tie_formatting_problem::find_optimal_tie_configuration (Tie_specification const for (int i = 0; i < details_.single_tie_region_size_; i ++) { - confs.push_back (generate_configuration (pos + i * dir, dir)); + confs.push_back (generate_configuration (pos + i * dir, dir, + spec.column_ranks_)); if (spec.has_manual_position_) { @@ -600,7 +641,12 @@ Tie_formatting_problem::find_optimal_tie_configuration (Tie_specification const } } - Tie_configuration best = *confs[best_idx]; + if (best_idx < 0) + programming_error ("No best tie configuration found."); + + Tie_configuration best + = (best_idx >= 0) ? *confs[best_idx] : *confs[0]; + for (vsize i = 0; i < confs.size (); i++) delete confs[i]; @@ -616,8 +662,15 @@ Tie_specification::Tie_specification () manual_dir_ = CENTER; note_head_drul_[LEFT] = note_head_drul_[RIGHT] = 0; + column_ranks_[RIGHT] = + column_ranks_[LEFT] = 0; } +int +Tie_specification::column_span () const +{ + return column_ranks_[RIGHT] - column_ranks_[LEFT]; +} void Tie_formatting_problem::score_ties_aptitude (Ties_configuration *ties) const @@ -709,7 +762,8 @@ Tie_formatting_problem::generate_ties_configuration (Ties_configuration const &t Ties_configuration copy; for (vsize i = 0; i < ties_config.size (); i++) { - Tie_configuration * ptr = get_configuration (ties_config[i].position_, ties_config[i].dir_); + Tie_configuration * ptr = get_configuration (ties_config[i].position_, ties_config[i].dir_, + ties_config[i].column_ranks_); if (specifications_[i].has_manual_position_) { ptr->delta_y_ @@ -741,6 +795,8 @@ Tie_formatting_problem::generate_base_chord_configuration () { conf.position_ = specifications_[i].position_; } + + conf.column_ranks_ = specifications_[i].column_ranks_; ties_config.push_back (conf); } @@ -814,10 +870,19 @@ Tie_formatting_problem::set_ties_config_standard_directions (Ties_configuration */ for (vsize i = 1; i < tie_configs->size (); i++) { - Real diff = (tie_configs->at (i-1).position_ - - tie_configs->at (i).position_); - - if (fabs (diff) <= 1) + Real diff = (tie_configs->at (i).position_ + -tie_configs->at (i-1).position_); + + Real span_diff + = specifications_[i].column_span () - specifications_[i-1].column_span (); + if (span_diff && fabs (diff) <= 2) + { + if (span_diff > 0) + tie_configs->at (i).dir_ = UP; + else if (span_diff < 0) + tie_configs->at (i-1).dir_ = DOWN; + } + else if (fabs (diff) <= 1) { if (!tie_configs->at (i-1).dir_) tie_configs->at (i-1).dir_ = DOWN; @@ -861,7 +926,8 @@ Tie_formatting_problem::generate_extremal_tie_variations (Ties_configuration con Tie_configuration_variation var; var.index_ = (d == DOWN) ? 0 : ties.size () - 1; var.suggestion_ = get_configuration (boundary (ties, d, 0).position_ - + d * i, d); + + d * i, d, + boundary (ties, d, 0).column_ranks_); vars.push_back (var); } } @@ -894,7 +960,10 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const var.index_ = i; var.suggestion_ = get_configuration (specifications_[i].position_ - ties[i].dir_, - -ties[i].dir_); + - ties[i].dir_, + + ties[i].column_ranks_ + ); vars.push_back (var); } @@ -905,7 +974,8 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const var.index_ = i-1; var.suggestion_ = get_configuration (specifications_[i-1].position_ - ties[i-1].dir_, - - ties[i-1].dir_); + - ties[i-1].dir_, + specifications_[i-1].column_ranks_); vars.push_back (var); } @@ -915,8 +985,8 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const { Tie_configuration_variation var; var.index_ = i-1; - var.suggestion_ = get_configuration (specifications_[i-1].position_ - - 1, DOWN); + var.suggestion_ = get_configuration (specifications_[i-1].position_ - 1, DOWN, + specifications_[i-1].column_ranks_); vars.push_back (var); } if (i == ties.size() && !specifications_[i].has_manual_position_ @@ -925,7 +995,8 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const Tie_configuration_variation var; var.index_ = i; var.suggestion_ = get_configuration (specifications_[i].position_ - + 1, UP); + + 1, UP, + specifications_[i].column_ranks_); vars.push_back (var); } } @@ -935,7 +1006,8 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const Tie_configuration_variation var; var.index_ = i; var.suggestion_ = get_configuration (ties[i].position_ + ties[i].dir_, - ties[i].dir_); + ties[i].dir_, + ties[i].column_ranks_); vars.push_back (var); }