]> git.donarmstrong.com Git - lilypond.git/blob - lily/spacing-engraver.cc
release: 1.1.39
[lilypond.git] / lily / spacing-engraver.cc
1 /*   
2   spacing-engraver.cc --  implement Spacing_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "engraver.hh"
11 #include "pqueue.hh"
12 #include "musical-request.hh"
13 #include "score-column.hh"
14
15 struct Rhythmic_tuple
16 {
17   Score_element_info info_;
18   Moment end_;
19   
20   Rhythmic_tuple ()
21     {
22     }
23   Rhythmic_tuple (Score_element_info i, Moment m )
24     {
25       info_ = i;
26       end_ = m;
27     }
28   static int time_compare (Rhythmic_tuple const &, Rhythmic_tuple const &);  
29 };
30
31 inline int
32 compare (Rhythmic_tuple const &a, Rhythmic_tuple const &b)
33 {
34   return Rhythmic_tuple::time_compare (a,b);
35 }
36
37 int
38 Rhythmic_tuple::time_compare (Rhythmic_tuple const&h1,
39                               Rhythmic_tuple const &h2)
40 {
41   return (h1.end_ - h2.end_ ).sign ();
42 }
43
44 /**
45    Acknowledge rhythmic elements, for initializing spacing fields in
46    the columns.  */
47 class Spacing_engraver : public Engraver
48 {
49   PQueue<Rhythmic_tuple> playing_durations_;
50   Array<Rhythmic_tuple> now_durations_;
51   Array<Rhythmic_tuple> stopped_durations_;
52
53 protected:
54   VIRTUAL_COPY_CONS(Translator);
55   virtual void acknowledge_element (Score_element_info);
56   virtual void do_post_move_processing ();
57   virtual void do_pre_move_processing ();
58
59 public:
60
61 };
62
63
64 void
65 Spacing_engraver::acknowledge_element (Score_element_info i)
66 {
67   if (Rhythmic_req * r = dynamic_cast<Rhythmic_req*>(i.req_l_))
68     {
69       Rhythmic_tuple t(i, now_mom () + r->length_mom ());
70       now_durations_.push (t);
71     }
72 }
73
74 void
75 Spacing_engraver::do_pre_move_processing ()
76 {
77   Moment shortest_playing;
78   shortest_playing.set_infinite (1);
79   for (int i=0; i < playing_durations_.size (); i++)
80     {
81       Moment m = (playing_durations_[i].info_.req_l_)->length_mom ();
82       if (m)
83         shortest_playing = shortest_playing <? m;
84     }
85
86   Moment starter;
87   starter.set_infinite (1);
88   for (int i=0; i < now_durations_.size (); i++)
89     {
90       Moment m = now_durations_[i].info_.req_l_->length_mom ();
91       if (m)
92         starter = starter <? m;
93
94       playing_durations_.insert (now_durations_[i]);
95     }
96   now_durations_.clear ();
97   
98   shortest_playing = shortest_playing <? starter;
99   
100   Score_column * sc
101     = dynamic_cast<Score_column*> (get_staff_info ().musical_pcol_l ());
102
103   sc->shortest_playing_mom_ = shortest_playing;
104   sc->shortest_starter_mom_ = starter;
105 }
106
107
108 void
109 Spacing_engraver::do_post_move_processing ()
110 {
111   Moment now = now_mom ();
112   stopped_durations_.clear ();
113   while (playing_durations_.size () && playing_durations_.front ().end_ < now)
114     playing_durations_.delmin ();
115   while (playing_durations_.size () && playing_durations_.front ().end_ == now)
116     stopped_durations_.push (playing_durations_.get ());
117 }
118
119 ADD_THIS_TRANSLATOR(Spacing_engraver);
120