X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie-formatting-problem.cc;h=0c3279ce21479b7ed790e16552777c2908c40071;hb=e90f0536f9be39ada0bef0aeb0d275dec3b2fb5b;hp=f7682c904c56db5af97bcd4c9c3f0c240e6a7b84;hpb=d2300573cae3c1920400d040faddd33f17b43c2d;p=lilypond.git diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index f7682c904c..0c3279ce21 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -1,22 +1,35 @@ /* - tie-formatting-problem.cc -- implement Tie_formatting_problem + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2005--2011 Han-Wen Nienhuys - (c) 2005--2007 Han-Wen Nienhuys + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ +#include #include "tie-formatting-problem.hh" +#include "axis-group-interface.hh" #include "paper-column.hh" -#include "bezier.hh" +#include "bezier.hh" #include "directional-element-interface.hh" #include "libc-extension.hh" #include "misc.hh" #include "note-head.hh" #include "rhythmic-head.hh" -#include "spanner.hh" +#include "spanner.hh" #include "staff-symbol-referencer.hh" #include "stem.hh" #include "tie-configuration.hh" @@ -61,6 +74,8 @@ Tie_formatting_problem::get_attachment (Real y, Drul_array columns) const Tie_formatting_problem::Tie_formatting_problem () { x_refpoint_ = 0; + y_refpoint_ = 0; + use_horizontal_spacing_ = true; } Tie_formatting_problem::~Tie_formatting_problem () @@ -123,16 +138,23 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, { 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; - Real stem_end_position = - Stem::is_cross_staff (stem) - ? get_grob_direction (stem) * infinity_f - : Stem::stem_end_position (stem) * staff_space * .5; + Real stem_end_position = 0.0; + if (Stem::is_cross_staff (stem)) + stem_end_position = get_grob_direction (stem) * infinity_f; + else + { + if (use_horizontal_spacing_ || !Stem::get_beam (stem)) + stem_end_position = Stem::stem_end_position (stem) * staff_space * .5; + else + stem_end_position = Stem::note_head_positions (stem)[get_grob_direction (stem)] + * staff_space * .5; + } + y.add_point (stem_end_position); Direction stemdir = get_grob_direction (stem); @@ -163,6 +185,7 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, Real x_center = head->extent (x_refpoint_, X_AXIS).center (); Interval x_ext; x_ext[-dir] = x_center; + x_ext[dir] = infinity_f * dir; Interval y_ext; for (vsize j = 0; j < head_boxes.size (); j++) y_ext.unite (head_boxes[j][Y_AXIS]); @@ -185,6 +208,9 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, } Grob *acc = unsmob_grob (heads[i]->get_object ("accidental-grob")); + if (acc) + acc->get_property ("stencil"); /* trigger tie-related suicide */ + if (acc && acc->is_live () && dir == RIGHT) { boxes.push_back (Box (acc->extent (x_refpoint_, X_AXIS), @@ -219,9 +245,11 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, 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); + Interval iv (Axis_group_interface::staff_extent (bounds[0], x_refpoint_, X_AXIS, y_refpoint_, Y_AXIS)); + if (iv.is_empty ()) + iv.add_point (bounds[0]->relative_coordinate (x_refpoint_, X_AXIS)); + + chord_outlines_[key].set_minimum_height (iv[-dir]); } else { @@ -291,10 +319,20 @@ Tie_formatting_problem::from_ties (vector const &ties) return; x_refpoint_ = ties[0]; + y_refpoint_ = ties[0]; for (vsize i = 0; i < ties.size (); i++) { - x_refpoint_ = dynamic_cast (ties[i])->get_bound (LEFT)->common_refpoint (x_refpoint_, X_AXIS); - x_refpoint_ = dynamic_cast (ties[i])->get_bound (RIGHT)->common_refpoint (x_refpoint_, X_AXIS); + Spanner *tie = dynamic_cast (ties[i]); + Item *l = tie->get_bound (LEFT); + Item *r = tie->get_bound (RIGHT); + + x_refpoint_ = l->common_refpoint (x_refpoint_, X_AXIS); + x_refpoint_ = r->common_refpoint (x_refpoint_, X_AXIS); + + if (!l->break_status_dir ()) + y_refpoint_ = l->common_refpoint (y_refpoint_, Y_AXIS); + if (!r->break_status_dir ()) + y_refpoint_ = r->common_refpoint (y_refpoint_, Y_AXIS); } details_.from_grob (ties[0]); @@ -308,18 +346,9 @@ Tie_formatting_problem::from_ties (vector const &ties) { Item *it = dynamic_cast (ties[i])->get_bound (d); 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; + it = it->get_column (); - bounds.push_back (it); - } - else - { - bounds.push_back (it); - } + bounds.push_back (it); } set_chord_outline (bounds, d); @@ -347,7 +376,8 @@ Tie_formatting_problem::from_semi_ties (vector const &semi_ties, Directio { if (semi_ties.empty ()) return; - + + use_horizontal_spacing_ = false; details_.from_grob (semi_ties[0]); vector heads; @@ -374,11 +404,19 @@ Tie_formatting_problem::from_semi_ties (vector const &semi_ties, Directio specifications_.push_back (spec); } - x_refpoint_ = semi_ties [0]; + x_refpoint_ = semi_ties[0]; + y_refpoint_ = semi_ties[0]; + for (vsize i = 0; i < semi_ties.size (); i++) - x_refpoint_ = semi_ties[i]->common_refpoint (x_refpoint_, X_AXIS); + { + x_refpoint_ = semi_ties[i]->common_refpoint (x_refpoint_, X_AXIS); + y_refpoint_ = semi_ties[i]->common_refpoint (y_refpoint_, Y_AXIS); + } for (vsize i = 0; i < heads.size (); i++) - x_refpoint_ = heads[i]->common_refpoint (x_refpoint_, X_AXIS); + { + x_refpoint_ = heads[i]->common_refpoint (x_refpoint_, X_AXIS); + y_refpoint_ = heads[i]->common_refpoint (y_refpoint_, Y_AXIS) ; + } set_chord_outline (heads, head_dir); @@ -650,8 +688,6 @@ Tie_formatting_problem::score_aptitude (Tie_configuration *conf, if (!tie_position_dir_ok) ties_conf->add_score (details_.same_dir_as_stem_penalty_, "tie/pos dir"); } - while (flip (&d) != LEFT); - return penalty; } @@ -683,9 +719,10 @@ Tie_formatting_problem::score_configuration (Tie_configuration *conf) const Real length = conf->attachment_x_.length (); + Real length_penalty + = peak_around (0.33 * details_.min_length_, details_.min_length_, length); conf->add_score (details_.min_length_penalty_factor_ - * peak_around (0.33 * details_.min_length_, details_.min_length_, length), - "minlength"); + * length_penalty, "minlength"); Real tip_pos = conf->position_ + conf->delta_y_ / 0.5 * details_.staff_space_; Real tip_y = tip_pos * details_.staff_space_ * 0.5; @@ -828,6 +865,7 @@ Tie_formatting_problem::score_ties_configuration (Ties_configuration *ties) cons "pos symmetry"); } } + /* Generate with correct X-attachments and beziers, copying delta_y_ from TIES_CONFIG if necessary. @@ -901,7 +939,8 @@ Tie_formatting_problem::find_best_variation (Ties_configuration const &base, for (vsize i = 0; i < vars.size (); i++) { Ties_configuration variant (base); - variant[vars[i].index_] = *vars[i].suggestion_; + for (vsize j = 0; j < vars[i].index_suggestion_pairs_.size(); j++) + variant[vars[i].index_suggestion_pairs_[j].first] = *vars[i].index_suggestion_pairs_[j].second; variant.reset_score (); score_ties (&variant); @@ -951,7 +990,8 @@ Tie_formatting_problem::set_ties_config_standard_directions (Ties_configuration tie_configs->at (0).dir_ = Direction (sign (tie_configs->at (0).position_)); if (!tie_configs->at (0).dir_) - tie_configs->at (0).dir_ = DOWN; + tie_configs->at (0).dir_ + = (tie_configs->size() > 1) ? DOWN : details_.neutral_direction_; } if (!tie_configs->back ().dir_) @@ -998,33 +1038,38 @@ Tie_formatting_problem::set_ties_config_standard_directions (Ties_configuration } } -Tie_configuration_variation::Tie_configuration_variation () -{ - index_ = 0; - suggestion_ = 0; -} - vector Tie_formatting_problem::generate_extremal_tie_variations (Ties_configuration const &ties) const { vector vars; - Direction d = DOWN; - do + Direction d = DOWN; + for (int i = 1; i <= details_.multi_tie_region_size_; i++) { - if (boundary (ties, d, 0).dir_ == d - && !boundary (specifications_, d, 0).has_manual_position_) - for (int i = 1; i <= details_.multi_tie_region_size_; i++) - { - Tie_configuration_variation var; - 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_, - true); - vars.push_back (var); - } + Drul_array configs (0, 0); + do + { + const Tie_configuration &config = boundary (ties, d, 0); + if (config.dir_ == d + && !boundary (specifications_, d, 0).has_manual_position_) + { + Tie_configuration_variation var; + configs[d] = get_configuration (config.position_ + d * i, d, + config.column_ranks_, + true); + var.add_suggestion((d == DOWN) ? 0 : ties.size () - 1, + configs[d]); + vars.push_back (var); + } + } + while (flip (&d) != DOWN); + if (configs[LEFT] && configs[RIGHT]) + { + Tie_configuration_variation var; + var.add_suggestion(0, configs[DOWN]); + var.add_suggestion(ties.size() - 1, configs[UP]); + vars.push_back (var); + } } - while (flip (&d) != DOWN); return vars; } @@ -1052,10 +1097,10 @@ Tie_formatting_problem::generate_single_tie_variations (Ties_configuration const || 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_); + var.add_suggestion(0, + get_configuration (p, + d, specifications_[0].column_ranks_, + !specifications_[0].has_manual_delta_y_)); vars.push_back (var); } } @@ -1085,14 +1130,14 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const if (!specifications_[i].has_manual_dir_) { Tie_configuration_variation var; - var.index_ = i; - var.suggestion_ = get_configuration (specifications_[i].position_ + var.add_suggestion(i, + get_configuration (specifications_[i].position_ - ties[i].dir_, - ties[i].dir_, ties[i].column_ranks_, !specifications_[i].has_manual_delta_y_ - ); + )); vars.push_back (var); } @@ -1100,13 +1145,12 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const if (!specifications_[i-1].has_manual_dir_) { Tie_configuration_variation var; - var.index_ = i-1; - var.suggestion_ = get_configuration (specifications_[i-1].position_ - - ties[i-1].dir_, - - ties[i-1].dir_, - specifications_[i-1].column_ranks_, - !specifications_[i-1].has_manual_delta_y_ - ); + var.add_suggestion(i-1, + get_configuration (specifications_[i-1].position_ + - ties[i-1].dir_, + - ties[i-1].dir_, + specifications_[i-1].column_ranks_, + !specifications_[i-1].has_manual_delta_y_)); vars.push_back (var); } @@ -1115,24 +1159,23 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const && ties[i-1].dir_ == DOWN) { 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].has_manual_delta_y_ - - ); + var.add_suggestion(i-1, + get_configuration (specifications_[i-1].position_ - 1, DOWN, + 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_ && ties[i].dir_ == UP) { Tie_configuration_variation var; - var.index_ = i; - var.suggestion_ = get_configuration (specifications_[i].position_ - + 1, UP, - specifications_[i].column_ranks_, - !specifications_[i].has_manual_delta_y_ - ); + var.add_suggestion(i, + get_configuration (specifications_[i].position_ + + 1, UP, + specifications_[i].column_ranks_, + !specifications_[i].has_manual_delta_y_ + )); vars.push_back (var); } } @@ -1140,12 +1183,12 @@ Tie_formatting_problem::generate_collision_variations (Ties_configuration const && !specifications_[i].has_manual_position_) { Tie_configuration_variation var; - var.index_ = i; - var.suggestion_ = get_configuration (ties[i].position_ + ties[i].dir_, - ties[i].dir_, - ties[i].column_ranks_, - !specifications_[i].has_manual_delta_y_ - ); + var.add_suggestion(i, + get_configuration (ties[i].position_ + ties[i].dir_, + ties[i].dir_, + ties[i].column_ranks_, + !specifications_[i].has_manual_delta_y_ + )); vars.push_back (var); } @@ -1198,7 +1241,7 @@ Tie_formatting_problem::set_debug_scoring (Ties_configuration const &base) for (vsize i = 0; i < base.size (); i++) { string card = base.complete_tie_card (i); - specifications_[i].tie_grob_->set_property ("quant-score", + specifications_[i].tie_grob_->set_property ("annotation", ly_string2scm (card)); } }