]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest-engraver.cc
* lily/context.cc (where_defined): also assign value in
[lilypond.git] / lily / rest-engraver.cc
1 /*
2   rest-engraver.cc -- implement Rest_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "engraver.hh"
10
11 #include "duration.hh"
12 #include "item.hh"
13 #include "staff-symbol-referencer.hh"
14 #include "dots.hh"
15 #include "rhythmic-head.hh"
16 #include "music.hh"
17
18
19 class Rest_engraver : public Engraver
20 {
21   Music *rest_event_;
22   Item *dot_;
23   Grob *rest_;
24 protected:
25   virtual bool try_music (Music *);
26   PRECOMPUTED_VIRTUAL void start_translation_timestep ();
27   PRECOMPUTED_VIRTUAL void process_music ();
28
29 public:
30   TRANSLATOR_DECLARATIONS (Rest_engraver);
31 };
32
33 /*
34   Should merge with Note_head_engraver
35 */
36 Rest_engraver::Rest_engraver ()
37 {
38   rest_event_ = 0;
39   rest_ = 0;
40   dot_ = 0;
41 }
42
43 void
44 Rest_engraver::start_translation_timestep ()
45 {
46   rest_event_ = 0;
47   rest_ = 0;
48   dot_ = 0;
49 }
50
51
52 void
53 Rest_engraver::process_music ()
54 {
55   if (rest_event_ && !rest_)
56     {
57       rest_ = make_item ("Rest", rest_event_->self_scm ());
58
59       int durlog = unsmob_duration (rest_event_->get_property ("duration"))->duration_log ();
60
61       rest_->set_property ("duration-log",
62                            scm_int2num (durlog));
63
64       int dots = unsmob_duration (rest_event_->get_property ("duration"))->dot_count ();
65
66       if (dots)
67         {
68           dot_ = make_item ("Dots", SCM_EOL);
69
70           Rhythmic_head::set_dots (rest_, dot_);
71           dot_->set_parent (rest_, Y_AXIS);
72           dot_->set_property ("dot-count", scm_int2num (dots));
73         }
74
75       Pitch *p = unsmob_pitch (rest_event_->get_property ("pitch"));
76
77       /*
78         This is ridiculous -- rests don't have pitch, but we act as if
79         our nose is bleeding.
80       */
81       if (p)
82         {
83           int pos = p->steps ();
84           SCM c0 = get_property ("middleCPosition");
85           if (scm_is_number (c0))
86             pos += scm_to_int (c0);
87
88           rest_->set_property ("staff-position", scm_int2num (pos));
89         }
90     }
91 }
92
93 bool
94 Rest_engraver::try_music (Music *m)
95 {
96   if (m->is_mus_type ("rest-event"))
97     {
98       rest_event_ = m;
99       return true;
100     }
101   return false;
102 }
103
104 #include "translator.icc"
105
106 ADD_TRANSLATOR (Rest_engraver,
107                 /* descr */ "",
108                 /* creats*/ "Rest Dots",
109                 /* accepts */ "rest-event",
110                 /* reads */ "middleCPosition",
111                 /* write */ "");