+ SCM last_beaming = SCM_EOL;;
+ Real last_xposn = -1;
+ Real last_width = -1 ;
+
+
+ SCM gap = me->get_grob_property ("gap");
+ Molecule the_beam;
+ Real lt = me->get_paper ()->get_var ("linethickness");
+ for (int i = 0; i< stems.size(); i++)
+ {
+ Grob * st =stems[i];
+
+ SCM this_beaming = st->get_grob_property ("beaming");
+ Real xposn = st->relative_coordinate (xcommon, X_AXIS);
+ Real stem_width = gh_scm2double (st->get_grob_property ("thickness")) *lt;
+
+ if (i > 0)
+ {
+ SCM left = gh_cdr (last_beaming);
+ SCM right = gh_car (this_beaming);
+
+ Array<int> fullbeams;
+ Array<int> lfliebertjes;
+ Array<int> rfliebertjes;
+
+ for (SCM s = left;
+ gh_pair_p (s); s =gh_cdr (s))
+ {
+ int b = gh_scm2int (gh_car (s));
+ if (scm_memq (gh_car(s), right) != SCM_BOOL_F)
+ {
+ fullbeams.push (b);
+ }
+ else
+ {
+ lfliebertjes.push (b);
+ }
+ }
+ for (SCM s = right;
+ gh_pair_p (s); s =gh_cdr (s))
+ {
+ int b = gh_scm2int (gh_car (s));
+ if (scm_memq (gh_car(s), left) == SCM_BOOL_F)
+ {
+ rfliebertjes.push (b);
+ }
+ }
+
+
+ Real w = xposn - last_xposn;
+ Real stem_offset = 0.0;
+ Real width_corr = 0.0;
+ if (i == 1)
+ {
+ stem_offset -= last_width/2;
+ width_corr += last_width/2;
+ }
+
+ if (i == stems.size() -1)
+ {
+ width_corr += stem_width/2;
+ }
+
+ if (gh_number_p (gap))
+ {
+ Real g = gh_scm2double (gap);
+ stem_offset += g;
+ width_corr -= 2*g;
+ }
+
+ Molecule whole = Lookup::beam (dydx, w + width_corr, thick);
+ for (int j = fullbeams.size(); j--;)
+ {
+ Molecule b (whole);
+ b.translate_axis (last_xposn - x0 + stem_offset, X_AXIS);
+ b.translate_axis (dydx * (last_xposn - x0) + bdy * fullbeams[j], Y_AXIS);
+ the_beam.add_molecule (b);
+ }
+
+ if (lfliebertjes.size() || rfliebertjes.size())
+ {
+
+ Real nw_f;
+ if (!Stem::first_head (st))
+ nw_f = 0;
+ else
+ {
+ int t = Stem::duration_log (st);
+
+ SCM proc = me->get_grob_property ("flag-width-function");
+ SCM result = gh_call1 (proc, scm_int2num (t));
+ nw_f = gh_scm2double (result);
+ }
+
+ /* Half beam should be one note-width,
+ but let's make sure two half-beams never touch */
+
+ Real w = xposn - last_xposn;
+ w = w/2 <? nw_f;
+
+ Molecule half = Lookup::beam (dydx, w, thick);
+ for (int j = lfliebertjes.size(); j--;)
+ {
+ Molecule b (half);
+ b.translate_axis (last_xposn - x0, X_AXIS);
+ b.translate_axis (dydx * (last_xposn-x0) + bdy * lfliebertjes[j], Y_AXIS);
+ the_beam.add_molecule (b);
+ }
+ for (int j = rfliebertjes.size(); j--;)
+ {
+ Molecule b (half);
+ b.translate_axis (xposn - x0 - w , X_AXIS);
+ b.translate_axis (dydx * (xposn-x0 -w) + bdy * rfliebertjes[j], Y_AXIS);
+ the_beam.add_molecule (b);
+ }
+ }
+ }
+
+ last_xposn = xposn;
+ last_width = stem_width;
+ last_beaming = this_beaming;
+ }
+
+ the_beam.translate_axis (x0 - me->relative_coordinate (xcommon, X_AXIS), X_AXIS);
+ the_beam.translate_axis (pos[LEFT], Y_AXIS);
+
+#if (DEBUG_QUANTING)
+ {
+ /*
+ This code prints the demerits for each beam. Perhaps this
+ should be switchable for those who want to twiddle with the
+ parameters.
+ */
+ String str;
+ if (1)
+ {
+ str += to_string (gh_scm2int (me->get_grob_property ("best-idx")));
+ str += ":";
+ }
+ str += to_string (gh_scm2double (me->get_grob_property ("quant-score")),
+ "%.2f");
+
+ SCM properties = Font_interface::font_alist_chain (me);
+
+
+ Molecule tm = Text_item::text2molecule (me, scm_makfrom0str (str.to_str0 ()), properties);
+ the_beam.add_at_edge (Y_AXIS, UP, tm, 5.0);
+ }
+#endif
+
+
+
+ return the_beam.smobbed_copy();