/*
- grob.cc -- implement Grob
+ This file is part of LilyPond, the GNU music typesetter.
- source file of the GNU LilyPond music typesetter
+ Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
- (c) 1997--2007 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 "grob.hh"
#include <cstring>
#include "align-interface.hh"
+#include "axis-group-interface.hh"
#include "input.hh"
#include "international.hh"
#include "item.hh"
#include "music.hh"
#include "output-def.hh"
#include "pointer-group-interface.hh"
+#include "program-option.hh"
#include "stencil.hh"
#include "stream-event.hh"
#include "system.hh"
if (Stencil *m = unsmob_stencil (stil))
{
retval = *m;
- if (to_boolean (get_property ("transparent")))
+ bool transparent = to_boolean (get_property ("transparent"));
+
+ if (transparent)
retval = Stencil (m->extent_box (), SCM_EOL);
else
{
retval = Stencil (retval.extent_box (), expr);
}
+ /* process whiteout */
+ /* a grob has to be visible, otherwise the whiteout property has no effect */
+ if (!transparent && to_boolean (get_property ("whiteout")))
+ {
+ /* Call the scheme procedure stencil-whiteout in scm/stencils.scm */
+ /* to add a round-filled-box stencil to the stencil list */
+ retval
+ = *unsmob_stencil (scm_call_1 (ly_lily_module_constant ("stencil-whiteout"),
+ retval.smobbed_copy()));
+ }
}
return retval;
Interval
Grob::pure_height (Grob *refp, int start, int end)
{
- SCM proc = get_property_data (ly_symbol2scm ("Y-extent"));
- SCM iv_scm = call_pure_function (proc,
- scm_list_1 (self_scm ()),
- start, end);
+ SCM iv_scm = get_pure_property ("Y-extent", start, end);
Interval iv = robust_scm2interval (iv_scm, Interval (0, 0));
Real offset = pure_relative_y_coordinate (refp, start, end);
return Interval_t<int> (-1, 0);
}
+bool
+Grob::pure_is_visible (int start, int end) const
+{
+ return true;
+}
+
+/* Sort grobs according to their starting column. */
+bool
+Grob::less (Grob *g1, Grob *g2)
+{
+ return g1->spanned_rank_interval ()[LEFT] < g2->spanned_rank_interval ()[LEFT];
+}
+
/****************************************************************
REFPOINTS
****************************************************************/
void
Grob::warning (string s) const
{
+ if (get_program_option ("warning-as-error"))
+ error (s);
+
SCM cause = self_scm ();
while (Grob *g = unsmob_grob (cause))
cause = g->get_property ("cause");
void
Grob::programming_error (string s) const
{
+ if (get_program_option ("warning-as-error"))
+ error (s);
+
SCM cause = self_scm ();
while (Grob *g = unsmob_grob (cause))
cause = g->get_property ("cause");
if (Music *m = unsmob_music (cause))
m->origin ()->message (s);
else if (Stream_event *ev = unsmob_stream_event (cause))
- ev->origin ()->warning (s);
+ ev->origin ()->message (s);
else
::message (s);
}
ADD_INTERFACE (Grob,
"A grob represents a piece of music notation.\n"
"\n"
- "All grobs have an X and Y@tie{}position on the page. These "
- "X and Y@tie{}positions are stored in a relative format, thus "
- "they can easily be combined by stacking them, hanging one "
- "grob to the side of another, or coupling them into grouping "
- "objects.\n"
+ "All grobs have an X and Y@tie{}position on the page. These"
+ " X and Y@tie{}positions are stored in a relative format, thus"
+ " they can easily be combined by stacking them, hanging one"
+ " grob to the side of another, or coupling them into grouping"
+ " objects.\n"
"\n"
- "Each grob has a reference point (a.k.a.@: parent): The "
- "position of a grob is stored relative to that reference "
- "point. For example, the X@tie{}reference point of a staccato "
- "dot usually is the note head that it applies to. When the "
- "note head is moved, the staccato dot moves along "
- "automatically.\n"
+ "Each grob has a reference point (a.k.a.@: parent): The"
+ " position of a grob is stored relative to that reference"
+ " point. For example, the X@tie{}reference point of a staccato"
+ " dot usually is the note head that it applies to. When the"
+ " note head is moved, the staccato dot moves along"
+ " automatically.\n"
"\n"
- "A grob is often associated with a symbol, but some grobs do "
- "not print any symbols. They take care of grouping objects. "
- "For example, there is a separate grob that stacks staves "
- "vertically. The @ref{NoteCollision} object is also an "
- "abstract grob: It only moves around chords, but doesn't print "
- "anything.\n"
+ "A grob is often associated with a symbol, but some grobs do"
+ " not print any symbols. They take care of grouping objects."
+ " For example, there is a separate grob that stacks staves"
+ " vertically. The @ref{NoteCollision} object is also an"
+ " abstract grob: It only moves around chords, but doesn't print"
+ " anything.\n"
"\n"
- "Grobs have properties (Scheme variables) that can be read and "
- "set. Two types of them exist: immutable and mutable. "
- "Immutable variables define the default style and behavior. "
- "They are shared between many objects. They can be changed "
- "using @code{\\override} and @code{\\revert}. Mutable "
- "properties are variables that are specific to one grob. "
- "Typically, lists of other objects, or results from "
- "computations are stored in mutable properties. In "
- "particular, every call to @code{set-grob-property} (or its "
- "C++ equivalent) sets a mutable property.\n"
+ "Grobs have properties (Scheme variables) that can be read and"
+ " set. Two types of them exist: immutable and mutable."
+ " Immutable variables define the default style and behavior."
+ " They are shared between many objects. They can be changed"
+ " using @code{\\override} and @code{\\revert}. Mutable"
+ " properties are variables that are specific to one grob."
+ " Typically, lists of other objects, or results from"
+ " computations are stored in mutable properties. In"
+ " particular, every call to @code{ly:grob-set-property!}"
+ " (or its C++ equivalent) sets a mutable property.\n"
"\n"
- "The properties @code{after-line-breaking} and "
- "@code{before-line-breaking} are dummies that are not "
- "user-serviceable.",
+ "The properties @code{after-line-breaking} and"
+ " @code{before-line-breaking} are dummies that are not"
+ " user-serviceable.",
/* properties */
"X-extent "
"staff-symbol "
"stencil "
"transparent "
+ "whiteout "
);
/****************************************************************
}
-
Grob *
common_refpoint_of_list (SCM elist, Grob *common, Axis a)
{
Grob *
common_refpoint_of_array (vector<Grob*> const &arr, Grob *common, Axis a)
{
- for (vsize i = arr.size (); i--;)
- if (Grob *s = arr[i])
- {
- if (common)
- common = common->common_refpoint (s, a);
- else
- common = s;
- }
+ for (vsize i = 0; i < arr.size (); i++)
+ if (common)
+ common = common->common_refpoint (arr[i], a);
+ else
+ common = arr[i];
return common;
}
return ext;
}
+// Checks whether there is a vertical alignment in the chain of
+// parents between this and commony.
+bool
+Grob::check_cross_staff (Grob *commony)
+{
+ if (Align_interface::has_interface (commony))
+ return true;
+
+ for (Grob *g = this; g && g != commony; g = g->get_parent (Y_AXIS))
+ if (Align_interface::has_interface (g))
+ return true;
+
+ return false;
+}
+