2 tie-column.cc -- implement Tie_column
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "tie-column.hh"
15 #include "paper-column.hh"
17 #include "pointer-group-interface.hh"
19 #include "directional-element-interface.hh"
20 #include "tie-column-format.hh"
25 Tie_column::add_tie (Grob *me, Grob *tie)
27 if (tie->get_parent (Y_AXIS)
28 && Tie_column::has_interface (tie->get_parent (Y_AXIS)))
31 if (!Pointer_group_interface::count (me, ly_symbol2scm ("ties")))
33 dynamic_cast<Spanner *> (me)->set_bound (LEFT, Tie::head (tie, LEFT));
34 dynamic_cast<Spanner *> (me)->set_bound (RIGHT, Tie::head (tie, RIGHT));
37 tie->set_parent (me, Y_AXIS);
38 Pointer_group_interface::add_grob (me, ly_symbol2scm ("ties"), tie);
39 tie->add_dependency (me);
43 Tie_column::set_directions (Grob *me)
45 if (!to_boolean (me->get_property ("positioning-done")))
47 me->set_property ("positioning-done", SCM_BOOL_T);
54 MAKE_SCHEME_CALLBACK (Tie_column, after_line_breaking, 1);
56 Tie_column::after_line_breaking (SCM smob)
58 set_directions (unsmob_grob (smob));
59 return SCM_UNSPECIFIED;
63 Extend the spanner over its Tie constituents.
65 MAKE_SCHEME_CALLBACK (Tie_column, before_line_breaking, 1);
67 Tie_column::before_line_breaking (SCM smob)
69 Spanner *me = dynamic_cast<Spanner *> (unsmob_grob (smob));
70 for (SCM s = me->get_property ("ties"); scm_is_pair (s); s = scm_cdr (s))
72 Spanner *tie = dynamic_cast<Spanner *> (unsmob_grob (scm_car (s)));
76 if (dir * tie->get_bound (dir)->get_column ()->get_rank ()
77 > dir * me->get_bound (dir)->get_column ()->get_rank ())
78 me->set_bound (dir, Tie::head (tie, dir));
80 while (flip (&dir) != LEFT);
82 return SCM_UNSPECIFIED;
87 Tie_column::new_directions (Grob *me)
89 extract_grob_set (me, "ties", ro_ties);
90 Link_array<Grob> ties (ro_ties);
96 Tie::set_default_control_points (ties[0]);
100 ties.sort (&Tie::compare);
102 Array<Tie_configuration> tie_configs;
103 for (int i = 0; i < ties.size (); i++)
105 Tie_configuration conf;
106 conf.dir_ = get_grob_direction (ties[i]);
107 conf.position_ = Tie::get_position (ties[i]);
108 tie_configs.push (conf);
111 SCM manual_configs = me->get_property ("tie-configuration");
112 bool manual_override = false;
113 set_manual_tie_configuration (&tie_configs,
116 set_tie_config_directions (&tie_configs);
119 for (int i = 0; i < ties.size (); i++)
121 common = dynamic_cast<Spanner*> (ties[i])->get_bound (LEFT)->common_refpoint (common, X_AXIS);
122 common = dynamic_cast<Spanner*> (ties[i])->get_bound (RIGHT)->common_refpoint (common, X_AXIS);
125 Drul_array< Array<Skyline_entry> > skylines;
126 set_chord_outlines (&skylines, ties, common);
129 details.init (ties[0]);
132 Let the ties flow out, according to our single-tie formatting.
134 if (!manual_override)
136 Tie::get_configuration (ties[0], common, &tie_configs.elem_ref (0),
140 Tie::get_configuration (ties.top (), common,
141 &tie_configs.elem_ref (tie_configs.size()-1),
148 Calculate final width and shape of the ties.
150 for (int i = 0; i < ties.size(); i++)
153 && (i == 0 || i == ties.size () -1))
157 final_shape_adjustment (tie_configs[i],
165 Try to shift small ties into available spaces.
167 if (!manual_override)
169 shift_small_ties (&tie_configs, ties[0], details);
172 for (int i = 0; i < ties.size(); i++)
174 Tie::set_control_points (ties[i], common, tie_configs[i],
177 set_grob_direction (ties[i], tie_configs[i].dir_);
183 ADD_INTERFACE (Tie_column, "tie-column-interface",
184 "Object that sets directions of multiple ties in a tied chord",