From ff95ccbbb814e6ccd108426afcbc9e14723ffb7f Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 14 Nov 2005 21:50:35 +0000 Subject: [PATCH] * lily/include/tie-formatting-problem.hh (class Tie_formatting_problem): new file. * lily/tie-formatting-problem.cc (common_x_refpoint): new file. --- lily/include/lily-proto.hh | 2 + lily/include/tie-column-format.hh | 8 +- lily/include/tie-formatting-problem.hh | 34 ++++ lily/include/tie.hh | 33 ++-- lily/laissez-vibrer-tie-column.cc | 45 ++--- lily/tie-column-format.cc | 185 +++---------------- lily/tie-column.cc | 46 ++--- lily/tie-formatting-problem.cc | 243 +++++++++++++++++++++++++ lily/tie.cc | 104 +++++------ 9 files changed, 401 insertions(+), 299 deletions(-) create mode 100644 lily/include/tie-formatting-problem.hh create mode 100644 lily/tie-formatting-problem.cc diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index bd3e5e83dd..b0f413fb78 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -160,6 +160,8 @@ class Tex_font_metric; class Tie; class Tie_details; class Tie_configuration; +class Tie_formatting_problem; +class Ties_configuration; class Tie_performer; class Time_scaled_music; class Time_scaled_music_iterator; diff --git a/lily/include/tie-column-format.hh b/lily/include/tie-column-format.hh index 5f0c438e68..500ac5882a 100644 --- a/lily/include/tie-column-format.hh +++ b/lily/include/tie-column-format.hh @@ -16,12 +16,12 @@ void set_chord_outline (Array *skyline, Link_array bounds, Grob *common, Direction d); -void set_tie_config_directions (Array *tie_configs_ptr); -void shift_small_ties (Array *tie_configs, +void set_tie_config_directions (Ties_configuration *tie_configs_ptr); +void shift_small_ties (Ties_configuration *tie_configs, Grob *staff_referencer, Tie_details const &details); void final_shape_adjustment (Tie_configuration &conf, - Drul_array< Array > const &skylines, + Tie_formatting_problem const&, Grob *staff_referencer, Tie_details const &details); void @@ -30,7 +30,7 @@ set_chord_outlines (Drul_array< Array > *skyline_drul, Grob *common); void -set_manual_tie_configuration (Array *tie_configs, +set_manual_tie_configuration (Ties_configuration *tie_configs, bool *manual_override, SCM manual_configs ); diff --git a/lily/include/tie-formatting-problem.hh b/lily/include/tie-formatting-problem.hh new file mode 100644 index 0000000000..946e303235 --- /dev/null +++ b/lily/include/tie-formatting-problem.hh @@ -0,0 +1,34 @@ +/* + tie-formatting-problem.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys + +*/ + +#ifndef TIE_FORMATTING_PROBLEM_HH +#define TIE_FORMATTING_PROBLEM_HH + +#include "drul-array.hh" +#include "parray.hh" +#include "skyline.hh" +#include "lily-proto.hh" + +class Tie_formatting_problem +{ + Drul_array< Array > chord_outlines_; + Grob *x_refpoint_; +public: + Tie_formatting_problem (); + + void from_ties (Link_array const &ties); + void from_tie (Grob *tie); + void from_lv_ties (Link_array const &); + void set_chord_outline (Link_array, Direction); + + Interval get_attachment (Real) const; + Grob *common_x_refpoint () const; +}; + +#endif /* TIE_FORMATTING_PROBLEM_HH */ diff --git a/lily/include/tie.hh b/lily/include/tie.hh index 16cde3cfca..b5b8fd8eb6 100644 --- a/lily/include/tie.hh +++ b/lily/include/tie.hh @@ -15,10 +15,6 @@ -Interval -get_skyline_attachment (Drul_array< Array < Skyline_entry > > const &skylines, - Real y1); - struct Tie_details { Real height_limit_; @@ -31,14 +27,17 @@ struct Tie_details void init (Grob *); }; -struct Tie_configuration +class Tie_configuration { - int head_position_; +public: int position_; - Direction dir_; - Interval attachment_x_; Real delta_y_; + + + Interval attachment_x_; + Grob *tie_; + int head_position_; Tie_configuration (); void center_tie_vertically (Tie_details const &); @@ -53,6 +52,14 @@ struct Tie_configuration INSTANTIATE_COMPARE (Tie_configuration, Tie_configuration::compare); +class Ties_configuration +{ +public: + Array ties_; + +}; + + class Tie { public: @@ -62,13 +69,13 @@ public: static int get_column_rank (Grob *, Direction); static int get_position (Grob *); static Direction get_default_dir (Grob *); - static void get_configuration (Grob *, Grob *, Tie_configuration *, - Drul_array< Array > const *, + static void get_configuration (Grob *, Tie_configuration *, + Tie_formatting_problem const &, Tie_details const & ); - static void set_control_points (Grob *, Grob *,Tie_configuration const&, - Tie_details const& - ); + static void set_control_points (Grob *, Grob *, + Tie_configuration const&, + Tie_details const&); static void set_default_control_points (Grob *); DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM)); diff --git a/lily/laissez-vibrer-tie-column.cc b/lily/laissez-vibrer-tie-column.cc index 83b14cc3f4..df8cbab09d 100644 --- a/lily/laissez-vibrer-tie-column.cc +++ b/lily/laissez-vibrer-tie-column.cc @@ -17,6 +17,7 @@ #include "staff-symbol-referencer.hh" #include "item.hh" #include "tie-column-format.hh" +#include "tie-formatting-problem.hh" ADD_INTERFACE(Laissez_vibrer_tie_column, @@ -44,52 +45,30 @@ Laissez_vibrer_tie_column::calc_positioning_done (SCM smob) lv_ties.sort (&Laissez_vibrer_tie::compare); - Array tie_configs; - Link_array heads; + Ties_configuration ties_config; for (int i = 0; i < lv_ties.size (); i++) { Tie_configuration conf; conf.dir_ = CENTER; Item *head = unsmob_item (lv_ties[i]->get_object ("note-head")); - heads.push (head); if (head) conf.position_ = (int) Staff_symbol_referencer::get_position (head); - tie_configs.push (conf); + ties_config.ties_.push (conf); } bool manual_override = false; SCM manual_configs = me->get_property ("tie-configuration"); - set_manual_tie_configuration (&tie_configs, + set_manual_tie_configuration (&ties_config, &manual_override, manual_configs ); - set_tie_config_directions (&tie_configs); + set_tie_config_directions (&ties_config); - Grob *common = me; - for (int i = 0; i < lv_ties.size (); i++) - { - common = lv_ties[i]->common_refpoint (common, X_AXIS); - } - - Drul_array< Array > skylines; - set_chord_outline (&skylines[LEFT], - heads, - common, LEFT); - - Real right_most = - infinity_f; - for (int i = 0; i < skylines[LEFT].size (); i++) - { - right_most = max (right_most, skylines[LEFT][i].height_); - } - - Skyline_entry right_entry; - right_entry.width_.set_full (); - right_entry.height_ = right_most + 1.5; - - skylines[RIGHT].push (right_entry); + Tie_formatting_problem problem; + problem.from_lv_ties (lv_ties); Tie_details details; details.init (lv_ties[0]); @@ -99,8 +78,8 @@ Laissez_vibrer_tie_column::calc_positioning_done (SCM smob) */ for (int i = 0; i < lv_ties.size(); i++) { - final_shape_adjustment (tie_configs[i], - skylines, + final_shape_adjustment (ties_config.ties_[i], + problem, lv_ties[0], details); } @@ -110,14 +89,14 @@ Laissez_vibrer_tie_column::calc_positioning_done (SCM smob) */ if (!manual_override) { - shift_small_ties (&tie_configs, lv_ties[0], details); + shift_small_ties (&ties_config, lv_ties[0], details); } for (int i = 0; i < lv_ties.size(); i++) { - Tie::set_control_points (lv_ties[i], common, tie_configs[i], + Tie::set_control_points (lv_ties[i], problem.common_x_refpoint (), ties_config.ties_[i], details ); - set_grob_direction (lv_ties[i], tie_configs[i].dir_); + set_grob_direction (lv_ties[i], ties_config.ties_[i].dir_); } return SCM_BOOL_T; diff --git a/lily/tie-column-format.cc b/lily/tie-column-format.cc index 255899c5d2..ce56cae766 100644 --- a/lily/tie-column-format.cc +++ b/lily/tie-column-format.cc @@ -16,11 +16,12 @@ #include "staff-symbol-referencer.hh" #include "directional-element-interface.hh" #include "rhythmic-head.hh" +#include "tie-formatting-problem.hh" #include void -set_manual_tie_configuration (Array *tie_configs, +set_manual_tie_configuration (Ties_configuration *ties_config, bool *manual_override, SCM manual_configs ) @@ -28,14 +29,14 @@ set_manual_tie_configuration (Array *tie_configs, *manual_override = false; int k = 0; for (SCM s = manual_configs; - scm_is_pair (s) && k < tie_configs->size(); s = scm_cdr (s)) + scm_is_pair (s) && k < ties_config->ties_.size(); s = scm_cdr (s)) { SCM entry = scm_car (s); if (!scm_is_pair (entry)) continue; *manual_override = true; - Tie_configuration &conf = tie_configs->elem_ref (k); + Tie_configuration &conf = ties_config->ties_.elem_ref (k); Real complete_pos = robust_scm2double (scm_car (entry), conf.position_); @@ -49,160 +50,17 @@ set_manual_tie_configuration (Array *tie_configs, } void -set_chord_outline (Array *skyline, - Link_array bounds, - Grob *common, - Direction d) -{ - Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]); - - Array boxes; - - 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 = Staff_symbol_referencer::get_position (head); - 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)); - - Grob *dots = Rhythmic_head::get_dots (head); - if (d == LEFT && dots) - { - Interval x = dots->extent (common, X_AXIS); - Interval y (-0.5, 0.5); - y.translate (Staff_symbol_referencer::get_position (dots)); - y *= staff_space * 0.5; - - boxes.push (Box (x, y)); - } - } - - (*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, - 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 = get_grob_direction (stem); - y.add_point (Stem::head_positions (stem)[-stemdir] - * staff_space * .5); - - 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, 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; - - - Grob *dots = unsmob_grob (bounds[i]->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, - Box (x,y), Y_AXIS, -d); - } - } -} - -void -set_chord_outlines (Drul_array< Array > *skyline_drul, - Link_array ties, - Grob *common) -{ - Direction d = LEFT; - - do - { - Link_array bounds; - - for (int i = 0; i < ties.size (); i++) - { - Item *it = dynamic_cast (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_configs, +shift_small_ties (Ties_configuration *tie_configs, Grob *staff_referencer, Tie_details const &details) { set 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->ties_.size (); i++) + positions_taken.insert (int (rint (tie_configs->ties_.elem (i).position_))); - for (int i = 0; i < tie_configs->size (); i++) + for (int i = 0; i < tie_configs->ties_.size (); i++) { - Tie_configuration * conf = &tie_configs->elem_ref (i); + Tie_configuration * conf = &tie_configs->ties_.elem_ref (i); /* on staff line and small enough, translate a little further @@ -231,7 +89,7 @@ shift_small_ties (Array *tie_configs, void final_shape_adjustment (Tie_configuration &conf, - Drul_array< Array > const &skylines, + Tie_formatting_problem const &problem, Grob *staff_referencer, Tie_details const &details) { @@ -245,9 +103,8 @@ final_shape_adjustment (Tie_configuration &conf, 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.attachment_x_ = problem.get_attachment (y); + conf.attachment_x_.intersect (problem.get_attachment (y + conf.dir_ * details.staff_space_ * 0.5)); conf.delta_y_ += line_dy; conf.attachment_x_.widen (-details.x_gap_); @@ -257,9 +114,9 @@ final_shape_adjustment (Tie_configuration &conf, } void -set_tie_config_directions (Array *tie_configs_ptr) +set_tie_config_directions (Ties_configuration *tie_configs_ptr) { - Array &tie_configs (*tie_configs_ptr); + Array &tie_configs (tie_configs_ptr->ties_); if (!tie_configs[0].dir_) tie_configs[0].dir_ = DOWN; @@ -271,7 +128,9 @@ set_tie_config_directions (Array *tie_configs_ptr) */ for (int i = 1; i < tie_configs.size(); i++) { - Real diff = tie_configs[i-1].position_ - tie_configs[i].position_; + Real diff = tie_configs[i-1].position_ + - tie_configs[i].position_; + if (fabs (diff) <= 1) { if (!tie_configs[i-1].dir_) @@ -283,14 +142,16 @@ set_tie_config_directions (Array *tie_configs_ptr) for (int i = 1; i < tie_configs.size() - 1; i++) { - if (tie_configs[i].dir_) + Tie_configuration &conf = tie_configs.elem_ref (i); + if (conf.dir_) continue; - Direction position_dir = (Direction) sign (tie_configs[i].position_); + Direction position_dir = + Direction (sign (conf.position_)); if (!position_dir) position_dir = DOWN; - - tie_configs[i].dir_ = position_dir; + + conf.dir_ = position_dir; } } diff --git a/lily/tie-column.cc b/lily/tie-column.cc index 9b488a6f74..7a2b878c49 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -18,6 +18,7 @@ #include "tie.hh" #include "directional-element-interface.hh" #include "tie-column-format.hh" +#include "tie-formatting-problem.hh" using namespace std; @@ -82,31 +83,25 @@ Tie_column::calc_positioning_done (SCM smob) ties.sort (&Tie::compare); - Array tie_configs; + Ties_configuration ties_config; for (int i = 0; i < ties.size (); i++) { Tie_configuration conf; - conf.dir_ = get_grob_direction (ties[i]); + if (scm_is_number (ties[i]->get_property_data (ly_symbol2scm ("direction")))) + conf.dir_ = get_grob_direction (ties[i]); conf.position_ = Tie::get_position (ties[i]); - tie_configs.push (conf); + ties_config.ties_.push (conf); } SCM manual_configs = me->get_property ("tie-configuration"); bool manual_override = false; - set_manual_tie_configuration (&tie_configs, + set_manual_tie_configuration (&ties_config, &manual_override, manual_configs); - set_tie_config_directions (&tie_configs); + set_tie_config_directions (&ties_config); - Grob *common = me; - for (int i = 0; i < ties.size (); i++) - { - common = dynamic_cast (ties[i])->get_bound (LEFT)->common_refpoint (common, X_AXIS); - common = dynamic_cast (ties[i])->get_bound (RIGHT)->common_refpoint (common, X_AXIS); - } - - Drul_array< Array > skylines; - set_chord_outlines (&skylines, ties, common); + Tie_formatting_problem problem; + problem.from_ties (ties); Tie_details details; details.init (ties[0]); @@ -116,13 +111,12 @@ Tie_column::calc_positioning_done (SCM smob) */ if (!manual_override) { - Tie::get_configuration (ties[0], common, &tie_configs.elem_ref (0), - &skylines, - details - ); - Tie::get_configuration (ties.top (), common, - &tie_configs.elem_ref (tie_configs.size()-1), - &skylines, + Tie::get_configuration (ties[0], &ties_config.ties_.elem_ref (0), + problem, + details); + Tie::get_configuration (ties.top (), + &ties_config.ties_.elem_ref (ties_config.ties_.size()-1), + problem, details ); } @@ -137,8 +131,8 @@ Tie_column::calc_positioning_done (SCM smob) continue; - final_shape_adjustment (tie_configs[i], - skylines, + final_shape_adjustment (ties_config.ties_[i], + problem, ties[0], details); } @@ -149,15 +143,15 @@ Tie_column::calc_positioning_done (SCM smob) */ if (!manual_override) { - shift_small_ties (&tie_configs, ties[0], details); + shift_small_ties (&ties_config, ties[0], details); } for (int i = 0; i < ties.size(); i++) { - Tie::set_control_points (ties[i], common, tie_configs[i], + Tie::set_control_points (ties[i], problem.common_x_refpoint (), ties_config.ties_[i], details ); - set_grob_direction (ties[i], tie_configs[i].dir_); + set_grob_direction (ties[i], ties_config.ties_[i].dir_); } return SCM_BOOL_T; } diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc new file mode 100644 index 0000000000..f30a197d47 --- /dev/null +++ b/lily/tie-formatting-problem.cc @@ -0,0 +1,243 @@ +/* + tie-formatting-problem.cc -- implement Tie_formatting_problem6 + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys + +*/ + +#include "tie-formatting-problem.hh" + +#include "directional-element-interface.hh" +#include "staff-symbol-referencer.hh" +#include "tie.hh" + +#include "item.hh" +#include "spanner.hh" + +#include "stem.hh" +#include "note-head.hh" +#include "rhythmic-head.hh" + +Interval +Tie_formatting_problem::get_attachment (Real y) const +{ + Interval attachments; + Direction d = LEFT; + do + { + attachments[d] = skyline_height (chord_outlines_[d], y, -d); + } + while (flip (&d) != LEFT); + + return attachments; +} + + + + +Tie_formatting_problem::Tie_formatting_problem() +{ + x_refpoint_ = 0; + +} + +void +Tie_formatting_problem::set_chord_outline (Link_array bounds, + Direction d) +{ + Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]); + + Array boxes; + + 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 = Staff_symbol_referencer::get_position (head); + Interval y ((p-1) * 0.5 * staff_space, + (p+1) * 0.5 * staff_space); + + Interval x = head->extent (x_refpoint_, X_AXIS); + boxes.push (Box (x, y)); + + Grob *dots = Rhythmic_head::get_dots (head); + if (d == LEFT && dots) + { + Interval x = dots->extent (x_refpoint_, X_AXIS); + Interval y (-0.5, 0.5); + y.translate (Staff_symbol_referencer::get_position (dots)); + y *= staff_space * 0.5; + + boxes.push (Box (x, y)); + } + } + + chord_outlines_[d] = empty_skyline (-d); + + if (bounds[0]->break_status_dir ()) + { + Real x = robust_relative_extent (bounds[0], x_refpoint_, X_AXIS)[-d]; + chord_outlines_[d].elem_ref (0).height_ = x; + } + + for (int i = 0; i < boxes.size (); i++) + insert_extent_into_skyline (&chord_outlines_[d] , + boxes[i], Y_AXIS, -d); + + if (stem + && !Stem::is_invisible (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); + + insert_extent_into_skyline (&chord_outlines_[d], 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 (&chord_outlines_[d], 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 (&chord_outlines_[d], + 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; + + + Grob *dots = unsmob_grob (bounds[i]->get_object ("dot")); + if (dots && d == LEFT) + { + Interval x = dots->extent (x_refpoint_, 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 (&chord_outlines_[d], + Box (x,y), Y_AXIS, -d); + } + } +} + + +void +Tie_formatting_problem::from_tie (Grob *tie) +{ + Link_array ties; + ties.push (tie); + + from_ties (ties); +} + +Grob * +Tie_formatting_problem::common_x_refpoint () const +{ + return x_refpoint_; +} + +void +Tie_formatting_problem::from_ties (Link_array const &ties) +{ + if (ties.is_empty ()) + return; + + x_refpoint_ = ties[0]; + for (int 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); + } + + Direction d = LEFT; + do + { + Link_array bounds; + + for (int i = 0; i < ties.size (); i++) + { + Item *it = dynamic_cast (ties[i])->get_bound (d); + + bounds.push (it); + } + + set_chord_outline (bounds, d); + } + while (flip (&d) != LEFT); +} + +void +Tie_formatting_problem::from_lv_ties (Link_array const &lv_ties) +{ + if (lv_ties.is_empty ()) + return ; + + Link_array heads; + for (int i = 0; i < lv_ties.size (); i++) + { + Item *head = unsmob_item (lv_ties[i]->get_object ("note-head")); + heads.push (head); + } + + x_refpoint_ = lv_ties [0]; + for (int i = 0; i < lv_ties.size (); i++) + { + x_refpoint_ = lv_ties[i]->common_refpoint (x_refpoint_, X_AXIS); + } + + set_chord_outline (heads, LEFT); + + Real right_most = - infinity_f; + + for (int i = 0; i < chord_outlines_[LEFT].size (); i++) + { + right_most = max (right_most, chord_outlines_[LEFT][i].height_); + } + + Skyline_entry right_entry; + right_entry.width_.set_full (); + right_entry.height_ = right_most + 1.5; + + chord_outlines_[RIGHT].push (right_entry); +} diff --git a/lily/tie.cc b/lily/tie.cc index a0b8213f2d..91e444747e 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -21,6 +21,8 @@ #include "note-head.hh" #include "tie-column.hh" #include "grob-array.hh" +#include "tie-formatting-problem.hh" + int Tie::compare (Grob *const &s1, @@ -190,26 +192,11 @@ Tie::get_default_attachments (Spanner *me, Grob *common, Real gap, return attachments; } - -Interval -get_skyline_attachment (Drul_array< Array < Skyline_entry > > const &skylines, - Real y) -{ - Interval attachments; - Direction d = LEFT; - do - { - attachments[d] = skyline_height (skylines[d], y, -d); - } - while (flip (&d) != LEFT); - - return attachments; -} void -Tie::get_configuration (Grob *me_grob, Grob *common, +Tie::get_configuration (Grob *me_grob, Tie_configuration *conf, - Drul_array< Array < Skyline_entry > > const *skylines, + Tie_formatting_problem const &problem, Tie_details const &details ) { @@ -236,16 +223,15 @@ Tie::get_configuration (Grob *me_grob, Grob *common, if (conf->attachment_x_.is_empty()) { +#if 0 if (!skylines) conf->attachment_x_ = get_default_attachments (me, common, gap, &conf->position_, &in_between, details); - else - { - Real y = staff_space * 0.5 * conf->position_; - conf->attachment_x_ = get_skyline_attachment (*skylines, y); - conf->attachment_x_.widen (-gap); - } +#endif + Real y = staff_space * 0.5 * conf->position_; + conf->attachment_x_ = problem.get_attachment (y); + conf->attachment_x_.widen (-gap); } Bezier b = slur_shape (conf->attachment_x_.length(), @@ -283,20 +269,17 @@ Tie::get_configuration (Grob *me_grob, Grob *common, in_space = !in_space; } - if (skylines) - { - 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); - Offset edge = b.curve_point (0.0); - dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]); - fits_in_space = - (dy < 0.6 * staff_space); - } + Real y = staff_space * 0.5 * conf->position_; + conf->attachment_x_ = problem.get_attachment (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); + Offset edge = b.curve_point (0.0); + dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]); + fits_in_space = + (dy < 0.6 * staff_space); } /* @@ -328,22 +311,19 @@ Tie::get_configuration (Grob *me_grob, Grob *common, /* ugh: code dup. - */ - if (skylines) - { - Real y = staff_space * 0.5 * conf->position_; - conf->attachment_x_ = get_skyline_attachment (*skylines, y); - conf->attachment_x_.widen (-gap); + */ + Real y = staff_space * 0.5 * conf->position_; + conf->attachment_x_ = problem.get_attachment (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); - Offset edge = b.curve_point (0.0); - dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]); - fits_in_space = - (dy < 0.6 * staff_space); - } + Bezier b = slur_shape (conf->attachment_x_.length(), + details.height_limit_, + details.ratio_); + Offset middle = b.curve_point (0.5); + Offset edge = b.curve_point (0.0); + dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]); + fits_in_space = + (dy < 0.6 * staff_space); } @@ -412,14 +392,11 @@ Tie::get_configuration (Grob *me_grob, Grob *common, } - if (skylines) - { - Real half_space = 0.5 * staff_space; - Real y = conf->position_ * half_space; + Real half_space = 0.5 * staff_space; + Real y = conf->position_ * half_space; - conf->attachment_x_ = get_skyline_attachment (*skylines, y); - conf->attachment_x_.widen (-gap); - } + conf->attachment_x_ = problem.get_attachment (y); + conf->attachment_x_.widen (-gap); } @@ -437,8 +414,13 @@ Tie::set_default_control_points (Grob *me_grob) Tie_details details; details.init (me); - get_configuration (me, common, &conf, 0, details); - set_control_points (me, common, conf, details); + + Tie_formatting_problem problem; + problem.from_tie (me); + + get_configuration (me, &conf, problem, details); + set_control_points (me, problem.common_x_refpoint (), + conf, details); } void -- 2.39.2