+static void
+set_rods (Drul_array<Interval> const ¤t_extents,
+ Drul_array<Interval> const &previous_extents,
+ Item *current_column,
+ Item *previous_column,
+ Real min_length_fraction)
+{
+ Direction d = UP;
+ do
+ {
+ if (!current_extents[d].is_empty ()
+ && !previous_extents[d].is_empty ())
+ {
+ Real total_head_length = previous_extents[d].length ()
+ + current_extents[d].length ();
+
+ Rod rod;
+ rod.distance_ = total_head_length
+ * (3 / 2 * min_length_fraction)
+ /*
+ we go from right to left.
+ */
+ - previous_extents[d][LEFT]
+ + current_extents[d][RIGHT];
+
+ rod.item_drul_[LEFT] = current_column;
+ rod.item_drul_[RIGHT] = previous_column;
+ rod.add_to_cols ();
+ }
+ }
+ while (flip (&d) != DOWN);
+}
+
+MAKE_SCHEME_CALLBACK (Ledger_line_spanner, set_spacing_rods, 1);
+SCM
+Ledger_line_spanner::set_spacing_rods (SCM smob)
+{
+ Spanner *me = dynamic_cast<Spanner *> (unsmob_grob (smob));
+
+ // find size of note heads.
+ Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
+ if (!staff)
+ return SCM_EOL;
+
+ Real min_length_fraction
+ = robust_scm2double (me->get_property ("minimum-length-fraction"), 0.15);
+
+ Drul_array<Interval> current_extents;
+ Drul_array<Interval> previous_extents;
+ Item *previous_column = 0;
+ Item *current_column = 0;
+
+ Real halfspace = Staff_symbol::staff_space (staff) / 2;
+
+ Interval staff_extent = staff->extent (staff, Y_AXIS);
+ staff_extent *= 1 / halfspace;
+
+ /*
+ Run through heads using a loop. Since Ledger_line_spanner can
+ contain a lot of noteheads, superlinear performance is too slow.
+ */
+ extract_item_set (me, "note-heads", heads);
+ for (vsize i = heads.size (); i--;)
+ {
+ Item *h = heads[i];
+
+ int pos = Staff_symbol_referencer::get_rounded_position (h);
+ if (staff_extent.contains (pos))
+ continue;
+
+ Item *column = h->get_column ();
+ if (current_column != column)
+ {
+ set_rods (current_extents, previous_extents,
+ current_column, previous_column,
+ min_length_fraction);
+
+ previous_column = current_column;
+ current_column = column;
+ previous_extents = current_extents;
+
+ current_extents[DOWN].set_empty ();
+ current_extents[UP].set_empty ();
+ }
+
+ Interval head_extent = h->extent (column, X_AXIS);
+ Direction vdir = Direction (sign (pos));
+ if (!vdir)
+ continue;
+
+ current_extents[vdir].unite (head_extent);
+ }
+
+ if (previous_column && current_column)
+ set_rods (current_extents, previous_extents,
+ current_column, previous_column,
+ min_length_fraction);
+
+ return SCM_UNSPECIFIED;
+}