source file of the GNU LilyPond music typesetter
- (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
#include "grob.hh"
Real
Grob::relative_coordinate (Grob const *refp, Axis a) const
{
- if (refp == this)
+ /* eaa - hmmm, should we do a programming_error() here? */
+ if ((this == NULL) || (refp == this))
return 0.0;
/* We catch PARENT_L_ == nil case with this, but we crash if we did
Real off = 0;
if (dim_cache_[Y_AXIS].offset_)
- off = *dim_cache_[Y_AXIS].offset_;
+ {
+ if (to_boolean (get_property ("pure-Y-offset-in-progress")))
+ programming_error ("cyclic chain in pure-Y-offset callbacks");
+
+ off = *dim_cache_[Y_AXIS].offset_;
+ }
else
{
SCM proc = get_property_data ("Y-offset");
dim_cache_[Y_AXIS].offset_ = new Real (0.0);
+ set_property ("pure-Y-offset-in-progress", SCM_BOOL_T);
off = robust_scm2double (call_pure_function (proc,
scm_list_1 (self_scm ()),
start, end),
0.0);
+ del_property ("pure-Y-offset-in-progress");
delete dim_cache_[Y_AXIS].offset_;
dim_cache_[Y_AXIS].offset_ = 0;
}
if (!iv.is_empty () && is_number_pair (min_ext))
iv.unite (ly_scm2interval (min_ext));
- iv.translate (offset);
+ if (!iv.is_empty ())
+ iv.translate (offset);
return iv;
}
ADD_INTERFACE (Grob,
- "A grob represents a piece of music notation\n"
+ "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"
- "All grobs have an X and Y-position on the page. These X and Y positions\n"
- "are stored in a relative format, so they can easily be combined by\n"
- "stacking them, hanging one grob to the side of another, and coupling\n"
- "them into a grouping objects.\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"
- "Each grob has a reference point (a.k.a. parent): the position of a grob\n"
- "is stored relative to that reference point. For example the X-reference\n"
- "point of a staccato dot usually is the note head that it applies\n"
- "to. When the note head is moved, the staccato dot moves along\n"
- "automatically.\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"
- "A grob is often associated with a symbol, but some grobs do not print\n"
- "any symbols. They take care of grouping objects. For example, there is a\n"
- "separate grob that stacks staves vertically. The @ref{NoteCollision}\n"
- "is also an abstract grob: it only moves around chords, but doesn't print\n"
- "anything.\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"
"\n"
- "Grobs have a properties: Scheme variables, that can be read and set. "
- "They have two types. Immutable variables "
- "define the default style and behavior. They are shared between many objects. "
- "They can be changed using @code{\\override} and @code{\\revert}. "
- "\n\n"
- "Mutable properties are variables that are specific to one grob. Typically, "
- "lists of other objects, or results from computations are stored in"
- "mutable properties: every call to set-grob-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 "
"outside-staff-horizontal-padding "
"outside-staff-padding "
"outside-staff-priority "
+ "pure-Y-offset-in-progress "
"rotation "
"springs-and-rods "
"staff-symbol "
}
-
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;
}