]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest-collision-engraver.cc
Merge branch 'master' into lilypond/translation
[lilypond.git] / lily / rest-collision-engraver.cc
1 /*
2   rest-collision-engraver.cc -- implement Rest_collision_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include <set>
10
11 #include "duration.hh"
12 #include "engraver.hh"
13 #include "international.hh"
14 #include "item.hh"
15 #include "moment.hh"
16 #include "note-column.hh"
17 #include "paper-column.hh"
18 #include "rest.hh"
19 #include "rest-collision.hh"
20 #include "rhythmic-head.hh"
21 #include "stream-event.hh"
22 #include "warn.hh"
23
24 class Rest_collision_engraver : public Engraver
25 {
26 protected:
27   Grob *rest_collision_;
28
29   void process_acknowledged ();
30   void stop_translation_timestep ();
31 public:
32   TRANSLATOR_DECLARATIONS (Rest_collision_engraver);
33 };
34
35 Rest_collision_engraver::Rest_collision_engraver ()
36 {
37   rest_collision_ = 0;
38 }
39
40 void
41 Rest_collision_engraver::process_acknowledged ()
42 {
43   vsize rest_count = 0;
44   set<Grob*> columns;
45   Moment now = now_mom ();
46
47   for (SCM s = get_property ("busyGrobs"); scm_is_pair (s); s = scm_cdr (s))
48     {
49       Grob *g = unsmob_grob (scm_cdar (s));
50       Moment *m = unsmob_moment (scm_caar (s));
51       if (!g || !m)
52         continue;
53
54       if (Rhythmic_head::has_interface (g) && (*m) > now)
55         {
56           Grob *column = g->get_parent (X_AXIS);
57           if (!column)
58             {
59               g->warning (_ ("rhythmic head is not part of a rhythmic column"));
60               continue;
61             }
62
63           // Only include rests that start now. Include notes that started any time.
64           Paper_column *paper_column = dynamic_cast<Item*> (column)->get_column ();
65           if (!Rest::has_interface (g) || !paper_column || Paper_column::when_mom (paper_column) == now)
66             {
67               columns.insert (column);
68               rest_count += Note_column::has_rests (column);
69             }
70         }
71     }
72
73   if (!rest_collision_ && rest_count && columns.size () > 1)
74     {
75       rest_collision_ = make_item ("RestCollision", SCM_EOL);
76       for (set<Grob*>::iterator i = columns.begin (); i != columns.end (); ++i)
77         Rest_collision::add_column (rest_collision_, *i);
78     }
79 }
80
81 void
82 Rest_collision_engraver::stop_translation_timestep ()
83 {
84   rest_collision_ = 0;
85 }
86
87 #include "translator.icc"
88
89 ADD_TRANSLATOR (Rest_collision_engraver,
90                 /* doc */
91                 "Handle collisions of rests.",
92
93                 /* create */
94                 "RestCollision ",
95
96                 /* read */
97                 "busyGrobs ",
98
99                 /* write */
100                 ""
101                 );