]> git.donarmstrong.com Git - lilypond.git/blob - lily/tuplet-engraver.cc
(DECLARE_EVENT_SWALLOWER): ENTER_DESCRIPTION -> ADD_TRANSLATOR
[lilypond.git] / lily / tuplet-engraver.cc
1 /*   
2   tuplet-engraver.cc --  implement Tuplet_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1998--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "tuplet-bracket.hh"
11 #include "note-column.hh"
12 #include "time-scaled-music.hh"
13 #include "beam.hh"
14 #include "music-list.hh"
15 #include "engraver.hh"
16 #include "spanner.hh"
17
18 struct Tuplet_description
19 {
20   Music *music_;
21   Rational stop_;
22   Rational span_stop_;
23   Spanner *spanner_;
24   Tuplet_description()
25   {
26     music_ = 0;
27     spanner_ = 0;
28   }
29 };
30
31 class Tuplet_engraver : public Engraver
32 {
33 public:
34   TRANSLATOR_DECLARATIONS (Tuplet_engraver);
35
36 protected:
37   Array<Tuplet_description> tuplets_;
38
39   virtual void acknowledge_grob (Grob_info);
40   virtual bool try_music (Music*r);
41   virtual void start_translation_timestep ();
42   virtual void process_music ();
43 };
44
45 bool
46 Tuplet_engraver::try_music (Music *music)
47 {
48   if (music->is_mus_type ("time-scaled-music"))
49     {
50       Music *el = unsmob_music (music->get_property ("element"));
51       if (el && !el->is_mus_type ("event-chord"))
52         {
53           Tuplet_description d;
54           d.music_ = music;
55           d.stop_  = now_mom ().main_part_ + music->get_length ().main_part_;
56           d.span_stop_ = d.stop_;
57           
58           SCM s = get_property ("tupletSpannerDuration");
59           if (unsmob_moment (s))
60             d.span_stop_ = d.span_stop_ <? (now_mom () + *unsmob_moment (s)).main_part_;
61           
62           tuplets_.push (d);
63         }
64       return true;
65     }
66   return false;
67 }
68
69 void
70 Tuplet_engraver::process_music ()
71 {
72   for (int i = 0; i < tuplets_.size (); i++)
73     {
74       if (tuplets_[i].spanner_)
75         continue;
76
77       Spanner* spanner = make_spanner ("TupletBracket",
78                                        tuplets_[i].music_->self_scm ());
79       tuplets_[i].spanner_ = spanner;
80
81       SCM proc = get_property ("tupletNumberFormatFunction");
82       if (ly_c_procedure_p (proc))
83         {
84           SCM t = scm_apply_0 (proc, scm_list_1 (tuplets_[i].music_->self_scm ()));
85           spanner->set_property ("text", t);
86         }
87     }
88 }
89
90 void
91 Tuplet_engraver::acknowledge_grob (Grob_info i)
92 {
93   if (Note_column::has_interface (i.grob_))
94     {
95       for (int j = 0; j < tuplets_.size (); j++)
96         if (tuplets_[j].spanner_) 
97           Tuplet_bracket::add_column (tuplets_[j].spanner_,
98                                       dynamic_cast<Item*> (i.grob_));
99     }
100 }
101
102 void
103 Tuplet_engraver::start_translation_timestep ()
104 {
105   Moment now = now_mom ();
106
107   Moment tsd;
108   SCM s = get_property ("tupletSpannerDuration");
109   if (unsmob_moment (s))
110     tsd = unsmob_moment (s)->main_part_;
111
112   for (int i = tuplets_.size (); i--;)
113     {
114       if (now.main_part_ >= tuplets_[i].span_stop_)
115         {
116           if (Spanner *sp = tuplets_[i].spanner_)
117             {
118               if (!sp->get_bound (RIGHT))
119                 sp->set_bound (RIGHT, sp->get_bound (LEFT));
120               
121               tuplets_[i].spanner_ = 0;
122             }
123           
124           if (tsd.to_bool ())
125             tuplets_[i].span_stop_ += tsd.main_part_;
126         }
127
128       if (now.main_part_ >= tuplets_[i].stop_)
129         {
130           tuplets_.del (i);
131         }
132     }
133 }
134
135 Tuplet_engraver::Tuplet_engraver ()
136 {
137 }
138
139 ADD_TRANSLATOR (Tuplet_engraver,
140 /* descr */       "Catch Time_scaled_music and generate appropriate bracket  ",
141 /* creats*/       "TupletBracket",
142 /* accepts */     "time-scaled-music",
143 /* acks  */      "note-column-interface",
144 /* reads */       "tupletNumberFormatFunction tupletSpannerDuration",
145 /* write */       "");