]> git.donarmstrong.com Git - lilypond.git/blob - lily/stem-tremolo.cc
patch::: 1.3.32.jcn1
[lilypond.git] / lily / stem-tremolo.cc
1 /*   
2   stem-tremolo.cc --  implement Stem_tremolo
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "stem-tremolo.hh"
11 #include "debug.hh"
12 #include "beam.hh"
13 #include "paper-def.hh"
14 #include "lookup.hh"
15 #include "stem.hh"
16 #include "offset.hh"
17 #include "dimension-cache.hh"
18 #include "staff-symbol-referencer.hh"
19 #include "directional-element-interface.hh"
20
21 /*
22   TODO:
23     lengthen stem if necessary
24  */
25
26 Stem_tremolo::Stem_tremolo ()
27 {
28   set_elt_property ("stem", SCM_EOL);
29 }
30
31
32 Stem *
33 Stem_tremolo::stem_l ()const
34 {
35   SCM s =   get_elt_property ("stem");
36
37   return dynamic_cast<Stem*> (  unsmob_element (s));
38 }
39
40 Interval
41 Stem_tremolo::dim_callback (Dimension_cache const *c) 
42 {
43   Stem_tremolo * s = dynamic_cast<Stem_tremolo*> (c->element_l ());
44   Real space = Staff_symbol_referencer_interface (s->stem_l ())
45     .staff_space ();
46   return Interval (-space, space);
47 }
48
49
50 Molecule 
51 Stem_tremolo::do_brew_molecule () const
52 {
53   Stem * stem = stem_l ();
54   Beam * beam = stem->beam_l ();
55   
56   Real dydx;
57   if (beam)
58     {
59       Real dy = 0;
60       SCM s = beam->get_elt_property ("height");
61       if (gh_number_p (s))
62         dy = gh_scm2double (s);
63       Real dx = beam->last_visible_stem ()->hpos_f ()
64         - beam->first_visible_stem ()->hpos_f ();
65       dydx = dx ? dy/dx : 0;
66     }
67   else
68     // urg
69     dydx = 0.25;
70
71   Real thick = gh_scm2double (get_elt_property ("beam-thickness"));
72   Real width = gh_scm2double (get_elt_property ("beam-width"));
73   Molecule a (lookup_l ()->beam (dydx, width, thick));
74   a.translate (Offset (-width/2, width / 2 * dydx));
75   
76   int tremolo_flags;
77   SCM s = get_elt_property ("tremolo-flags");
78   if (gh_number_p (s))
79     tremolo_flags = gh_scm2int (s);
80   else
81     // huh?
82     tremolo_flags = 1;
83
84   int mult = beam ? beam->get_multiplicity () : 0;
85   Real interbeam_f = paper_l ()->interbeam_f (mult);
86   Molecule mol; 
87   for (int i = 0; i < tremolo_flags; i++)
88     {
89       Molecule b (a);
90       b.translate_axis (interbeam_f * i, Y_AXIS);
91       mol.add_molecule (b);
92     }
93   if (tremolo_flags)
94     mol.translate_axis (-mol.extent ()[Y_AXIS].center (), Y_AXIS);
95
96   Real half_space = Staff_symbol_referencer_interface (stem).staff_space ()
97     / 2;
98   if (beam)
99     {
100       // ugh, rather calc from Stem_tremolo_req
101       int beams_i = stem->beam_count(RIGHT) >? stem->beam_count (LEFT);
102       mol.translate (Offset(stem->hpos_f () - hpos_f (),
103                             stem->stem_end_position () * half_space - 
104                             directional_element (beam).get () * beams_i * interbeam_f));
105     }
106   else
107     {  
108       /*
109         Beams should intersect one beamthickness below stem end
110       */
111       Real dy = stem->stem_end_position () * half_space;
112       dy -= mol.extent ()[Y_AXIS].length () / 2 *  stem->get_direction ();
113
114       /*
115         uhg.  Should use relative coords and placement
116       */
117       Real whole_note_correction;
118       if (stem->invisible_b ())
119         whole_note_correction = -stem->get_direction ()
120           * stem->support_head ()->extent (X_AXIS).length () / 2;
121       else
122         whole_note_correction = 0;
123          
124       mol.translate (Offset (stem->hpos_f () - hpos_f () +
125                              whole_note_correction, dy));
126     }
127   
128   return mol;
129 }
130
131
132 void
133 Stem_tremolo::set_stem (Stem *s)
134 {
135   set_elt_property ("stem", s->self_scm_);
136   add_dependency (s);
137 }
138