X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie-formatting-problem.cc;h=6c7e2a024f091d0f5af9adae860c0a790b1cb80c;hb=87eedcd59f4082cb0841528ad5bc82cb1d1191e3;hp=527091267f9d2bbf31bb9568af3a948b81a4fd8f;hpb=03ce3667568361ee7433032988a4089c64de2ec7;p=lilypond.git diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index 527091267f..6c7e2a024f 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 2005--2006 Han-Wen Nienhuys + (c) 2005--2007 Han-Wen Nienhuys */ @@ -22,7 +22,8 @@ #include "tie-configuration.hh" #include "tie.hh" #include "warn.hh" - +#include "pointer-group-interface.hh" +#include "output-def.hh" void Tie_formatting_problem::print_ties_configuration (Ties_configuration const *ties) @@ -103,6 +104,9 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, Interval x = dots->extent (x_refpoint_, X_AXIS); int p = int (Staff_symbol_referencer::get_position (dots)); + /* + TODO: shouldn't this use column-rank dependent key? + */ dot_positions_.insert (p); dot_x_.unite (x); @@ -115,45 +119,76 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, Tuple2 key (column_rank, int (dir)); - if (stem - && !Stem::is_invisible (stem)) + if (stem) { - Interval x; - x.add_point (stem->relative_coordinate (x_refpoint_, X_AXIS)); - x.widen (staff_space / 20); // ugh. - Interval y; - y.add_point (Stem::stem_end_position (stem) * staff_space * .5); - - Direction stemdir = get_grob_direction (stem); - y.add_point (Stem::head_positions (stem)[-stemdir] - * staff_space * .5); - - boxes.push_back (Box (x, y)); + if (Stem::is_normal_stem (stem)) + { + + Interval x; + x.add_point (stem->relative_coordinate (x_refpoint_, X_AXIS)); + x.widen (staff_space / 20); // ugh. + Interval y; + y.add_point (Stem::stem_end_position (stem) * staff_space * .5); + + Direction stemdir = get_grob_direction (stem); + y.add_point (Stem::head_positions (stem)[-stemdir] + * staff_space * .5); + + /* + add extents of stem. + */ + boxes.push_back (Box (x, y)); - stem_extents_[key].unite (Box (x,y)); + stem_extents_[key].unite (Box (x,y)); - if (dir == LEFT) + if (dir == LEFT) + { + Box flag_box = Stem::get_translated_flag (stem).extent_box (); + flag_box.translate( Offset (x[RIGHT], X_AXIS)); + boxes.push_back (flag_box); + } + } + else { - Box flag_box = Stem::get_translated_flag (stem).extent_box (); - flag_box.translate( Offset (x[RIGHT], X_AXIS)); - boxes.push_back (flag_box); + Grob *head = Stem::support_head (stem); + + /* + In case of invisible stem, don't pass x-center of heads. + */ + Real x_center = head->extent (x_refpoint_, X_AXIS).center (); + Interval x_ext; + x_ext[-dir] = x_center; + Interval y_ext; + for (vsize j = 0; j < head_boxes.size (); j++) + y_ext.unite (head_boxes[j][Y_AXIS]); + + boxes.push_back (Box (x_ext, y_ext)); } - } - else if (stem) - { - Grob *head = Stem::support_head (stem); - /* - In case of invisible stem, don't pass x-center of heads. - */ - Real x_center = head->extent (x_refpoint_, X_AXIS).center (); - Interval x_ext; - x_ext[-dir] = x_center; - Interval y_ext; - for (vsize j = 0; j < head_boxes.size (); j++) - y_ext.unite (head_boxes[j][Y_AXIS]); + extract_grob_set (stem, "note-heads", heads); + for (vsize i = 0; i < heads.size(); i ++) + { + if (find (bounds.begin(), bounds.end (), dynamic_cast (heads[i])) == bounds.end ()) + { + /* + other untied notes in the same chord. + */ + + Interval y = Staff_symbol_referencer::extent_in_staff (heads[i]); + Interval x = heads[i]->extent (x_refpoint_, X_AXIS); + boxes.push_back (Box (x, y)); + } + + Grob *acc = unsmob_grob (heads[i]->get_object ("accidental-grob")); + if (acc && acc->is_live () && dir == RIGHT) + { + boxes.push_back (Box (acc->extent (x_refpoint_, X_AXIS), + Staff_symbol_referencer::extent_in_staff (acc))); + } - boxes.push_back (Box (x_ext, y_ext)); + head_positions_[column_rank].add_point (int (Staff_symbol_referencer::get_position (heads[i]))); + } + } Direction updowndir = DOWN; @@ -176,10 +211,11 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, while (flip (&updowndir) != DOWN); /* todo: the horizon_padding is somewhat arbitrary */ - chord_outlines_[key] = Skyline (boxes, 0.1, Y_AXIS, -dir); + chord_outlines_[key] = Skyline (boxes, details_.skyline_padding_, 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 @@ -266,8 +302,19 @@ Tie_formatting_problem::from_ties (vector const &ties) for (vsize i = 0; i < ties.size (); i++) { Item *it = dynamic_cast (ties[i])->get_bound (d); - - bounds.push_back (it); + if (it->break_status_dir ()) + { + Item *sep + = dynamic_cast (unsmob_grob (ties[i]->get_object ("separation-item"))); + if (sep && sep->get_column () == it->get_column ()) + it = sep; + + bounds.push_back (it); + } + else + { + bounds.push_back (it); + } } set_chord_outline (bounds, d); @@ -278,16 +325,12 @@ 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]); - - + spec.from_grob (ties[i]); 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 (); + spec.column_ranks_[d] = Tie::get_column_rank (ties[i], d); } while (flip (&d) != LEFT); specifications_.push_back (spec); @@ -317,10 +360,10 @@ Tie_formatting_problem::from_semi_ties (vector const &semi_ties, Directio spec.position_ = int (Staff_symbol_referencer::get_position (head)); } - spec.get_tie_manual_settings (semi_ties[i]); + spec.from_grob (semi_ties[i]); spec.note_head_drul_[head_dir] = head; - column_rank = dynamic_cast (head)->get_column ()->get_rank (); + column_rank = Tie::get_column_rank (semi_ties[i], head_dir); spec.column_ranks_ = Drul_array (column_rank, column_rank); heads.push_back (head); specifications_.push_back (spec); @@ -354,7 +397,8 @@ 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, Drul_array columns) const +Tie_formatting_problem::get_configuration (int pos, Direction dir, Drul_array columns, + bool tune_dy) const { int key_components[] = { pos, dir, columns[LEFT], columns[RIGHT] @@ -368,14 +412,14 @@ Tie_formatting_problem::get_configuration (int pos, Direction dir, Drul_arraypossibilities_[key] = conf; return conf; } Tie_configuration* Tie_formatting_problem::generate_configuration (int pos, Direction dir, - Drul_array columns) const + Drul_array columns, bool y_tune) const { Tie_configuration *conf = new Tie_configuration; conf->position_ = pos; @@ -385,7 +429,6 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir, 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_; @@ -416,37 +459,41 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir, size. */ - if (h < details_.intra_space_threshold_ * 0.5 * details_.staff_space_) + if (head_positions_slice (columns[LEFT]).contains (pos) + || head_positions_slice (columns[RIGHT]).contains (pos) + || abs (pos) < 2 * Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_)) { - if (!Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos) - && abs (pos) < 2 * Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_)) - { - conf->center_tie_vertically (details_); - } - else if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos)) + if (h < details_.intra_space_threshold_ * 0.5 * details_.staff_space_) { - conf->delta_y_ += dir * - details_.tip_staff_line_clearance_ * 0.5 * details_.staff_space_; + if (!Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos) + && abs (pos) < 2 * Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_)) + { + conf->center_tie_vertically (details_); + } + else if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos)) + { + conf->delta_y_ += dir * + details_.tip_staff_line_clearance_ * 0.5 * details_.staff_space_; + } } - } - else - { - Real top_y = y + conf->delta_y_ + conf->dir_ * h; - Real top_pos = top_y / (0.5*details_.staff_space_); - int round_pos = int (my_round (top_pos)); - - /* TODO: should use other variable? */ - Real clearance = details_.center_staff_line_clearance_; - if (fabs (top_pos - round_pos) < clearance - && Staff_symbol_referencer::on_staff_line (details_.staff_symbol_referencer_, - round_pos)) + else { - Real new_y = (round_pos + clearance * conf->dir_) * 0.5 * details_.staff_space_; - conf->delta_y_ = (new_y - top_y); + Real top_y = y + conf->delta_y_ + conf->dir_ * h; + Real top_pos = top_y / (0.5*details_.staff_space_); + int round_pos = int (my_round (top_pos)); + + /* TODO: should use other variable? */ + Real clearance = details_.center_staff_line_clearance_; + if (fabs (top_pos - round_pos) < clearance + && Staff_symbol_referencer::on_staff_line (details_.staff_symbol_referencer_, + round_pos)) + { + Real new_y = (round_pos + clearance * conf->dir_) * 0.5 * details_.staff_space_; + conf->delta_y_ = (new_y - top_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_) { @@ -532,7 +579,8 @@ Tie_formatting_problem::score_aptitude (Tie_configuration *conf, } { - Real p = details_.vertical_distance_penalty_factor_ * fabs (curve_y - tie_y); + Real relevant_dist = max (fabs (curve_y - tie_y) - 0.5, 0.0); + Real p = details_.vertical_distance_penalty_factor_ * convex_amplifier (1.0, 0.9, relevant_dist); if (ties_conf) ties_conf->add_tie_score (p, tie_idx, "vdist"); else @@ -547,22 +595,79 @@ Tie_formatting_problem::score_aptitude (Tie_configuration *conf, Interval head_x = spec.note_head_drul_[d]->extent (x_refpoint_, X_AXIS); Real dist = head_x.distance (conf->attachment_x_[d]); + /* TODO: flatten with log or sqrt. */ - Real p = details_.horizontal_distance_penalty_factor_ * dist; + Real p = details_.horizontal_distance_penalty_factor_ + * convex_amplifier (1.25, 1.0, dist); if (ties_conf) ties_conf->add_tie_score (p, tie_idx, (d == LEFT) ? "lhdist" : "rhdist"); else penalty += p; + } while (flip (&d) != LEFT); + if (ties_conf + && ties_conf->size() == 1) + { + Direction d = LEFT; + Drul_array stems (0, 0); + do + { + if (!spec.note_head_drul_[d]) + continue; + + Grob *stem = unsmob_grob (spec.note_head_drul_[d]->get_object ("stem")); + if (stem + && Stem::is_normal_stem (stem)) + stems[d] = stem; + } + while (flip (&d) != LEFT); + + bool tie_stem_dir_ok = true; + bool tie_position_dir_ok = true; + if (stems[LEFT] && !stems[RIGHT]) + tie_stem_dir_ok = conf->dir_ != get_grob_direction (stems[LEFT]); + else if (!stems[LEFT] && stems[RIGHT]) + tie_stem_dir_ok = conf->dir_ != get_grob_direction (stems[RIGHT]); + else if (stems[LEFT] && stems[RIGHT] + && get_grob_direction (stems[LEFT]) == get_grob_direction (stems[RIGHT])) + tie_stem_dir_ok = conf->dir_ != get_grob_direction (stems[LEFT]); + else if (spec.position_) + tie_position_dir_ok = conf->dir_ == sign (spec.position_); + + if (!tie_stem_dir_ok) + ties_conf->add_score (details_.same_dir_as_stem_penalty_, "tie/stem dir"); + if (!tie_position_dir_ok) + ties_conf->add_score (details_.same_dir_as_stem_penalty_, "tie/pos dir"); + } + while (flip (&d) != LEFT); + + return penalty; } + +Slice +Tie_formatting_problem::head_positions_slice (int rank) const +{ + Position_extent_map::const_iterator i (head_positions_.find (rank)); + if (i != head_positions_.end ()) + { + return (*i).second; + } + Slice empty; + return empty; +} + +/* + Score a configuration, ie. how well these ties looks without regard + to the note heads that they should connect to. + */ void Tie_formatting_problem::score_configuration (Tie_configuration *conf) const { @@ -591,13 +696,17 @@ Tie_formatting_problem::score_configuration (Tie_configuration *conf) const conf->add_score ( details_.staff_line_collision_penalty_ * peak_around (0.1 * details_.center_staff_line_clearance_, - details_.center_staff_line_clearance_, + details_.center_staff_line_clearance_, fabs (top_pos - round_top_pos)), "line center"); } - - if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, - int (rint (tip_pos)))) + + int rounded_tip_pos = int (rint (tip_pos)); + if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, rounded_tip_pos) + && (head_positions_slice (conf->column_ranks_[LEFT]).contains (rounded_tip_pos) + || head_positions_slice (conf->column_ranks_[RIGHT]).contains (rounded_tip_pos) + || abs (rounded_tip_pos) < 2 * Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_)) + ) { conf->add_score (details_.staff_line_collision_penalty_ * peak_around (0.1 * details_.tip_staff_line_clearance_, @@ -632,96 +741,6 @@ Tie_formatting_problem::score_configuration (Tie_configuration *conf) const conf->scored_ = true; } -Tie_configuration -Tie_formatting_problem::find_optimal_tie_configuration (Tie_specification const &spec) const -{ - vector confs; - - int pos = spec.position_; - Direction dir = spec.manual_dir_; - - for (int i = 0; i < details_.single_tie_region_size_; i ++) - { - confs.push_back (generate_configuration (pos + i * dir, dir, - spec.column_ranks_)); - - if (spec.has_manual_position_) - { - confs.back ()->delta_y_ - = (spec.manual_position_ - spec.position_) - * 0.5 * details_.staff_space_; - - break; - } - } - - vector scores; - - int best_idx = -1; - Real best_score = 1e6; - for (vsize i = 0; i < confs.size (); i ++) - { - score_configuration (confs[i]); - Real score = score_aptitude (confs[i], spec, 0, 0) - + confs[i]->score (); - - if (score < best_score) - { - best_score = score; - best_idx = i; - } - } - - 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]; - - return best; -} - -Tie_specification::Tie_specification () -{ - has_manual_position_ = false; - has_manual_dir_ = false; - position_ = 0; - manual_position_ = 0; - manual_dir_ = CENTER; - note_head_drul_[LEFT] = - note_head_drul_[RIGHT] = 0; - column_ranks_[RIGHT] = - 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 -{ - return column_ranks_[RIGHT] - column_ranks_[LEFT]; -} - void Tie_formatting_problem::score_ties_aptitude (Ties_configuration *ties) const { @@ -787,21 +806,23 @@ Tie_formatting_problem::score_ties_configuration (Ties_configuration *ties) cons last_center = center; } - ties->add_score (details_.outer_tie_length_symmetry_penalty_factor_ - * fabs (ties->at (0).attachment_x_.length () - ties->back ().attachment_x_.length ()), - "length symm"); + if (ties->size () > 1) + { + ties->add_score (details_.outer_tie_length_symmetry_penalty_factor_ + * fabs (ties->at (0).attachment_x_.length () - ties->back ().attachment_x_.length ()), + "length symm"); - ties->add_score (details_.outer_tie_vertical_distance_symmetry_penalty_factor_ - * fabs (fabs (specifications_[0].position_ * 0.5 * details_.staff_space_ - - (ties->at (0).position_ * 0.5 * details_.staff_space_ - + ties->at (0).delta_y_)) - - - fabs (specifications_.back ().position_ * 0.5 * details_.staff_space_ - - (ties->back ().position_ * 0.5 * details_.staff_space_ - + ties->back ().delta_y_))), - "pos symmetry"); + ties->add_score (details_.outer_tie_vertical_distance_symmetry_penalty_factor_ + * fabs (fabs (specifications_[0].position_ * 0.5 * details_.staff_space_ + - (ties->at (0).position_ * 0.5 * details_.staff_space_ + + ties->at (0).delta_y_)) + - + fabs (specifications_.back ().position_ * 0.5 * details_.staff_space_ + - (ties->back ().position_ * 0.5 * details_.staff_space_ + + ties->back ().delta_y_))), + "pos symmetry"); + } } - /* Generate with correct X-attachments and beziers, copying delta_y_ from TIES_CONFIG if necessary. @@ -813,8 +834,9 @@ Tie_formatting_problem::generate_ties_configuration (Ties_configuration const &t for (vsize i = 0; i < ties_config.size (); i++) { Tie_configuration * ptr = get_configuration (ties_config[i].position_, ties_config[i].dir_, - ties_config[i].column_ranks_); - if (specifications_[i].has_manual_position_) + ties_config[i].column_ranks_, + !specifications_[i].has_manual_delta_y_); + if (specifications_[i].has_manual_delta_y_) { ptr->delta_y_ = (specifications_[i].manual_position_ - ties_config[i].position_) @@ -838,8 +860,9 @@ Tie_formatting_problem::generate_base_chord_configuration () if (specifications_[i].has_manual_position_) { conf.position_ = (int) my_round (specifications_[i].manual_position_); - conf.delta_y_ = (specifications_[i].manual_position_ - conf.position_) - * 0.5 * details_.staff_space_; + if (specifications_[i].has_manual_delta_y_) + conf.delta_y_ = (specifications_[i].manual_position_ - conf.position_) + * 0.5 * details_.staff_space_; } else { @@ -862,7 +885,7 @@ Tie_formatting_problem::generate_base_chord_configuration () Ties_configuration Tie_formatting_problem::find_best_variation (Ties_configuration const &base, - vector vars) + vector const &vars) { Ties_configuration best = base; @@ -890,16 +913,24 @@ Tie_formatting_problem::find_best_variation (Ties_configuration const &base, Ties_configuration -Tie_formatting_problem::generate_optimal_chord_configuration () +Tie_formatting_problem::generate_optimal_configuration () { Ties_configuration base = generate_base_chord_configuration (); - vector vars = generate_collision_variations (base); - score_ties (&base); + + vector vars; + if (specifications_.size () > 1) + vars = generate_collision_variations (base); + else + vars = generate_single_tie_variations (base); + Ties_configuration best = find_best_variation (base, vars); - vars = generate_extremal_tie_variations (best); - best = find_best_variation (best, vars); + if (specifications_.size () > 1) + { + vars = generate_extremal_tie_variations (best); + best = find_best_variation (best, vars); + } return best; } @@ -947,7 +978,7 @@ Tie_formatting_problem::set_ties_config_standard_directions (Ties_configuration } } - for (vsize i = 1; i < tie_configs->size() - 1; i++) + for (vsize i = 1; i + 1 < tie_configs->size (); i++) { Tie_configuration &conf = tie_configs->at (i); if (conf.dir_) @@ -983,7 +1014,8 @@ Tie_formatting_problem::generate_extremal_tie_variations (Ties_configuration con var.index_ = (d == DOWN) ? 0 : ties.size () - 1; var.suggestion_ = get_configuration (boundary (ties, d, 0).position_ + d * i, d, - boundary (ties, d, 0).column_ranks_); + boundary (ties, d, 0).column_ranks_, + true); vars.push_back (var); } } @@ -992,6 +1024,41 @@ Tie_formatting_problem::generate_extremal_tie_variations (Ties_configuration con return vars; } +vector +Tie_formatting_problem::generate_single_tie_variations (Ties_configuration const &ties) const +{ + vector vars; + + int sz = details_.single_tie_region_size_; + if (specifications_[0].has_manual_position_) + sz = 1; + for (int i = 0; i < sz; i ++) + { + Direction d = LEFT; + do + { + if (i == 0 + && ties[0].dir_ == d) + continue; + + int p = ties[0].position_ + i * d; + + if (!specifications_[0].has_manual_dir_ + || d == specifications_[0].manual_dir_) + { + Tie_configuration_variation var; + var.index_ = 0; + var.suggestion_ = get_configuration (p, + d, specifications_[0].column_ranks_, + !specifications_[0].has_manual_delta_y_); + vars.push_back (var); + } + } + while (flip (&d) != LEFT); + } + return vars; +} + vector Tie_formatting_problem::generate_collision_variations (Ties_configuration const &ties) const @@ -1018,7 +1085,8 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const - ties[i].dir_, - ties[i].dir_, - ties[i].column_ranks_ + ties[i].column_ranks_, + !specifications_[i].has_manual_delta_y_ ); vars.push_back (var); @@ -1031,7 +1099,9 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const var.suggestion_ = get_configuration (specifications_[i-1].position_ - ties[i-1].dir_, - ties[i-1].dir_, - specifications_[i-1].column_ranks_); + specifications_[i-1].column_ranks_, + !specifications_[i-1].has_manual_delta_y_ + ); vars.push_back (var); } @@ -1042,7 +1112,10 @@ 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, - specifications_[i-1].column_ranks_); + specifications_[i-1].column_ranks_, + !specifications_[i-1].has_manual_delta_y_ + + ); vars.push_back (var); } if (i == ties.size() && !specifications_[i].has_manual_position_ @@ -1052,7 +1125,9 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const var.index_ = i; var.suggestion_ = get_configuration (specifications_[i].position_ + 1, UP, - specifications_[i].column_ranks_); + specifications_[i].column_ranks_, + !specifications_[i].has_manual_delta_y_ + ); vars.push_back (var); } } @@ -1063,7 +1138,9 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const var.index_ = i; var.suggestion_ = get_configuration (ties[i].position_ + ties[i].dir_, ties[i].dir_, - ties[i].column_ranks_); + ties[i].column_ranks_, + !specifications_[i].has_manual_delta_y_ + ); vars.push_back (var); } @@ -1092,7 +1169,9 @@ Tie_formatting_problem::set_manual_tie_configuration (SCM manual_configs) { spec.has_manual_position_ = true; spec.manual_position_ = scm_to_double (scm_car (entry)); + spec.has_manual_delta_y_ = (scm_inexact_p (scm_car (entry)) == SCM_BOOL_T); } + if (scm_is_number (scm_cdr (entry))) { spec.has_manual_dir_ = true; @@ -1103,3 +1182,20 @@ Tie_formatting_problem::set_manual_tie_configuration (SCM manual_configs) } } + +void +Tie_formatting_problem::set_debug_scoring (Ties_configuration const &base) +{ +#if DEBUG_TIE_SCORING + if (to_boolean (x_refpoint_->layout () + ->lookup_variable (ly_symbol2scm ("debug-tie-scoring")))) + { + for (vsize i = 0; i < base.size(); i++) + { + string card = base.complete_tie_card (i); + specifications_[i].tie_grob_->set_property ("quant-score", + ly_string2scm (card)); + } + } +#endif +}