2 arpeggio.cc -- implement Arpeggio
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2004 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "paper-def.hh"
11 #include "arpeggio.hh"
14 #include "staff-symbol-referencer.hh"
15 #include "staff-symbol.hh"
17 #include "font-interface.hh"
21 MAKE_SCHEME_CALLBACK (Arpeggio
, print
, 1);
23 Arpeggio::print (SCM smob
)
25 Grob
*me
= unsmob_grob (smob
);
28 for (SCM s
= me
->get_property ("stems"); ly_pair_p (s
); s
= ly_cdr (s
))
30 Grob
* stem
= unsmob_grob (ly_car (s
));
31 common
= common
->common_refpoint (Staff_symbol_referencer::get_staff_symbol (stem
),
38 Using stems here is not very convenient; should store noteheads
39 instead, and also put them into the support. Now we will mess up
40 in vicinity of a collision.
44 Real my_y
= me
->relative_coordinate (common
, Y_AXIS
);
46 for (SCM s
= me
->get_property ("stems"); ly_pair_p (s
); s
= ly_cdr (s
))
48 Grob
* stem
= unsmob_grob (ly_car (s
));
49 Grob
* ss
= Staff_symbol_referencer::get_staff_symbol (stem
);
50 Interval iv
=Stem::head_positions (stem
);
51 iv
*= Staff_symbol::staff_space (ss
)/2.0;
53 heads
.unite (iv
+ ss
->relative_coordinate (common
, Y_AXIS
)
57 if (heads
.is_empty ())
64 programming_error ("Huh, no heads for arpeggio found.");
68 SCM ad
= me
->get_property ("arpeggio-direction");
69 Direction dir
= CENTER
;
70 if (is_direction (ad
))
76 Font_metric
*fm
=Font_interface::get_default_font (me
);
77 Stencil squiggle
= fm
->find_by_name ("scripts-arpeggio");
82 arrow
= fm
->find_by_name ("scripts-arpeggio-arrow-" + to_string (dir
));
83 heads
[dir
] -= dir
* arrow
.extent (Y_AXIS
).length ();
86 for (Real y
= heads
[LEFT
] ; y
< heads
[RIGHT
];
87 y
+= squiggle
. extent (Y_AXIS
).length ())
88 mol
.add_at_edge (Y_AXIS
, UP
,squiggle
, 0.0, 0);
90 mol
.translate_axis (heads
[LEFT
], Y_AXIS
);
92 mol
.add_at_edge (Y_AXIS
, dir
,arrow
, 0,0);
94 return mol
.smobbed_copy () ;
97 /* Draws a vertical bracket to the left of a chord
98 Chris Jackson <chris@fluffhouse.org.uk> */
100 MAKE_SCHEME_CALLBACK (Arpeggio
, brew_chord_bracket
, 1);
102 Arpeggio::brew_chord_bracket (SCM smob
)
104 Grob
*me
= unsmob_grob (smob
);
107 for (SCM s
= me
->get_property ("stems"); ly_pair_p (s
); s
= ly_cdr (s
))
109 Grob
* stem
= unsmob_grob (ly_car (s
));
110 common
= common
->common_refpoint (Staff_symbol_referencer::get_staff_symbol (stem
),
115 Real my_y
= me
->relative_coordinate (common
, Y_AXIS
);
117 for (SCM s
= me
->get_property ("stems"); ly_pair_p (s
); s
= ly_cdr (s
))
119 Grob
* stem
= unsmob_grob (ly_car (s
));
120 Grob
* ss
= Staff_symbol_referencer::get_staff_symbol (stem
);
121 Interval iv
= Stem::head_positions (stem
);
122 iv
*= Staff_symbol::staff_space (ss
)/2.0;
123 heads
.unite (iv
+ ss
->relative_coordinate (common
, Y_AXIS
) - my_y
);
126 Real lt
= me
->get_paper ()->get_dimension (ly_symbol2scm ("linethickness"));
127 Real sp
= 1.5 * Staff_symbol_referencer::staff_space (me
);
128 Real dy
= heads
.length () + sp
;
131 Stencil
mol (Lookup::bracket (Y_AXIS
, Interval (0, dy
), lt
, x
, lt
));
132 mol
.translate_axis (heads
[LEFT
] - sp
/2.0, Y_AXIS
);
133 return mol
.smobbed_copy ();
138 We have to do a callback, because print () triggers a
139 vertical alignment if it is cross-staff.
141 MAKE_SCHEME_CALLBACK (Arpeggio
, width_callback
,2);
143 Arpeggio::width_callback (SCM smob
, SCM axis
)
145 Grob
* me
= unsmob_grob (smob
);
146 Axis a
= (Axis
)ly_scm2int (axis
);
147 assert (a
== X_AXIS
);
148 Stencil arpeggio
= Font_interface::get_default_font (me
)->find_by_name ("scripts-arpeggio");
150 return ly_interval2scm (arpeggio
.extent (X_AXIS
));
154 ADD_INTERFACE (Arpeggio
, "arpeggio-interface",
155 "Functions and settings for drawing an arpeggio symbol (a wavy line left to noteheads.",
156 "stems arpeggio-direction");