2 stem-tremolo.cc -- implement Stem_tremolo
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "stem-tremolo.hh"
13 #include "paper-def.hh"
17 #include "staff-symbol-referencer.hh"
18 #include "directional-element-interface.hh"
22 lengthen stem if necessary
26 Stem_tremolo::set_interface (Grob
*me
)
28 me
->set_interface (ly_symbol2scm ("stem-tremolo"));
32 Stem_tremolo::has_interface (Grob
*me
)
34 return me
->has_interface (ly_symbol2scm ("stem-tremolo"));
37 MAKE_SCHEME_CALLBACK(Stem_tremolo
,dim_callback
,2);
43 Stem_tremolo::dim_callback (SCM e
, SCM
)
45 Grob
* se
= unsmob_grob (e
);
47 Real space
= Staff_symbol_referencer::staff_space (se
);
48 return ly_interval2scm ( Interval (-space
, space
));
54 MAKE_SCHEME_CALLBACK (Stem_tremolo
, height
, 2);
56 Stem_tremolo::height (SCM smob
, SCM ax
)
58 Axis a
= (Axis
)gh_scm2int (ax
);
59 Grob
* me
= unsmob_grob (smob
);
60 assert ( a
== Y_AXIS
);
62 SCM mol
= me
->get_uncached_molecule ();
63 return ly_interval2scm (unsmob_molecule (mol
)->extent (a
));
67 MAKE_SCHEME_CALLBACK(Stem_tremolo
,brew_molecule
,1);
69 Stem_tremolo::brew_molecule (SCM smob
)
71 Grob
*me
= unsmob_grob (smob
);
72 Grob
* stem
= unsmob_grob (me
->get_grob_property ("stem"));
73 Grob
* beam
= Stem::beam_l (stem
);
79 SCM s
= beam
->get_grob_property ("height");
81 dy
= gh_scm2double (s
);
82 Real dx
= Beam::last_visible_stem (beam
)->relative_coordinate (0, X_AXIS
)
83 - Beam::first_visible_stem (beam
)->relative_coordinate (0, X_AXIS
);
84 dydx
= dx
? dy
/dx
: 0;
90 Real ss
= Staff_symbol_referencer::staff_space (stem
);
91 Real thick
= gh_scm2double (me
->get_grob_property ("beam-thickness"));
92 Real width
= gh_scm2double (me
->get_grob_property ("beam-width"));
96 Molecule
a (Lookup::beam (dydx
, width
, thick
));
97 a
.translate (Offset (-width
/2, width
/ 2 * dydx
));
100 SCM s
= me
->get_grob_property ("tremolo-flags");
102 tremolo_flags
= gh_scm2int (s
);
107 int mult
= beam
? Beam::get_multiplicity (beam
) : 0;
108 SCM space_proc
= me
->get_grob_property ("beam-space-function");
109 SCM space
= gh_call1 (space_proc
, gh_int2scm (mult
));
110 Real interbeam_f
= gh_scm2double (space
) * ss
;
114 for (int i
= 0; i
< tremolo_flags
; i
++)
117 b
.translate_axis (interbeam_f
* i
, Y_AXIS
);
118 mol
.add_molecule (b
);
121 mol
.translate_axis (-mol
.extent (Y_AXIS
).center (), Y_AXIS
);
124 // ugh, rather calc from Stem_tremolo_req
125 int beams_i
= Stem::beam_count(stem
, RIGHT
) >? Stem::beam_count (stem
, LEFT
);
126 mol
.translate (Offset(stem
->relative_coordinate (0, X_AXIS
) - me
->relative_coordinate (0, X_AXIS
),
127 Stem::stem_end_position (stem
) * ss
/ 2 -
128 Directional_element_interface::get (beam
) * beams_i
* interbeam_f
));
133 Beams should intersect one beamthickness below stem end
135 Real dy
= Stem::stem_end_position (stem
) * ss
/ 2;
136 dy
-= mol
.extent (Y_AXIS
).length () / 2 * Stem::get_direction (stem
);
139 uhg. Should use relative coords and placement
141 Real whole_note_correction
;
142 if (Stem::invisible_b (stem
))
144 Grob
*hed
= Stem::support_head (stem
);
145 whole_note_correction
= -Stem::get_direction (stem
)
146 *hed
->extent (hed
, X_AXIS
).length () / 2;
149 whole_note_correction
= 0;
151 mol
.translate (Offset (stem
->relative_coordinate (0, X_AXIS
) - me
->relative_coordinate (0, X_AXIS
) +
152 whole_note_correction
, dy
));
155 return mol
.smobbed_copy ();
160 Stem_tremolo::set_stem (Grob
*me
,Grob
*s
)
162 me
->set_grob_property ("stem", s
->self_scm ());