+ Grob *me = unsmob_grob (smob);
+
+ Grob * common = me;
+ for (SCM s = me->get_property ("stems"); gh_pair_p (s); s = ly_cdr (s))
+ {
+ Grob * stem = unsmob_grob (ly_car (s));
+ common = common->common_refpoint (Staff_symbol_referencer::get_staff_symbol (stem),
+ Y_AXIS);
+ }
+
+ /*
+ TODO:
+
+ Using stems here is not very convenient; should store noteheads
+ instead, and also put them into the support. Now we will mess up
+ in vicinity of a collision.
+
+ */
+ Interval heads;
+ Real my_y = me->relative_coordinate (common, Y_AXIS);
+
+ for (SCM s = me->get_property ("stems"); gh_pair_p (s); s = ly_cdr (s))
+ {
+ Grob * stem = unsmob_grob (ly_car (s));
+ Grob * ss = Staff_symbol_referencer::get_staff_symbol (stem);
+ Interval iv =Stem::head_positions (stem);
+ iv *= Staff_symbol::staff_space (ss)/2.0;
+
+ heads.unite (iv + ss->relative_coordinate (common, Y_AXIS)
+ - my_y);
+ }
+
+ if (heads.is_empty ())
+ {
+ /*
+ Dumb blonde error
+
+ :-)
+ */
+ programming_error ("Huh, no heads for arpeggio found.");
+ return SCM_EOL;
+ }
+
+ SCM ad = me->get_property ("arpeggio-direction");
+ Direction dir = CENTER;
+ if (is_direction (ad))
+ {
+ dir = to_dir (ad);
+ }
+
+ Stencil mol;
+ Font_metric *fm =Font_interface::get_default_font (me);
+ Stencil squiggle = fm->find_by_name ("scripts-arpeggio");
+
+ Stencil arrow ;
+ if (dir)
+ {
+ arrow = fm->find_by_name ("scripts-arpeggio-arrow-" + to_string (dir));
+ heads[dir] -= dir * arrow.extent (Y_AXIS).length();
+ }
+
+ for (Real y= heads[LEFT] ; y < heads[RIGHT];
+ y+= squiggle. extent (Y_AXIS).length ())
+ mol.add_at_edge (Y_AXIS, UP,squiggle, 0.0, 0);
+
+ mol.translate_axis (heads[LEFT], Y_AXIS);
+ if (dir)
+ mol.add_at_edge (Y_AXIS, dir,arrow, 0,0);
+
+ return mol.smobbed_copy () ;