+ Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS);
+
+ commonx = me->get_bound (LEFT)->common_refpoint (commonx, X_AXIS);
+ commonx = me->get_bound (RIGHT)->common_refpoint (commonx, X_AXIS);
+
+ *common = commonx;
+
+ int gap_count = robust_scm2int (me->get_property ("gap-count"), 0);
+ Real gap_length = robust_scm2double (me->get_property ("gap"), 0.0);
+
+ Position_stem_segments_map stem_segments;
+ Real lt = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
+
+ Slice ranks;
+
+ for (vsize i = 0; i < stems.size (); i++)
+ {
+ Grob *stem = stems[i];
+ Real stem_width = robust_scm2double (stem->get_property ("thickness"), 1.0) * lt;
+ Real stem_x = stem->relative_coordinate (commonx, X_AXIS);
+ SCM beaming = stem->get_property ("beaming");
+ Direction d = LEFT;
+ do
+ {
+ for (SCM s = index_get_cell (beaming, d);
+ scm_is_pair (s); s = scm_cdr (s))
+ {
+ if (!scm_is_integer (scm_car (s)))
+ continue;
+
+ int beam_rank = scm_to_int (scm_car (s));
+ ranks.add_point (beam_rank);
+ }
+
+ for (SCM s = index_get_cell (beaming, d);
+ scm_is_pair (s); s = scm_cdr (s))
+ {
+ if (!scm_is_integer (scm_car (s)))
+ continue;
+
+ int beam_rank = scm_to_int (scm_car (s));
+ Beam_stem_segment seg;
+ seg.stem_ = stem;
+ seg.stem_x_ = stem_x;
+ seg.rank_ = 2 * i + (d+1)/2;
+ seg.width_ = stem_width;
+ seg.stem_index_ = i;
+ seg.dir_ = d;
+ seg.max_connect_ = robust_scm2int (stem->get_property ("max-beam-connect"), 1000);
+
+ Direction stem_dir = get_grob_direction (stem);
+
+ seg.gapped_
+ = (stem_dir * beam_rank < (stem_dir * ranks[-stem_dir] + gap_count));
+ stem_segments[beam_rank].push_back (seg);
+ }
+ }
+ while (flip (&d) != LEFT);
+ }
+
+ Drul_array<Real> break_overshoot
+ = robust_scm2drul (me->get_property ("break-overshoot"),
+ Drul_array<Real> (-0.5, 0.0));
+
+ vector<Beam_segment> segments;
+ for (Position_stem_segments_map::const_iterator i (stem_segments.begin ());
+ i != stem_segments.end (); i++)
+ {
+ vector<Beam_stem_segment> segs = (*i).second;
+ vector_sort (segs, less<Beam_stem_segment> ());
+
+ Beam_segment current;
+
+ int vertical_count = (*i).first;
+ for (vsize j = 0; j < segs.size (); j++)
+ {
+ /*
+ event_dir == LEFT: left edge of a beamsegment.
+ */
+ Direction event_dir = LEFT;
+ do
+ {
+ bool on_bound = (event_dir == LEFT) ? j == 0 :
+ j == segs.size() - 1;
+
+ bool inside_stem = (event_dir == LEFT)
+ ? segs[j].stem_index_ > 0
+ : segs[j].stem_index_ < stems.size () - 1;
+
+ bool event = on_bound
+ || abs (segs[j].rank_ - segs[j+event_dir].rank_) > 1
+ || (abs (vertical_count) >= segs[j].max_connect_
+ || abs (vertical_count) >= segs[j + event_dir].max_connect_);
+
+ if (!event)
+ continue;
+
+ current.vertical_count_ = vertical_count;
+ current.horizontal_[event_dir] = segs[j].stem_x_;
+ if (segs[j].dir_ == event_dir)
+ {
+ if (on_bound
+ && me->get_bound (event_dir)->break_status_dir ())
+ {
+ current.horizontal_[event_dir]
+ = (me->get_bound (event_dir)->extent (commonx, X_AXIS)[RIGHT]
+ + event_dir * break_overshoot[event_dir]);
+ }
+ else
+ {
+ Real notehead_width =
+ Stem::duration_log (segs[j].stem_) == 1
+ ? 1.98
+ : 1.32; // URG.
+
+
+ if (inside_stem)
+ {
+ Grob *neighbor_stem = stems[segs[j].stem_index_ + event_dir];
+ Real neighbor_stem_x = neighbor_stem->relative_coordinate (commonx, X_AXIS);
+
+ notehead_width = min (notehead_width,
+ fabs (neighbor_stem_x - segs[j].stem_x_)/2);
+ }
+ current.horizontal_[event_dir] += event_dir * notehead_width;
+ }
+ }
+ else
+ {
+ current.horizontal_[event_dir] += event_dir * segs[j].width_/2;
+ if (segs[j].gapped_)
+ current.horizontal_[event_dir] -= event_dir * gap_length;
+ }
+
+ if (event_dir == RIGHT)
+ {
+ segments.push_back (current);
+ current = Beam_segment();
+ }
+ }
+ while (flip (&event_dir) != LEFT);
+ }
+
+ }
+
+ return segments;
+}