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