2 stem-tremolo.cc -- implement Stem_tremolo
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "stem-tremolo.hh"
13 #include "directional-element-interface.hh"
16 #include "output-def.hh"
17 #include "staff-symbol-referencer.hh"
21 /* TODO: lengthen stem if necessary */
23 MAKE_SCHEME_CALLBACK (Stem_tremolo
, dim_callback
, 2);
25 /* todo: init with cons. */
27 Stem_tremolo::dim_callback (SCM e
, SCM
)
29 Grob
*se
= unsmob_grob (e
);
31 Real space
= Staff_symbol_referencer::staff_space (se
);
32 return ly_interval2scm (Interval (-space
, space
));
35 /* ugh ? --from Slur */
36 MAKE_SCHEME_CALLBACK (Stem_tremolo
, height
, 2);
38 Stem_tremolo::height (SCM smob
, SCM ax
)
40 Axis a
= (Axis
)scm_to_int (ax
);
41 Grob
*me
= unsmob_grob (smob
);
44 SCM mol
= me
->get_uncached_stencil ();
46 if (Stencil
*m
= unsmob_stencil (mol
))
47 return ly_interval2scm (m
->extent (a
));
49 return ly_interval2scm (Interval ());
53 Stem_tremolo::raw_stencil (Grob
*me
)
55 Grob
*stem
= unsmob_grob (me
->get_property ("stem"));
56 Spanner
*beam
= Stem::get_beam (stem
);
61 SCM s
= beam
->get_property ("positions");
62 if (is_number_pair (s
))
63 dy
= -scm_to_double (scm_car (s
)) +scm_to_double (scm_cdr (s
));
65 Real dx
= Beam::last_visible_stem (beam
)->relative_coordinate (0, X_AXIS
)
66 - Beam::first_visible_stem (beam
)->relative_coordinate (0, X_AXIS
);
67 dydx
= dx
? dy
/ dx
: 0;
73 Real ss
= Staff_symbol_referencer::staff_space (me
);
74 Real thick
= robust_scm2double (me
->get_property ("beam-thickness"), 1);
75 Real width
= robust_scm2double (me
->get_property ("beam-width"), 1);
76 Real blot
= me
->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter"));
81 Stencil
a (Lookup::beam (dydx
, width
, thick
, blot
));
82 a
.translate (Offset (-width
* 0.5, width
* 0.5 * dydx
));
84 int tremolo_flags
= 0;
85 SCM s
= me
->get_property ("flag-count");
86 if (scm_is_number (s
))
87 tremolo_flags
= scm_to_int (s
);
91 programming_error ("no tremolo flags");
97 /* Who the fuck is 0.81 ? --hwn. */
98 Real beam_translation
= beam
? Beam::get_beam_translation (beam
) : 0.81;
101 for (int i
= 0; i
< tremolo_flags
; i
++)
104 b
.translate_axis (beam_translation
* i
, Y_AXIS
);
110 MAKE_SCHEME_CALLBACK (Stem_tremolo
, print
, 1);
112 Stem_tremolo::print (SCM grob
)
114 Grob
*me
= unsmob_grob (grob
);
115 Grob
*stem
= unsmob_grob (me
->get_property ("stem"));
118 programming_error ("no stem for stem-tremolo");
122 Spanner
*beam
= Stem::get_beam (stem
);
123 Direction stemdir
= Stem::get_direction (stem
);
127 Real beam_translation
128 = (beam
&& beam
->is_live ())
129 ? Beam::get_beam_translation (beam
)
132 Stencil mol
= raw_stencil (me
);
133 Interval mol_ext
= mol
.extent (Y_AXIS
);
134 Real ss
= Staff_symbol_referencer::staff_space (me
);
136 // ugh, rather calc from Stem_tremolo_req
137 int beam_count
= beam
? (Stem::beam_multiplicity (stem
).length () + 1) : 0;
139 Real beamthickness
= 0.0;
140 SCM sbt
= (beam
) ? beam
->get_property ("thickness") : SCM_EOL
;
141 if (scm_is_number (sbt
))
142 beamthickness
= scm_to_double (sbt
) * ss
;
145 = Stem::stem_end_position (stem
) * ss
/ 2
146 - stemdir
* (beam_count
* beamthickness
147 + (max (beam_count
-1, 0) * beam_translation
));
149 /* FIXME: the 0.33 ss is to compensate for the size of the note head. */
150 Real chord_start_y
= Stem::chord_start_y (stem
) + 0.33 * ss
* stemdir
;
152 Real padding
= beam_translation
;
154 /* if there is a flag, just above/below the notehead.
155 if there is not enough space, center on remaining space,
156 else one beamspace away from stem end. */
157 if (!beam
&& Stem::duration_log (stem
) >= 3)
159 mol
.align_to (Y_AXIS
, -stemdir
);
160 mol
.translate_axis (chord_start_y
+ 0.5 * stemdir
, Y_AXIS
);
162 else if (stemdir
* (end_y
- chord_start_y
) - 2 * padding
- mol_ext
.length ()
164 mol
.translate_axis (0.5 * (end_y
+ chord_start_y
) - mol_ext
.center (),
167 mol
.translate_axis (end_y
- stemdir
* beam_translation
-mol_ext
[stemdir
],
170 return mol
.smobbed_copy ();
173 ADD_INTERFACE (Stem_tremolo
, "stem-tremolo-interface",
174 "A beam slashing a stem to indicate a tremolo.",
175 "stem beam-width beam-thickness flag-count");