2 stem-tremolo.cc -- implement Stem_tremolo
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2003 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
24 MAKE_SCHEME_CALLBACK (Stem_tremolo
,dim_callback
,2);
30 Stem_tremolo::dim_callback (SCM e
, SCM
)
32 Grob
* se
= unsmob_grob (e
);
34 Real space
= Staff_symbol_referencer::staff_space (se
);
35 return ly_interval2scm (Interval (-space
, space
));
41 MAKE_SCHEME_CALLBACK (Stem_tremolo
, height
, 2);
43 Stem_tremolo::height (SCM smob
, SCM ax
)
45 Axis a
= (Axis
)gh_scm2int (ax
);
46 Grob
* me
= unsmob_grob (smob
);
49 SCM mol
= me
->get_uncached_molecule ();
51 if (Molecule
*m
= unsmob_molecule (mol
))
52 return ly_interval2scm (m
->extent (a
));
54 return ly_interval2scm (Interval());
58 MAKE_SCHEME_CALLBACK (Stem_tremolo
,brew_molecule
,1);
60 Stem_tremolo::brew_molecule (SCM smob
)
62 Grob
*me
= unsmob_grob (smob
);
63 Grob
* stem
= unsmob_grob (me
->get_grob_property ("stem"));
64 Grob
* beam
= Stem::get_beam (stem
);
70 SCM s
= beam
->get_grob_property ("positions");
73 dy
= -gh_scm2double (gh_car (s
)) +gh_scm2double (gh_cdr (s
));
75 Real dx
= Beam::last_visible_stem (beam
)->relative_coordinate (0, X_AXIS
)
76 - Beam::first_visible_stem (beam
)->relative_coordinate (0, X_AXIS
);
77 dydx
= dx
? dy
/dx
: 0;
83 Real ss
= Staff_symbol_referencer::staff_space (stem
);
84 Real thick
= gh_scm2double (me
->get_grob_property ("beam-thickness"));
85 Real width
= gh_scm2double (me
->get_grob_property ("beam-width"));
89 Molecule
a (Lookup::beam (dydx
, width
, thick
));
90 a
.translate (Offset (-width
/2, width
/ 2 * dydx
));
92 int tremolo_flags
= 0;
93 SCM s
= me
->get_grob_property ("flag-count");
95 tremolo_flags
= gh_scm2int (s
);
99 programming_error ("No tremolo flags?");
106 Who the fuck is 0.81 ?
110 Real beam_translation
= beam
? Beam::get_beam_translation (beam
) : 0.81;
113 for (int i
= 0; i
< tremolo_flags
; i
++)
116 b
.translate_axis (beam_translation
* i
, Y_AXIS
);
117 mol
.add_molecule (b
);
119 Direction stemdir
= Stem::get_direction (stem
);
120 Interval mol_ext
= mol
.extent (Y_AXIS
);
122 // ugh, rather calc from Stem_tremolo_req
123 int beams_i
= (beam
) ? (Stem::beam_multiplicity (stem
).length ()+ 1): 0;
130 Real beamthickness
= 0.0;
131 SCM sbt
= (beam
) ? beam
->get_grob_property ("thickness") : SCM_EOL
;
132 if (gh_number_p (sbt
))
134 beamthickness
= gh_scm2double (sbt
) * ss
;
138 = Stem::stem_end_position (stem
) *ss
/2
139 - stemdir
* (beams_i
* beamthickness
140 + ((beams_i
-1) >? 0) * beam_translation
);
143 the 0.33 ss is to compensate for the size of the note head
145 Real chord_start_y
= Stem::chord_start_y (stem
) +
148 Real padding
= beam_translation
;
151 if there is not enough space, center on remaining space,
152 else one beamspace away from stem end.
154 if (stemdir
* (end_y
- chord_start_y
) - 2*padding
- mol_ext
.length () < 0.0)
156 mol
.translate_axis ((end_y
+ chord_start_y
) /2.0 - mol_ext
.center (),Y_AXIS
);
160 mol
.translate_axis (end_y
- stemdir
* beam_translation
165 return mol
.smobbed_copy ();
170 Stem_tremolo::set_stem (Grob
*me
,Grob
*s
)
172 me
->set_grob_property ("stem", s
->self_scm ());
176 ADD_INTERFACE (Stem_tremolo
,"stem-tremolo-interface",
178 "stem beam-width beam-thickness flag-count");