2 tie-column-format.cc -- implement formatting routines for Tie_column
4 source file of the GNU LilyPond music typesetter
6 (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
11 #include "note-head.hh"
16 #include "staff-symbol-referencer.hh"
17 #include "directional-element-interface.hh"
18 #include "rhythmic-head.hh"
23 set_manual_tie_configuration (Array<Tie_configuration> *tie_configs,
24 bool *manual_override,
28 *manual_override = false;
30 for (SCM s = manual_configs;
31 scm_is_pair (s) && k < tie_configs->size(); s = scm_cdr (s))
33 SCM entry = scm_car (s);
34 if (!scm_is_pair (entry))
37 *manual_override = true;
38 Tie_configuration &conf = tie_configs->elem_ref (k);
40 Real complete_pos = robust_scm2double (scm_car (entry),
43 conf.position_ = int (rint (complete_pos));
44 conf.delta_y_ = complete_pos - conf.position_;
45 conf.dir_ = Direction (robust_scm2int (scm_cdr (entry),
52 set_chord_outline (Array<Skyline_entry> *skyline,
53 Link_array<Item> bounds,
57 Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]);
62 for (int i = 0; i < bounds.size (); i++)
64 Grob *head = bounds[i];
65 if (!Note_head::has_interface (head))
69 stem = unsmob_grob (head->get_object ("stem"));
71 Real p = Staff_symbol_referencer::get_position (head);
72 Interval y ((p-1) * 0.5 * staff_space,
73 (p+1) * 0.5 * staff_space);
75 Interval x = head->extent (common, X_AXIS);
76 boxes.push (Box (x, y));
78 Grob *dots = Rhythmic_head::get_dots (head);
79 if (d == LEFT && dots)
81 Interval x = dots->extent (common, X_AXIS);
82 Interval y (-0.5, 0.5);
83 y.translate (Staff_symbol_referencer::get_position (dots));
84 y *= staff_space * 0.5;
86 boxes.push (Box (x, y));
90 (*skyline) = empty_skyline (-d);
92 if (bounds[0]->break_status_dir ())
94 Real x = robust_relative_extent (bounds[0], common, X_AXIS)[-d];
95 skyline->elem_ref (0).height_ = x;
98 for (int i = 0; i < boxes.size (); i++)
99 insert_extent_into_skyline (skyline,
100 boxes[i], Y_AXIS, -d);
102 && !Stem::is_invisible (stem))
105 x.add_point (stem->relative_coordinate (common, X_AXIS));
106 x.widen (staff_space / 20); // ugh.
108 y.add_point (Stem::stem_end_position (stem) * staff_space * .5);
110 Direction stemdir = get_grob_direction (stem);
111 y.add_point (Stem::head_positions (stem)[-stemdir]
114 insert_extent_into_skyline (skyline, Box (x,y), Y_AXIS, -d);
120 Box flag_box = Stem::get_translated_flag (stem).extent_box ();
121 flag_box.translate( Offset (x[RIGHT], X_AXIS));
122 insert_extent_into_skyline (skyline, flag_box,
127 Direction updowndir = DOWN;
134 Box b = boxes.boundary (updowndir, 0);
136 x[-d] = b[X_AXIS].linear_combination (-d / 2);
137 y[-updowndir] = b[Y_AXIS][updowndir];
138 y[updowndir] = updowndir * infinity_f;
142 insert_extent_into_skyline (skyline,
146 while (flip (&updowndir) != DOWN);
148 for (int i = 0; i < bounds.size (); i++)
150 if (!Note_head::has_interface (bounds[i]))
154 Grob *dots = unsmob_grob (bounds[i]->get_object ("dot"));
155 if (dots && d == LEFT)
157 Interval x = dots->extent (common, X_AXIS);
158 Real p = Staff_symbol_referencer::get_position (dots);
161 y *= (staff_space /4);
162 y.translate (p * staff_space * .5);
164 insert_extent_into_skyline (skyline,
165 Box (x,y), Y_AXIS, -d);
171 set_chord_outlines (Drul_array< Array<Skyline_entry> > *skyline_drul,
172 Link_array<Grob> ties,
179 Link_array<Item> bounds;
181 for (int i = 0; i < ties.size (); i++)
183 Item *it = dynamic_cast<Spanner*> (ties[i])->get_bound (d);
188 set_chord_outline (&skyline_drul->elem_ref (d),
191 while (flip (&d) != LEFT);
195 shift_small_ties (Array<Tie_configuration> *tie_configs,
196 Grob *staff_referencer,
197 Tie_details const &details)
199 set<int> positions_taken;
200 for (int i = 0; i < tie_configs->size (); i++)
201 positions_taken.insert (int (rint (tie_configs->elem (i).position_)));
203 for (int i = 0; i < tie_configs->size (); i++)
205 Tie_configuration * conf = &tie_configs->elem_ref (i);
208 on staff line and small enough, translate a little further
210 Real h = conf->height (details);
211 bool next_free = positions_taken.find (int (rint (conf->position_ + conf->dir_)))
212 == positions_taken.end ();
214 int rounded_pos = int (rint (conf->position_ + conf->delta_y_ / details.staff_space_));
215 bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer, rounded_pos);
218 if (on_line && h < 0.4 * details.staff_space_)
220 positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
221 conf->delta_y_ += 0.2 * details.staff_space_ * conf->dir_;
223 else if (!on_line && h > 0.6 * details.staff_space_)
225 positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
226 conf->delta_y_ += 0.5 * details.staff_space_ * conf->dir_;
233 final_shape_adjustment (Tie_configuration &conf,
234 Drul_array< Array<Skyline_entry> > const &skylines,
235 Grob *staff_referencer,
236 Tie_details const &details)
239 bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer,
240 int (rint (conf.position_)));
242 line_dy = - sign (conf.height (details) - 0.6 * details.staff_space_)
243 * 0.2 * details.staff_space_ * conf.dir_;
245 Real y = conf.position_ * details.staff_space_ * 0.5
248 conf.attachment_x_ = get_skyline_attachment (skylines, y);
249 conf.attachment_x_.intersect (get_skyline_attachment (skylines,
250 y + conf.dir_ * details.staff_space_ * 0.5));
252 conf.delta_y_ += line_dy;
253 conf.attachment_x_.widen (-details.x_gap_);
255 && Staff_symbol_referencer::staff_radius (staff_referencer) * details.staff_space_ > y)
256 conf.center_tie_vertically (details);
260 set_tie_config_directions (Array<Tie_configuration> *tie_configs_ptr)
262 Array<Tie_configuration> &tie_configs (*tie_configs_ptr);
264 if (!tie_configs[0].dir_)
265 tie_configs[0].dir_ = DOWN;
266 if (!tie_configs.top().dir_)
267 tie_configs.top().dir_ = UP;
272 for (int i = 1; i < tie_configs.size(); i++)
274 Real diff = tie_configs[i-1].position_ - tie_configs[i].position_;
275 if (fabs (diff) <= 1)
277 if (!tie_configs[i-1].dir_)
278 tie_configs[i-1].dir_ = DOWN;
279 if (!tie_configs[i].dir_)
280 tie_configs[i].dir_ = UP;
284 for (int i = 1; i < tie_configs.size() - 1; i++)
286 if (tie_configs[i].dir_)
289 Direction position_dir = (Direction) sign (tie_configs[i].position_);
293 tie_configs[i].dir_ = position_dir;