]> git.donarmstrong.com Git - lilypond.git/blob - lily/abbrev.cc
36279673fd1fc049f414fb0a1adee8f582c49271
[lilypond.git] / lily / abbrev.cc
1 /*   
2   abbrev.cc --  implement Abbreviation
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "abbrev.hh"
11 #include "debug.hh"
12 #include "beam.hh"
13 #include "paper-def.hh"
14 #include "lookup.hh"
15 #include "stem.hh"
16
17 Abbreviation::Abbreviation ()
18 {
19   stem_l_ = 0;
20   abbrev_flags_i_ = 1;
21 }
22
23 void
24 Abbreviation::do_print () const
25 {
26   DOUT << "abbrev_flags_i_ " << abbrev_flags_i_;
27 }
28
29 Molecule*
30 Abbreviation::brew_molecule_p () const
31 {
32   Real interbeam_f = paper ()->interbeam_f (stem_l_->mult_i_);
33   Real w = 1.5 * lookup_l ()->ball (2).dim_.x ().length ();
34   Real internote_f = paper ()->internote_f ();
35   Real beam_f = paper ()->beam_thickness_f ();
36
37   int beams_i = 0;
38   Real slope_f = internote_f / 4 / internote_f;
39
40   if (stem_l_ && stem_l_->beam_l_) {
41     slope_f = stem_l_->beam_l_->slope_f_;
42     // ugh, rather calc from Abbreviation_req
43     beams_i = stem_l_->beams_right_i_ >? stem_l_->beams_left_i_;
44   } 
45   Real sl = slope_f * internote_f;
46
47   Atom a (lookup_l ()->beam (sl, w, beam_f));
48   a.translate (Offset (-w/2, w / 2 * slope_f));
49
50   Molecule *beams= new Molecule; 
51   for (int i = 0; i < abbrev_flags_i_; i++)
52     {
53       Atom b (a);
54       b.translate_axis (interbeam_f * i, Y_AXIS);
55       beams->add_atom (b);
56     }
57   beams->translate_axis (-beams->extent ()[Y_AXIS].center (), Y_AXIS);
58
59   if (stem_l_)
60     { 
61       if (stem_l_->beam_l_)
62         {
63           beams->translate (Offset(stem_l_->hpos_f () - hpos_f (),
64             stem_l_->stem_end_f () * internote_f - 
65             stem_l_->beam_l_->dir_ * beams_i * interbeam_f));
66         }
67       else
68 #if 1
69         {  
70           /*
71             Beams should intersect one beamthickness below staff end
72            */
73           Real dy = - beams->extent ()[Y_AXIS].length () / 2 * stem_l_->dir_;
74           dy /= internote_f;
75           dy += stem_l_->stem_end_f ();
76           dy *= internote_f;
77 // urg: can't: stem should be stetched first
78 //        dy -= paper ()->beam_thickness_f () * stem_l_->dir_;
79           beams->translate (Offset(stem_l_->hpos_f () - hpos_f (), dy));
80         }
81 #else
82         {
83           /* 
84              urg: this is wrong, even if coded correctly
85
86              Try to be in the middle of the open part of the stem and
87              between on the staff.
88
89              (urgh)
90           */
91           Direction sd  = stem_l_->dir_;
92           // watch out: chord_start_f is (the only one) not in dim(internote)
93           Interval empty_stem (stem_l_->chord_start_f () / internote_f * sd
94             + interline_f, (stem_l_->stem_end_f ()* sd));
95           empty_stem *= sd;
96           
97           Interval instaff = empty_stem;
98           /*
99             huh? i don't understand, hw
100             what about:
101             .fly= \stemup d'''2:16
102             instaff.intersect (Interval (-4,4));
103             */
104           // hmm, let's try
105           if (stem_l_->get_default_dir () == stem_l_->dir_)
106             instaff.intersect (Interval (-4,4));
107
108           if (instaff.empty_b ())
109             instaff = empty_stem;
110
111           instaff.print (); 
112           instaff *= internote_f;
113           beams->translate (Offset(stem_l_->hpos_f () - hpos_f (),
114                               instaff.center ()));
115         }
116 #endif
117     }
118   
119   return beams;
120 }
121
122 void
123 Abbreviation::do_substitute_dependent (Score_element*o, Score_element*n)
124 {
125   if (stem_l_ == o)
126     stem_l_ = dynamic_cast<Stem*> (n);
127 }
128
129
130 void
131 Abbreviation::set_stem (Stem *s)
132 {
133   stem_l_ = s;
134   add_dependency (s);
135 }