]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest-engraver.cc
*** empty log message ***
[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--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "engraver.hh"
10
11 #include "dots.hh"
12 #include "duration.hh"
13 #include "item.hh"
14 #include "rhythmic-head.hh"
15 #include "staff-symbol-referencer.hh"
16 #include "stream-event.hh"
17
18 #include "translator.icc"
19
20 class Rest_engraver : public Engraver
21 {
22   Stream_event *rest_event_;
23   Item *dot_;
24   Grob *rest_;
25 protected:
26   void start_translation_timestep ();
27   void process_music ();
28   DECLARE_TRANSLATOR_LISTENER (rest);
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 void
52 Rest_engraver::process_music ()
53 {
54   if (rest_event_ && !rest_)
55     {
56       rest_ = make_item ("Rest", rest_event_->self_scm ());
57
58       int durlog = unsmob_duration (rest_event_->get_property ("duration"))->duration_log ();
59
60       rest_->set_property ("duration-log",
61                            scm_from_int (durlog));
62
63       int dots = unsmob_duration (rest_event_->get_property ("duration"))->dot_count ();
64
65       if (dots)
66         {
67           dot_ = make_item ("Dots", SCM_EOL);
68
69           Rhythmic_head::set_dots (rest_, dot_);
70           dot_->set_parent (rest_, Y_AXIS);
71           dot_->set_property ("dot-count", scm_from_int (dots));
72         }
73
74       Pitch *p = unsmob_pitch (rest_event_->get_property ("pitch"));
75
76       /*
77         This is ridiculous -- rests don't have pitch, but we act as if
78         our nose is bleeding.
79       */
80       if (p)
81         {
82           int pos = p->steps ();
83           SCM c0 = get_property ("middleCPosition");
84           if (scm_is_number (c0))
85             pos += scm_to_int (c0);
86
87           rest_->set_property ("staff-position", scm_from_int (pos));
88         }
89     }
90 }
91
92 IMPLEMENT_TRANSLATOR_LISTENER (Rest_engraver, rest);
93 void
94 Rest_engraver::listen_rest (Stream_event *ev)
95 {
96   ASSIGN_EVENT_ONCE (rest_event_, ev);
97 }
98
99 ADD_TRANSLATOR (Rest_engraver,
100                 /* doc */ "",
101                 /* create */ "Rest Dots",
102                 /* accept */ "rest-event",
103                 /* read */ "middleCPosition",
104                 /* write */ "");