#include <math.h> // tanh.
+#include "interval-set.hh"
#include "stencil.hh"
#include "directional-element-interface.hh"
#include "beaming.hh"
Beam::get_beam_count (Grob *me)
{
int m = 0;
- for (SCM s = me->get_property ("stems"); ly_c_pair_p (s); s = ly_cdr (s))
+ for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s))
{
- Grob *stem = unsmob_grob (ly_car (s));
+ Grob *stem = unsmob_grob (scm_car (s));
m = m >? (Stem::beam_multiplicity (stem).length () + 1);
}
return m;
{
me->warning (_ ("removing beam with less than two stems"));
- unsmob_grob (ly_car (stems))->set_property ("beam", SCM_EOL);
+ unsmob_grob (scm_car (stems))->set_property ("beam", SCM_EOL);
me->suicide ();
return SCM_UNSPECIFIED;
Direction left_dir,
Direction right_dir)
{
- Slice lslice = int_list_to_slice (ly_cdr (left_beaming));
+ Slice lslice = int_list_to_slice (scm_cdr (left_beaming));
int best_count = 0;
int best_start = 0;
(i - lslice[left_dir])* left_dir <= 0 ; i+= left_dir)
{
int count =0;
- for ( SCM s = ly_car (right_beaming); ly_c_pair_p (s); s = ly_cdr (s))
+ for ( SCM s = scm_car (right_beaming); scm_is_pair (s); s = scm_cdr (s))
{
- int k = - right_dir * scm_to_int (ly_car (s)) + i;
+ int k = - right_dir * scm_to_int (scm_car (s)) + i;
if (scm_c_memq (scm_int2num (k), left_beaming) != SCM_BOOL_F)
count ++;
}
SCM this_beaming = this_stem->get_property ("beaming");
Direction this_dir = get_grob_direction (this_stem);
- if (ly_c_pair_p (last_beaming) && ly_c_pair_p (this_beaming))
+ if (scm_is_pair (last_beaming) && scm_is_pair (this_beaming))
{
int start_point = position_with_maximal_common_beams
(last_beaming, this_beaming,
new_slice.set_empty ();
SCM s = index_get_cell (this_beaming, d);
- for (; ly_c_pair_p (s); s = ly_cdr (s))
+ for (; scm_is_pair (s); s = scm_cdr (s))
{
int new_beam_pos =
- start_point - this_dir * scm_to_int (ly_car (s));
+ start_point - this_dir * scm_to_int (scm_car (s));
new_slice.add_point (new_beam_pos);
scm_set_car_x (s, scm_int2num (new_beam_pos));
else
{
scm_set_car_x ( this_beaming, SCM_EOL);
- SCM s = ly_cdr (this_beaming);
- for (; ly_c_pair_p (s); s = ly_cdr (s))
+ SCM s = scm_cdr (this_beaming);
+ for (; scm_is_pair (s); s = scm_cdr (s))
{
- int np = - this_dir * scm_to_int (ly_car (s));
+ int np = - this_dir * scm_to_int (scm_car (s));
scm_set_car_x (s, scm_int2num (np));
last_int.add_point (np);
}
scm_set_cdr_x (this_beaming, SCM_EOL);
}
- if (scm_ilength (ly_cdr (this_beaming)) > 0)
+ if (scm_ilength (scm_cdr (this_beaming)) > 0)
{
last_beaming = this_beaming;
last_dir = this_dir;
Real gap_length = robust_scm2double (me->get_property ("gap"), 0.0);
Stencil the_beam;
- Real lt = me->get_paper ()->get_dimension (ly_symbol2scm ("linethickness"));
+ Real lt = me->get_layout ()->get_dimension (ly_symbol2scm ("linethickness"));
for (int i = 0; i<= stems.size (); i++)
{
right from the left stem, and rfliebertjes pointing left from
right stem.
*/
- SCM left = (i > 0) ? ly_cdr (last_beaming) : SCM_EOL;
- SCM right = st ? ly_car (this_beaming) : SCM_EOL;
+ SCM left = (i > 0) ? scm_cdr (last_beaming) : SCM_EOL;
+ SCM right = st ? scm_car (this_beaming) : SCM_EOL;
Array<int> full_beams;
Array<int> lfliebertjes;
Array<int> rfliebertjes;
for (SCM s = left;
- ly_c_pair_p (s); s =ly_cdr (s))
+ scm_is_pair (s); s =scm_cdr (s))
{
- int b = scm_to_int (ly_car (s));
- if (scm_c_memq (ly_car (s), right) != SCM_BOOL_F)
+ int b = scm_to_int (scm_car (s));
+ if (scm_c_memq (scm_car (s), right) != SCM_BOOL_F)
{
full_beams.push (b);
}
}
}
for (SCM s = right;
- ly_c_pair_p (s); s =ly_cdr (s))
+ scm_is_pair (s); s =scm_cdr (s))
{
- int b = scm_to_int (ly_car (s));
- if (scm_c_memq (ly_car (s), left) == SCM_BOOL_F)
+ int b = scm_to_int (scm_car (s));
+ if (scm_c_memq (scm_car (s), left) == SCM_BOOL_F)
{
rfliebertjes.push (b);
}
w += stem_width/ 2 ;
- Real blot = me->get_paper ()->get_dimension (ly_symbol2scm ("blotdiameter"));
+ Real blot = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter"));
Stencil whole = Lookup::beam (slope, w, thick, blot);
Stencil gapped;
#if (DEBUG_QUANTING)
SCM quant_score = me->get_property ("quant-score");
- if (to_boolean (me->get_paper ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting")))
+ if (to_boolean (me->get_layout ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting")))
&& scm_is_string (quant_score))
{
Direction stem_dir = stems.size() ? to_dir (stems[0]->get_property ("direction")) : UP;
- Stencil tm = *unsmob_stencil (Text_item::interpret_markup
- (me->get_paper ()->self_scm (), properties, quant_score));
+ Stencil tm = *unsmob_stencil (Text_interface::interpret_markup
+ (me->get_layout ()->self_scm (), properties, quant_score));
the_beam.add_at_edge (Y_AXIS, stem_dir, tm, 1.0, 0);
}
#endif
}
}
-/*
- A union of intervals in the real line.
-
- Abysmal performance (quadratic) for large N, hopefully we don't have
- that large N. In any case, this should probably be rewritten to use
- a balanced tree.
- */
-struct Int_set
-{
- Array<Interval> allowed_regions_;
-
- Int_set ()
- {
- set_full ();
- }
-
- void set_full ()
- {
- allowed_regions_.clear ();
- Interval s;
- s.set_full ();
- allowed_regions_.push (s);
- }
-
- void remove_interval (Interval rm)
- {
- for (int i = 0; i < allowed_regions_.size (); )
- {
- Interval s = rm;
-
- s.intersect (allowed_regions_[i]);
-
- if (!s.is_empty ())
- {
- Interval before = allowed_regions_[i];
- Interval after = allowed_regions_[i];
-
- before[RIGHT] = s[LEFT];
- after[LEFT] = s[RIGHT];
-
- if (!before.is_empty () && before.length () > 0.0)
- {
- allowed_regions_.insert (before, i);
- i++;
- }
- allowed_regions_.del (i);
- if (!after.is_empty () && after.length () > 0.0)
- {
- allowed_regions_.insert (after, i);
- i++;
- }
- }
- else
- i++;
- }
- }
-};
-
-
/*
Only try horizontal beams for knees. No reliable detection of
anything else is possible here, since we don't know funky-beaming
Real threshold = scm_to_double (scm);
- Int_set gaps;
+ Interval_set gaps;
gaps.set_full ();
void
Beam::position_beam (Grob *me)
{
+ if (!me->is_live ())
+ return ;
if (to_boolean (me->get_property ("positioning-done")))
return ;
SCM s = ly_deep_copy (me->get_property ("positions"));
me->set_property ("positions", s);
- if (ly_car (s) == SCM_BOOL_F)
+ 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; ly_c_pair_p (i); i = ly_cdr (i))
- scm_call_1 (ly_car (i), me->self_scm ());
+ for (SCM i = callbacks; scm_is_pair (i); i = scm_cdr (i))
+ scm_call_1 (scm_car (i), me->self_scm ());
}
set_stem_lengths (me);
}
+void
+set_minimum_dy (Grob *me, Real * dy)
+{
+ if (*dy)
+ {
+ /*
+ If dy is smaller than the smallest quant, we
+ get absurd direction-sign penalties.
+ */
+
+ Real ss = Staff_symbol_referencer::staff_space (me);
+ Real thickness = Beam::get_thickness (me) / ss ;
+ Real slt = Staff_symbol_referencer::line_thickness (me) / ss;
+ Real sit = (thickness - slt) / 2;
+ Real inter = 0.5;
+ Real hang = 1.0 - (thickness - slt) / 2;
+
+ *dy = sign (*dy) * (fabs (*dy)
+ >?
+ (sit <? inter <? hang));
+ }
+}
+
/*
Compute a first approximation to the beam slope.
*/
minimise_least_squares (&slope, &y, ideals);
dy = slope * dx;
+
+ set_minimum_dy (me,&dy);
me->set_property ("least-squares-dy", scm_make_real (dy));
pos = Interval (y, (y+dy));
}
We can't combine with previous function, since check concave and
slope damping comes first.
-TODO: we should use the concaveness to control the amount of damping
-applied.
+ TODO: we should use the concaveness to control the amount of damping
+ applied.
- */
+*/
MAKE_SCHEME_CALLBACK (Beam, shift_region_to_valid, 1);
SCM
Beam::shift_region_to_valid (SCM grob)
slope = 0.6 * tanh (slope) / (damping + concaveness);
Real damped_dy = slope * dx;
+
+ set_minimum_dy (me, &damped_dy);
+
pos[LEFT] += (dy - damped_dy) / 2;
pos[RIGHT] -= (dy - damped_dy) / 2;
{
Slice l;
- for ( SCM s = ly_car (beaming); ly_c_pair_p (s) ; s = ly_cdr (s))
+ for ( SCM s = scm_car (beaming); scm_is_pair (s) ; s = scm_cdr (s))
{
- if (scm_c_memq (ly_car (s), ly_cdr (beaming)) != SCM_BOOL_F)
+ if (scm_c_memq (scm_car (s), scm_cdr (beaming)) != SCM_BOOL_F)
- l.add_point (scm_to_int (ly_car (s)));
+ l.add_point (scm_to_int (scm_car (s)));
}
return l;
Drul_array<Real> pos (0, 0);
SCM s = beam->get_property ("positions");
- if (ly_c_pair_p (s) && scm_is_number (ly_car (s)))
+ if (scm_is_pair (s) && scm_is_number (scm_car (s)))
pos = ly_scm2interval (s);
Real staff_space = Staff_symbol_referencer::staff_space (rest);
bool knee = false;
int d = 0;
- for (SCM s = me->get_property ("stems"); ly_c_pair_p (s); s = ly_cdr (s))
+ for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s))
{
- Direction dir = get_grob_direction (unsmob_grob (ly_car (s)));
+ Direction dir = get_grob_direction (unsmob_grob (scm_car (s)));
if (d && d != dir)
{
knee = true;