2 item.cc -- implement Item
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
11 #include "axis-group-interface.hh"
12 #include "paper-score.hh"
14 #include "paper-column.hh"
15 #include "lily-guile.hh"
17 #include "pointer-group-interface.hh"
25 return new Item (*this);
31 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] = 0;
32 cached_pure_height_valid_ = false;
36 Item copy ctor. Copy nothing: everything should be a elt property
37 or a special purpose pointer (such as broken_to_drul_[]) */
38 Item::Item (Item const &s)
41 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] = 0;
42 cached_pure_height_valid_ = false;
46 Item::is_non_musical (Grob *me)
51 Item *i = dynamic_cast<Item *> (me->get_parent (X_AXIS));
52 return i ? Item::is_non_musical (i) : to_boolean (me->get_property ("non-musical"));
56 Item::get_column () const
58 Item *parent = dynamic_cast<Item *> (get_parent (X_AXIS));
59 return parent ? parent->get_column () : 0;
63 Item::get_system () const
65 Grob *g = get_parent (X_AXIS);
66 return g ? g->get_system () : 0;
70 Item::copy_breakable_items ()
72 Drul_array<Item *> new_copies;
76 Grob *dolly = clone ();
77 Item *item = dynamic_cast<Item *> (dolly);
78 get_root_system (this)->typeset_grob (item);
81 while (flip (&i) != LEFT);
83 broken_to_drul_ = new_copies;
87 Item::is_broken () const
89 return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
93 Generate items for begin and end-of line.
96 Item::discretionary_processing ()
101 if (Item::is_non_musical (this))
102 copy_breakable_items ();
106 Item::find_broken_piece (System *l) const
108 if (get_system () == l)
109 return (Item *) (this);
114 Grob *s = broken_to_drul_[d];
115 if (s && s->get_system () == l)
118 while (flip (&d) != LEFT);
124 Item::find_prebroken_piece (Direction d) const
126 Item *me = (Item *) (this);
129 return dynamic_cast<Item *> (broken_to_drul_[d]);
133 Item::break_status_dir () const
137 Item *i = dynamic_cast<Item *> (original ());
139 return (i->broken_to_drul_[LEFT] == this) ? LEFT : RIGHT;
146 Item::handle_prebroken_dependencies ()
148 Grob::handle_prebroken_dependencies ();
151 Can't do this earlier, because try_visibility_lambda () might set
152 the elt property transparent, which would then be copied.
154 if (!Item::break_visible (this))
159 Item::break_visible (Grob *g)
161 Item *it = dynamic_cast<Item*> (g);
162 SCM vis = g->get_property ("break-visibility");
163 if (scm_is_vector (vis))
164 return to_boolean (scm_c_vector_ref (vis, it->break_status_dir () + 1));
169 Item::pure_is_visible (int start, int end) const
171 SCM vis = get_property ("break-visibility");
172 if (scm_is_vector (vis))
175 int pc_rank = Paper_column::get_rank (get_column ());
176 if (pc_rank == start)
178 else if (pc_rank == end)
180 return to_boolean (scm_vector_ref (vis, scm_from_int (pos)));
186 Item::spanned_rank_interval () const
188 int c = get_column ()->get_rank ();
189 return Interval_t<int> (c, c);
193 spanned_time_interval (Item *l, Item *r)
195 Drul_array<Item*> bounds (l, r);
196 Interval_t<Moment> iv;
201 if (bounds[d] && bounds[d]->get_column ())
202 iv[d] = robust_scm2moment (bounds[d]->get_column ()->get_property ("when"),
205 while (flip (&d) != LEFT);
209 if (!bounds[d] || !bounds[d]->get_column ())
212 while (flip (&d) != LEFT);
220 Item::derived_mark () const
222 if (broken_to_drul_[LEFT])
223 scm_gc_mark (broken_to_drul_[LEFT]->self_scm ());
224 if (broken_to_drul_[RIGHT])
225 scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
231 return dynamic_cast<Item *> (unsmob_grob (s));
235 Item::pure_height (Grob *g, int start, int end)
237 if (cached_pure_height_valid_)
238 return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
240 cached_pure_height_ = Grob::pure_height (this, start, end);
241 cached_pure_height_valid_ = true;
242 return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
246 Item::less (Grob * const &g1, Grob * const &g2)
248 return dynamic_cast<Item*> (g1)->get_column ()->get_rank () < dynamic_cast<Item*> (g2)->get_column ()->get_rank ();
253 "Grobs can be distinguished in their role in the horizontal spacing.\n"
254 "Many grobs define constraints on the spacing by their sizes. For\n"
255 "example, note heads, clefs, stems, and all other symbols with a fixed\n"
256 "shape. These grobs form a subtype called @code{Item}.\n"
259 "Some items need special treatment for line breaking. For example, a\n"
260 "clef is normally only printed at the start of a line (i.e. after a\n"
261 "line break). To model this, `breakable' items (clef, key signature,\n"
262 "bar lines, etc.) are copied twice. Then we have three versions of each\n"
263 "breakable item: one version if there is no line break, one version\n"
264 "that is printed before the line break (at the end of a system), one\n"
265 "version that is printed after the line break.\n"
267 "Whether these versions are visible and take up space, is determined by\n"
268 "the outcome of the @code{break-visibility}. This grob property is a\n"
269 "function taking a direction (-1, 0 or 1) as argument. It returns a\n"
270 "cons of booleans, signifying whether this grob should be transparent\n"
271 "and have no extent.\n"
273 "The following variables for break-visibility are predefined:\n"
275 " grob will show: before no after\n"
276 " break break break\n"
277 " all-invisible no no no\n"
278 " begin-of-line-visible no no yes\n"
279 " end-of-line-visible yes no no\n"
280 " all-visible yes yes yes\n"
281 " begin-of-line-invisible yes yes no\n"
282 " end-of-line-invisible no yes yes\n"
283 " center-invisible yes no yes\n"
288 "extra-spacing-width "
289 "infinite-spacing-height "