void
Beam::add_stem (Grob *me, Grob *s)
{
- Pointer_group_interface::add_grob (me, ly_symbol2scm ("stems"), s);
-
- s->add_dependency (me);
+ if (Stem::get_beam (s))
+ {
+ programming_error ("Stem already has beam");
+ return ;
+ }
- assert (!Stem::get_beam (s));
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("stems"), s);
s->set_object ("beam", me->self_scm ());
-
add_bound_item (dynamic_cast<Spanner *> (me), dynamic_cast<Item *> (s));
}
Currenly, this means that beam has set all stem's directions.
[Alternatively, stems could set its own directions, according to
their beam, during 'final-pre-processing'.] */
-MAKE_SCHEME_CALLBACK (Beam, before_line_breaking, 1);
+MAKE_SCHEME_CALLBACK (Beam, calc_direction, 1);
SCM
-Beam::before_line_breaking (SCM smob)
+Beam::calc_direction (SCM smob)
{
Grob *me = unsmob_grob (smob);
return SCM_UNSPECIFIED;
}
}
+
+ Direction d = CENTER;
+
if (count >= 1)
{
- Direction d = get_default_dir (me);
-
+ d = get_default_dir (me);
consider_auto_knees (me);
set_stem_directions (me, d);
set_stem_shorten (me);
}
- return SCM_EOL;
+ return scm_from_int (d);
}
/* We want a maximal number of shared beams, but if there is choice, we
Beam::print (SCM grob)
{
Spanner *me = unsmob_spanner (grob);
- position_beam (me);
extract_grob_set (me, "stems", stems);
Grob *xcommon = common_refpoint_of_array (stems, me, X_AXIS);
total[UP] = total[DOWN] = 0;
Drul_array<int> count;
count[UP] = count[DOWN] = 0;
- Direction d = DOWN;
extract_grob_set (me, "stems", stems);
for (int i = 0; i < stems.size (); i++)
- do
- {
- Grob *s = stems[i];
- Direction sd = get_grob_direction (s);
-
- int center_distance = max (int (- d * Stem::head_positions (s) [-d]), 0);
- int current = sd ? (1 + d * sd) / 2 : center_distance;
-
- if (current)
- {
- total[d] += current;
- count[d]++;
- }
- }
- while (flip (&d) != DOWN);
+ {
+ Grob *s = stems[i];
+ Direction stem_dir = CENTER;
+ SCM stem_dir_scm = s->get_property_data (ly_symbol2scm ("direction"));
+ if (is_direction (stem_dir_scm))
+ stem_dir = to_dir (stem_dir_scm);
+ else
+ stem_dir = Stem::get_default_dir (s);
+
+ if (stem_dir)
+ {
+ count[stem_dir] ++;
+ total[stem_dir] += max (int (- stem_dir * Stem::head_positions (s) [-stem_dir]), 0);
+ }
+ }
SCM func = me->get_property ("dir-function");
SCM s = scm_call_2 (func,
{
Grob *s = stems[i];
- SCM forcedir = s->get_property ("direction");
+ SCM forcedir = s->get_property_data (ly_symbol2scm ("direction"));
if (!to_dir (forcedir))
set_grob_direction (s, d);
}
*/
head_extents += stem->relative_coordinate (common, Y_AXIS);
- if (to_dir (stem->get_property ("direction")))
+ if (to_dir (stem->get_property_data (ly_symbol2scm ("direction"))))
{
Direction stemdir = to_dir (stem->get_property ("direction"));
head_extents[-stemdir] = -stemdir * infinity_f;
me->set_property ("shorten", scm_from_double (shorten_f));
}
-/* Call list of y-dy-callbacks, that handle setting of
- grob-properties
-*/
-MAKE_SCHEME_CALLBACK (Beam, after_line_breaking, 1);
+MAKE_SCHEME_CALLBACK (Beam, calc_positions, 1);
SCM
-Beam::after_line_breaking (SCM smob)
+Beam::calc_positions (SCM smob)
{
Grob *me = unsmob_grob (smob);
-
- position_beam (me);
- return SCM_UNSPECIFIED;
-}
-
-void
-Beam::position_beam (Grob *me)
-{
if (!me->is_live ())
- return;
- if (to_boolean (me->get_property ("positioning-done")))
- return;
-
- me->set_property ("positioning-done", SCM_BOOL_T);
+ return SCM_EOL;
- /* Copy to mutable list. */
- SCM s = ly_deep_copy (me->get_property ("positions"));
- me->set_property ("positions", s);
+ (void) me->get_property ("direction");
+
+ SCM posns = scm_cons (SCM_BOOL_F, SCM_BOOL_F);
+ me->set_property ("positions", posns);
- if (scm_car (s) == SCM_BOOL_F)
- {
- // one wonders if such genericity is necessary --hwn.
- SCM callbacks = me->get_property ("position-callbacks");
- for (SCM i = callbacks; scm_is_pair (i); i = scm_cdr (i))
- scm_call_1 (scm_car (i), me->self_scm ());
- }
+ SCM callbacks = me->get_property ("position-callbacks");
+ for (SCM i = callbacks; scm_is_pair (i); i = scm_cdr (i))
+ scm_call_1 (scm_car (i), me->self_scm ());
+ /*
+ TODO: move this in separate calc function.
+ */
set_stem_lengths (me);
+ return SCM_UNSPECIFIED;
}
+
void
set_minimum_dy (Grob *me, Real *dy)
{
if (scm_is_pair (s) && scm_is_number (scm_car (s)))
pos = ly_scm2interval (s);
else
- {
- /*
- UGH. TODO: fix dependency tracking.
- */
- position_beam (beam);
- pos = ly_scm2interval (beam->get_property ("positions"));
- }
+ programming_error ("positions property should always be pair of numbers.");
Real staff_space = Staff_symbol_referencer::staff_space (rest);
return bc;
}
-ADD_INTERFACE (Beam, "beam-interface",
+ADD_INTERFACE (Beam,
+ "beam-interface",
+
"A beam. \n\n"
"The @code{thickness} property is the weight of beams, "
- "measured in staffspace",
+ "measured in staffspace. The @code{direction} property is not user-serviceable. Use "
+ "the @code{direction} property of @code{Stem} instead. "
+
+ ,
+
+ /* properties */
"auto-knee-gap "
"beamed-stem-shorten "
"break-overshoot "
"concaveness "
"damping "
"details "
+ "direction "
"dir-function "
"flag-width-function "
"gap "
"least-squares-dy "
"neutral-direction "
"position-callbacks "
- "positioning-done "
"positions "
"quant-score "
"shorten "