- (c) 1997--2009 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/>.
- {
- SCM expr = scm_list_3 (ly_symbol2scm ("color"),
- color,
- retval.expr ());
-
- retval = Stencil (retval.extent_box (), expr);
- }
-
+ {
+ SCM expr = scm_list_3 (ly_symbol2scm ("color"),
+ color,
+ retval.expr ());
+
+ 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 ()));
+ }
+/****************************************************************
+ VERTICAL ORDERING
+****************************************************************/
+
+Grob*
+get_maybe_root_vertical_alignment (Grob *g, Grob *maybe)
+{
+ if (!g)
+ return maybe;
+ if (Align_interface::has_interface (g))
+ return get_maybe_root_vertical_alignment (g->get_parent (Y_AXIS), g);
+ return get_maybe_root_vertical_alignment (g->get_parent (Y_AXIS), maybe);
+
+}
+
+Grob*
+Grob::get_root_vertical_alignment (Grob *g)
+{
+ return get_maybe_root_vertical_alignment (g, 0);
+}
+
+Grob*
+Grob::get_vertical_axis_group (Grob *g)
+{
+ if (!g)
+ return 0;
+ if (Axis_group_interface::has_interface (g)
+ && Align_interface::has_interface (g->get_parent (Y_AXIS)))
+ return g;
+ return get_vertical_axis_group (g->get_parent (Y_AXIS));
+
+}
+
+int
+Grob::get_vertical_axis_group_index (Grob *g)
+{
+ Grob *val = get_root_vertical_alignment (g);
+ if (!val)
+ return -1;
+ Grob *vax = get_vertical_axis_group (g);
+ extract_grob_set (val, "elements", elts);
+ for (vsize i = 0; i < elts.size (); i++)
+ if (elts[i] == vax)
+ return (int) i;
+ g->programming_error ("could not find this grob's vertical axis group in the vertical alignment");
+ return -1;
+}
+
+bool
+Grob::vertical_less (Grob *g1, Grob *g2)
+{
+ Grob *vag = get_root_vertical_alignment (g1);
+ if (!vag)
+ return false;
+ if (!vag)
+ {
+ g1->programming_error ("grob does not belong to a VerticalAlignment?");
+ return false;
+ }
+ Grob *ag1 = get_vertical_axis_group (g1);
+ Grob *ag2 = get_vertical_axis_group (g2);
+
+ extract_grob_set (vag, "elements", elts);
+
+ for (vsize i = 0; i < elts.size (); i++)
+ {
+ if (elts[i] == ag1)
+ return true;
+ if (elts[i] == ag2)
+ return false;
+ }
+
+ g1->programming_error ("could not place this grob in its axis group");
+ return false;
+}
- "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"
- "\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"
- "\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.",
-
- /* properties */
- "X-extent "
- "X-offset "
- "Y-extent "
- "Y-offset "
- "after-line-breaking "
- "avoid-slur "
- "axis-group-parent-X "
- "axis-group-parent-Y "
- "before-line-breaking "
- "cause "
- "color "
- "cross-staff "
- "extra-X-extent "
- "extra-Y-extent "
- "extra-offset "
- "interfaces "
- "layer "
- "meta "
- "minimum-X-extent "
- "minimum-Y-extent "
- "outside-staff-horizontal-padding "
- "outside-staff-padding "
- "outside-staff-priority "
- "pure-Y-offset-in-progress "
- "rotation "
- "springs-and-rods "
- "staff-symbol "
- "stencil "
- "transparent "
- );
+ "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"
+ "\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"
+ "\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.",
+
+ /* properties */
+ "X-extent "
+ "X-offset "
+ "Y-extent "
+ "Y-offset "
+ "after-line-breaking "
+ "avoid-slur "
+ "axis-group-parent-X "
+ "axis-group-parent-Y "
+ "before-line-breaking "
+ "cause "
+ "color "
+ "cross-staff "
+ "extra-X-extent "
+ "extra-Y-extent "
+ "extra-offset "
+ "interfaces "
+ "layer "
+ "meta "
+ "minimum-X-extent "
+ "minimum-Y-extent "
+ "outside-staff-horizontal-padding "
+ "outside-staff-padding "
+ "outside-staff-priority "
+ "pure-Y-offset-in-progress "
+ "rotation "
+ "springs-and-rods "
+ "staff-symbol "
+ "stencil "
+ "transparent "
+ "whiteout "
+ );