]> git.donarmstrong.com Git - lilypond.git/blob - lily/stem-tremolo.cc
release: 1.3.17
[lilypond.git] / lily / stem-tremolo.cc
1 /*   
2   abbrev.cc --  implement Stem_tremolo
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c)  1997--1999 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 Stem_tremolo::Stem_tremolo ()
22 {
23   set_elt_property ("stem", SCM_EOL);
24 }
25
26
27 Stem *
28 Stem_tremolo::stem_l ()const
29 {
30   SCM s =   get_elt_property ("stem");
31
32   return dynamic_cast<Stem*> (  unsmob_element (s));
33 }
34
35 Interval
36 Stem_tremolo::dim_callback (Dimension_cache const *c) 
37 {
38   Stem_tremolo * s = dynamic_cast<Stem_tremolo*> (c->element_l ());
39   Real space = Staff_symbol_referencer_interface (s->stem_l ())
40     .staff_space ();
41   return Interval (-space, space);
42 }
43
44
45 Molecule*
46 Stem_tremolo::do_brew_molecule_p () const
47 {
48   Stem * st = stem_l ();
49   int mult =0;
50   if (Beam * b = st->beam_l ())
51     {
52       mult = b->get_multiplicity ();
53     }
54   
55   Real interbeam_f = paper_l ()->interbeam_f (mult);
56   Real w  = gh_scm2double (get_elt_property ("beam-width"));
57   Real space = Staff_symbol_referencer_interface (st).staff_space ();
58   Real half_staff_space = space / 2;
59   Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));
60
61   int beams_i = 0;
62   Real dydx = 0.25;
63   
64   if (st && st->beam_l ())
65     {
66       Real dy = 0;
67       SCM s = st->beam_l ()->get_elt_property ("height");
68       if (gh_number_p (s))
69         dy = gh_scm2double (s);
70       Real dx = st->beam_l ()->last_visible_stem ()->hpos_f ()
71         - st->beam_l ()->first_visible_stem ()->hpos_f ();
72       dydx = dy/dx;
73   
74       // ugh, rather calc from Stem_tremolo_req
75       beams_i = st->beam_count(RIGHT) >? st->beam_count (LEFT);
76     } 
77
78   Molecule a (lookup_l ()->beam (dydx, w, beam_f));
79   a.translate (Offset (-w/2, w / 2 * dydx));
80   
81   int abbrev_flags = 1;
82   {
83     SCM a = get_elt_property ("abbrev-flags");
84     if (gh_number_p (a))
85       abbrev_flags = gh_scm2int (a);
86   }
87
88   Molecule *beams= new Molecule; 
89   for (int i = 0; i < abbrev_flags; i++)
90     {
91       Molecule b (a);
92       b.translate_axis (interbeam_f * i, Y_AXIS);
93       beams->add_molecule (b);
94     }
95   beams->translate_axis (-beams->extent ()[Y_AXIS].center (), Y_AXIS);
96
97   if (st)
98     { 
99       if (st->beam_l ())
100         {
101           beams->translate (Offset(st->hpos_f () - hpos_f (),
102             st->stem_end_position () * half_staff_space - 
103             directional_element (st->beam_l ()).get () * beams_i * interbeam_f));
104         }
105       else
106         {  
107           /*
108             Beams should intersect one beamthickness below staff end
109            */
110           Real dy = - beams->extent ()[Y_AXIS].length () / 2 * st->get_direction ();
111
112           /*
113             uhg.  Should use relative coords and placement
114           */
115           Real whole_note_correction = (st && st->invisible_b( ))
116             ? 0.0 //  -st->get_direction () * st->note_delta_f ()/2
117             : 0.0;
118          
119           dy += st->stem_end_position ();
120           beams->translate (Offset(st->hpos_f () - hpos_f ()+
121                                    whole_note_correction, dy));
122         }
123
124       /*
125         there used to be half a page of code that was long commented out.
126         Removed in 1.1.35
127        */
128     }
129   
130   return beams;
131 }
132
133
134 void
135 Stem_tremolo::set_stem (Stem *s)
136 {
137   set_elt_property ("stem", s->self_scm_);
138   add_dependency (s);
139 }
140