2 tie-formatting-problem.cc -- implement Tie_formatting_problem6
4 source file of the GNU LilyPond music typesetter
6 (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
10 #include "tie-formatting-problem.hh"
12 #include "directional-element-interface.hh"
13 #include "staff-symbol-referencer.hh"
20 #include "note-head.hh"
21 #include "rhythmic-head.hh"
24 Tie_formatting_problem::get_attachment (Real y) const
30 attachments[d] = skyline_height (chord_outlines_[d], y, -d);
32 while (flip (&d) != LEFT);
40 Tie_formatting_problem::Tie_formatting_problem()
47 Tie_formatting_problem::set_chord_outline (Link_array<Item> bounds,
50 Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]);
55 for (int i = 0; i < bounds.size (); i++)
57 Grob *head = bounds[i];
58 if (!Note_head::has_interface (head))
62 stem = unsmob_grob (head->get_object ("stem"));
64 Real p = Staff_symbol_referencer::get_position (head);
65 Interval y ((p-1) * 0.5 * staff_space,
66 (p+1) * 0.5 * staff_space);
68 Interval x = head->extent (x_refpoint_, X_AXIS);
69 boxes.push (Box (x, y));
71 Grob *dots = Rhythmic_head::get_dots (head);
72 if (d == LEFT && dots)
74 Interval x = dots->extent (x_refpoint_, X_AXIS);
75 Interval y (-0.5, 0.5);
76 y.translate (Staff_symbol_referencer::get_position (dots));
77 y *= staff_space * 0.5;
79 boxes.push (Box (x, y));
83 chord_outlines_[d] = empty_skyline (-d);
85 if (bounds[0]->break_status_dir ())
87 Real x = robust_relative_extent (bounds[0], x_refpoint_, X_AXIS)[-d];
88 chord_outlines_[d].elem_ref (0).height_ = x;
91 for (int i = 0; i < boxes.size (); i++)
92 insert_extent_into_skyline (&chord_outlines_[d] ,
93 boxes[i], Y_AXIS, -d);
96 && !Stem::is_invisible (stem))
99 x.add_point (stem->relative_coordinate (x_refpoint_, X_AXIS));
100 x.widen (staff_space / 20); // ugh.
102 y.add_point (Stem::stem_end_position (stem) * staff_space * .5);
104 Direction stemdir = get_grob_direction (stem);
105 y.add_point (Stem::head_positions (stem)[-stemdir]
108 insert_extent_into_skyline (&chord_outlines_[d], Box (x,y), Y_AXIS, -d);
114 Box flag_box = Stem::get_translated_flag (stem).extent_box ();
115 flag_box.translate( Offset (x[RIGHT], X_AXIS));
116 insert_extent_into_skyline (&chord_outlines_[d], flag_box,
121 Direction updowndir = DOWN;
128 Box b = boxes.boundary (updowndir, 0);
130 x[-d] = b[X_AXIS].linear_combination (-d / 2);
131 y[-updowndir] = b[Y_AXIS][updowndir];
132 y[updowndir] = updowndir * infinity_f;
136 insert_extent_into_skyline (&chord_outlines_[d],
140 while (flip (&updowndir) != DOWN);
142 for (int i = 0; i < bounds.size (); i++)
144 if (!Note_head::has_interface (bounds[i]))
148 Grob *dots = unsmob_grob (bounds[i]->get_object ("dot"));
149 if (dots && d == LEFT)
151 Interval x = dots->extent (x_refpoint_, X_AXIS);
152 Real p = Staff_symbol_referencer::get_position (dots);
155 y *= (staff_space /4);
156 y.translate (p * staff_space * .5);
158 insert_extent_into_skyline (&chord_outlines_[d],
159 Box (x,y), Y_AXIS, -d);
166 Tie_formatting_problem::from_tie (Grob *tie)
168 Link_array<Grob> ties;
175 Tie_formatting_problem::common_x_refpoint () const
181 Tie_formatting_problem::from_ties (Link_array<Grob> const &ties)
183 if (ties.is_empty ())
186 x_refpoint_ = ties[0];
187 for (int i = 0; i < ties.size (); i++)
189 x_refpoint_ = dynamic_cast<Spanner*> (ties[i])->get_bound (LEFT)->common_refpoint (x_refpoint_, X_AXIS);
190 x_refpoint_ = dynamic_cast<Spanner*> (ties[i])->get_bound (RIGHT)->common_refpoint (x_refpoint_, X_AXIS);
196 Link_array<Item> bounds;
198 for (int i = 0; i < ties.size (); i++)
200 Item *it = dynamic_cast<Spanner*> (ties[i])->get_bound (d);
205 set_chord_outline (bounds, d);
207 while (flip (&d) != LEFT);
211 Tie_formatting_problem::from_lv_ties (Link_array<Grob> const &lv_ties)
213 if (lv_ties.is_empty ())
216 Link_array<Item> heads;
217 for (int i = 0; i < lv_ties.size (); i++)
219 Item *head = unsmob_item (lv_ties[i]->get_object ("note-head"));
223 x_refpoint_ = lv_ties [0];
224 for (int i = 0; i < lv_ties.size (); i++)
226 x_refpoint_ = lv_ties[i]->common_refpoint (x_refpoint_, X_AXIS);
229 set_chord_outline (heads, LEFT);
231 Real right_most = - infinity_f;
233 for (int i = 0; i < chord_outlines_[LEFT].size (); i++)
235 right_most = max (right_most, chord_outlines_[LEFT][i].height_);
238 Skyline_entry right_entry;
239 right_entry.width_.set_full ();
240 right_entry.height_ = right_most + 1.5;
242 chord_outlines_[RIGHT].push (right_entry);