+
+ Real vpos = dir * robust_scm2int (me->get_property ("voiced-position"), 0);
+ pos = vpos;
+
+ if (duration_log > 1)
+ /* Only half notes or longer want alignment with staff lines */
+ return pos;
+
+ /*
+ We need a staff symbol for actually aligning anything
+ */
+ Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
+ if (!staff)
+ return pos;
+
+ std::vector<Real> linepos = Staff_symbol::line_positions (staff);
+
+ if (linepos.empty ())
+ return pos;
+
+ std::sort (linepos.begin (), linepos.end ());
+
+ if (duration_log == 0)
+ {
+ /*
+ lower voice semibreve rests generally hang a line lower
+ */
+
+ if (dir < 0)
+ pos -= 2;
+
+ /*
+ make a semibreve rest hang from the next available line,
+ except when there is none.
+ */
+
+ std::vector<Real>::const_iterator it
+ = std::upper_bound (linepos.begin (), linepos.end (), pos);
+ if (it != linepos.end ())
+ pos = *it;
+ else
+ pos = linepos.back ();
+ }
+ else
+ {
+ std::vector<Real>::const_iterator it
+ = std::upper_bound (linepos.begin (), linepos.end (), pos);
+ if (it != linepos.begin ())
+ --it;
+ pos = *it;
+ }
+
+ /* Finished for neutral position */
+ if (!dir)
+ return pos;
+
+ /* If we have a voiced position, make sure that it's on the
+ proper side of neutral before using it.
+ */
+
+ Real neutral = staff_position_internal (me, duration_log, 0);
+
+ if (dir * (pos - neutral) > 0)
+ return pos;