+Interval_t<int>
+Item::spanned_rank_interval () const
+{
+ int c = get_column ()->get_rank ();
+ return Interval_t<int> (c, c);
+}
+
+Interval_t<Moment>
+spanned_time_interval (Item *l, Item *r)
+{
+ Drul_array<Item *> bounds (l, r);
+ Interval_t<Moment> iv;
+
+ for (LEFT_and_RIGHT (d))
+ {
+ if (bounds[d] && bounds[d]->get_column ())
+ iv[d] = robust_scm2moment (bounds[d]->get_column ()->get_property ("when"),
+ iv[d]);
+ }
+
+ for (LEFT_and_RIGHT (d))
+ {
+ if (!bounds[d] || !bounds[d]->get_column ())
+ iv[d] = iv[-d];
+ }
+
+ return iv;
+}
+
+void
+Item::derived_mark () const
+{
+ if (broken_to_drul_[LEFT])
+ scm_gc_mark (broken_to_drul_[LEFT]->self_scm ());
+ if (broken_to_drul_[RIGHT])
+ scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
+}
+
+Interval
+Item::pure_y_extent (Grob *g, int start, int end)
+{
+ if (cached_pure_height_valid_)
+ return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
+ /* Note: cached_pure_height_ does not notice if start changes, implicitly
+ assuming that Items' pure_heights do not depend on 'start' or 'end'.
+ */
+
+ cache_pure_height (Grob::pure_y_extent (this, start, end));
+ return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
+}
+
+void
+Item::cache_pure_height (Interval height)
+{
+ cached_pure_height_ = height;
+ cached_pure_height_valid_ = true;
+}
+
+ADD_INTERFACE (Item,
+ "Grobs can be distinguished in their role in the horizontal"
+ " spacing. Many grobs define constraints on the spacing by"
+ " their sizes, for example, note heads, clefs, stems, and all"
+ " other symbols with a fixed shape. These grobs form a"
+ " subtype called @code{Item}.\n"
+ "\n"
+ "Some items need special treatment for line breaking. For"
+ " example, a clef is normally only printed at the start of a"
+ " line (i.e., after a line break). To model this,"
+ " @q{breakable} items (clef, key signature, bar lines, etc.)"
+ " are copied twice. Then we have three versions of each"
+ " breakable item: one version if there is no line break, one"
+ " version that is printed before the line break (at the end of"
+ " a system), and one version that is printed after the line"
+ " break.\n"
+ "\n"
+ "Whether these versions are visible and take up space is"
+ " determined by the outcome of the @code{break-visibility}"
+ " grob property, which is a function taking a direction"
+ " (@w{@code{-1}}, @code{0} or@tie{}@code{1}) as an argument. It"
+ " returns a cons of booleans, signifying whether this grob"
+ " should be transparent and have no extent.\n"
+ "\n"
+ "The following variables for @code{break-visibility} are"
+ " predefined:\n"
+ "@example\n"
+ " grob will show: before no after\n"
+ " break break break\n"
+ " all-invisible no no no\n"
+ " begin-of-line-visible no no yes\n"
+ " end-of-line-visible yes no no\n"
+ " all-visible yes yes yes\n"
+ " begin-of-line-invisible yes yes no\n"
+ " end-of-line-invisible no yes yes\n"
+ " center-invisible yes no yes\n"
+ "@end example",
+
+ /* properties */
+ "break-visibility "
+ "extra-spacing-height "
+ "extra-spacing-width "
+ "non-musical "
+ );