return SCM_UNSPECIFIED;
}
+LY_DEFINE (ly_grob_pure_property, "ly:grob-pure-property",
+ 4, 1, 0, (SCM grob, SCM sym, SCM beg, SCM end, SCM val),
+ "Return the pure value for property @var{sym} of @var{grob}."
+ " If no value is found, return @var{val} or @code{'()}"
+ " if @var{val} is not specified.")
+{
+ Grob *sc = unsmob_grob (grob);
+
+ LY_ASSERT_SMOB (Grob, grob, 1);
+ LY_ASSERT_TYPE (ly_is_symbol, sym, 2);
+ LY_ASSERT_TYPE (scm_is_integer, beg, 3);
+ LY_ASSERT_TYPE (scm_is_integer, end, 4);
+ if (val == SCM_UNDEFINED)
+ val = SCM_EOL;
+
+ SCM retval = sc->internal_get_pure_property (sym, scm_to_int (beg), scm_to_int (end));
+ if (retval == SCM_EOL)
+ retval = val;
+
+ return retval;
+}
+
LY_DEFINE (ly_grob_property, "ly:grob-property",
2, 1, 0, (SCM grob, SCM sym, SCM val),
"Return the value for property @var{sym} of @var{grob}."
me->warning (_ ("weird stem size, check for narrow beams"));
Interval height = me->pure_height (me, 0, INT_MAX);
- Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
+ Real staff_space = Staff_symbol_referencer::staff_space (me);
+ Real half_space = staff_space * 0.5;
height[d] = se * half_space + beam_end_corrective (me);
me->programming_error ("Can't have a stemlet without a beam.");
}
- me->set_property ("Y-extent", ly_interval2scm (height));
+ me->set_property ("stem-begin-position", scm_from_double (height[-d] * 2 / staff_space));
+ me->set_property ("length", scm_from_double (height.length () * 2 / staff_space));
+ (void) me->extent (me, Y_AXIS);
}
/* Note head that determines hshift for upstems
Grob *beam = get_beam (me);
Real ss = Staff_symbol_referencer::staff_space (me);
+ Direction dir = get_grob_direction (me);
+
if (beam && calc_beam)
{
(void) beam->get_property ("quantized-positions");
- return me->extent (me, Y_AXIS)[get_grob_direction (me)] * ss * 2;
+ return robust_scm2double (me->get_property ("length"), 0.0)
+ + dir * robust_scm2double (me->get_property ("stem-begin-position"), 0.0);
}
vector<Real> a;
if (scm_is_pair (s))
length = 2 * scm_to_double (robust_list_ref (durlog - 2, s));
- Direction dir = get_grob_direction (me);
/* Stems in unnatural (forced) direction should be shortened,
according to [Roush & Gourlay] */
Interval
Stem::internal_height (Grob *me, bool calc_beam)
{
- if (!is_valid_stem (me))
+ Grob *beam = get_beam (me);
+ if (!is_valid_stem (me) && ! beam)
return Interval ();
Direction dir = get_grob_direction (me);
- Grob *beam = get_beam (me);
if (beam && calc_beam)
{
/* trigger set-stem-lengths. */
(void) beam->get_property ("quantized-positions");
- return me->extent (me, Y_AXIS);
}
- Real y2 = internal_calc_stem_end_position (me, calc_beam);
- Real y1 = internal_calc_stem_begin_position (me, calc_beam);
+ Real y1 = robust_scm2double ((calc_beam
+ ? me->get_property ("stem-begin-position")
+ : me->get_pure_property ("stem-begin-position", 0, INT_MAX)),
+ 0.0);
+
+ Real y2 = dir * robust_scm2double ((calc_beam
+ ? me->get_property ("length")
+ : me->get_pure_property ("length", 0, INT_MAX)),
+ 0.0)
+ + y1;
Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
Interval stem_y = Interval (min (y1, y2), max (y2, y1)) * half_space;
- stem_y[dir] += beam_end_corrective (me);
return stem_y;
}
if (beam && calc_beam)
{
(void) beam->get_property ("quantized-positions");
- return me->extent (me, Y_AXIS)[-get_grob_direction (me)] * ss * 2;
+ return robust_scm2double (me->get_property ("stem-begin-position"), 0.0);
}
Direction d = get_grob_direction (me);
Grob *lh = get_reference_head (me);
+ if (!lh)
+ return 0.0;
+
Real pos = Staff_symbol_referencer::get_position (lh);
if (Grob *head = support_head (me))
{
/* TODO: make the stem start a direction ?
This is required to avoid stems passing in tablature chords. */
- Real stemlet_length = robust_scm2double (me->get_property ("stemlet-length"),
- 0.0);
- bool stemlet = stemlet_length > 0.0;
-
Grob *lh = get_reference_head (me);
Grob *beam = unsmob_grob (me->get_object ("beam"));
- if (!lh && !stemlet)
- return false;
-
- if (!lh && stemlet && !beam)
+ if (!lh && !beam)
return false;
if (lh && robust_scm2int (lh->get_property ("duration-log"), 0) < 1)
if (!is_valid_stem (me))
return SCM_EOL;
- Interval stem_y = me->extent (me, Y_AXIS);
Direction dir = get_grob_direction (me);
+ Real y1 = robust_scm2double (me->get_property ("stem-begin-position"), 0.0);
+ Real y2 = dir * robust_scm2double (me->get_property ("length"), 0.0) + y1;
+
+ Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5;
+
+ Interval stem_y = Interval (min (y1, y2), max (y2, y1)) * half_space;
stem_y[dir] -= beam_end_corrective (me);
"duration-log "
"flag "
"french-beaming "
+ "length "
"length-fraction "
"max-beam-connect "
"neutral-direction "
"note-heads "
"positioning-done "
"rests "
+ "stem-begin-position "
"stem-info "
"stemlet-length "
"thickness "
(direction . ,ly:stem::calc-direction)
(duration-log . ,stem::calc-duration-log)
+ (length . ,stem::length)
(neutral-direction . ,DOWN)
(positioning-done . ,ly:stem::calc-positioning-done)
(stem-info . ,ly:stem::calc-stem-info)
+ (stem-begin-position . ,ly:stem::calc-stem-begin-position)
(stencil . ,ly:stem::print)
(thickness . 1.3)
(X-extent . ,ly:stem::width)
(,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback)
(,ly:stem::calc-stem-begin-position . ,ly:stem::pure-calc-stem-begin-position)
(,ly:stem::calc-stem-end-position . ,ly:stem::pure-calc-stem-end-position)
+ (,stem::length . ,stem::pure-length)
(,ly:stem::height . ,ly:stem::pure-height)
(,ly:stem-tremolo::calc-y-offset . ,ly:stem-tremolo::pure-calc-y-offset)
(,ly:system::height . ,ly:system::calc-pure-height)))
(ly:duration-log
(ly:event-property (event-cause grob) 'duration)))
-(define-public (stem::length val)
- (lambda (grob)
- (let* ((d (ly:grob-property grob 'direction))
- (ss (ly:staff-symbol-staff-space grob))
- (beg (ly:stem::calc-stem-begin-position grob))
- (y1 (* beg (* 0.5 ss)))
- (y2 (* ((if (eqv? d DOWN) - +) beg val) (* 0.5 ss))))
- (if (eqv? d DOWN)
- (cons y2 y1)
- (cons y1 y2)))))
+(define-public (stem::length grob)
+ (let* ((d (ly:grob-property grob 'direction))
+ (ss (ly:staff-symbol-staff-space grob))
+ (beg (ly:grob-property grob 'stem-begin-position))
+ (beam (ly:grob-object grob 'beam)))
+ (if (null? beam)
+ (abs (- (ly:stem::calc-stem-end-position grob) beg))
+ (ly:grob-property grob 'length))))
+
+(define-public (stem::pure-length grob beg end)
+ (let* ((d (ly:grob-property grob 'direction))
+ (ss (ly:staff-symbol-staff-space grob))
+ (beg (ly:grob-pure-property grob 'stem-begin-position 0 1000)))
+ (abs (- (ly:stem::pure-calc-stem-end-position grob 0 2147483646) beg))))
(define-public (note-head::calc-duration-log grob)
(min 2