/*
- item.cc -- implement Item
+ This file is part of LilyPond, the GNU music typesetter.
- source file of the GNU LilyPond music typesetter
+ Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
- (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
#include "item.hh"
#include "moment.hh"
-
Grob *
Item::clone () const
{
}
/**
- Item copy ctor. Copy nothing: everything should be a elt property
+ Item copy ctor. Copy nothing: everything should be an elt property
or a special purpose pointer (such as broken_to_drul_[]) */
Item::Item (Item const &s)
: Grob (s)
bool
Item::is_non_musical (Grob *me)
{
- if (me->original ())
- return false;
-
Item *i = dynamic_cast<Item *> (me->get_parent (X_AXIS));
return i ? Item::is_non_musical (i) : to_boolean (me->get_property ("non-musical"));
}
Item::copy_breakable_items ()
{
Drul_array<Item *> new_copies;
- Direction i = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
Grob *dolly = clone ();
Item *item = dynamic_cast<Item *> (dolly);
get_root_system (this)->typeset_grob (item);
- new_copies[i] = item;
+ new_copies[d] = item;
}
- while (flip (&i) != LEFT);
broken_to_drul_ = new_copies;
}
void
Item::discretionary_processing ()
{
- if (is_broken ())
+ if (is_broken () || original ())
return;
if (Item::is_non_musical (this))
if (get_system () == l)
return (Item *) (this);
- Direction d = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
Grob *s = broken_to_drul_[d];
if (s && s->get_system () == l)
- return s;
+ return s;
}
- while (flip (&d) != LEFT);
return 0;
}
bool
Item::break_visible (Grob *g)
{
- Item *it = dynamic_cast<Item*> (g);
+ Item *it = dynamic_cast<Item *> (g);
SCM vis = g->get_property ("break-visibility");
if (scm_is_vector (vis))
return to_boolean (scm_c_vector_ref (vis, it->break_status_dir () + 1));
int pos = 1;
int pc_rank = Paper_column::get_rank (get_column ());
if (pc_rank == start)
- pos = 2;
+ pos = 2;
else if (pc_rank == end)
- pos = 0;
+ pos = 0;
return to_boolean (scm_vector_ref (vis, scm_from_int (pos)));
}
return true;
}
Interval_t<Moment>
-spanned_time_interval (Item *l, Item *r)
+spanned_time_interval (Item *l, Item *r)
{
- Drul_array<Item*> bounds (l, r);
+ Drul_array<Item *> bounds (l, r);
Interval_t<Moment> iv;
- Direction d = LEFT;
- do
+ 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]);
+ iv[d] = robust_scm2moment (bounds[d]->get_column ()->get_property ("when"),
+ iv[d]);
}
- while (flip (&d) != LEFT);
- do
+ for (LEFT_and_RIGHT (d))
{
if (!bounds[d] || !bounds[d]->get_column ())
- iv[d] = iv[-d];
+ iv[d] = iv[-d];
}
- while (flip (&d) != LEFT);
-
-
+
return iv;
}
-
void
Item::derived_mark () const
{
scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
}
-Item *
-unsmob_item (SCM s)
-{
- return dynamic_cast<Item *> (unsmob_grob (s));
-}
-
Interval
-Item::pure_height (Grob *g, int start, int end)
+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'.
+ */
- cached_pure_height_ = Grob::pure_height (this, start, end);
- cached_pure_height_valid_ = true;
+ cache_pure_height (Grob::pure_y_extent (this, start, end));
return cached_pure_height_ + pure_relative_y_coordinate (g, start, end);
}
-bool
-Item::less (Grob * const &g1, Grob * const &g2)
+void
+Item::cache_pure_height (Interval height)
{
- return dynamic_cast<Item*> (g1)->get_column ()->get_rank () < dynamic_cast<Item*> (g2)->get_column ()->get_rank ();
+ 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"
- " (@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 "
- );
+ "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 "
+ );