]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-heads-engraver.cc
2002-07-17 Han-Wen <hanwen@cs.uu.nl>
[lilypond.git] / lily / note-heads-engraver.cc
1 /*
2   head-grav.cc -- part of GNU LilyPond
3
4   (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
5 */
6 #include <ctype.h>
7
8 #include "rhythmic-head.hh"
9 #include "paper-def.hh"
10 #include "musical-request.hh"
11 #include "dots.hh"
12 #include "dot-column.hh"
13 #include "staff-symbol-referencer.hh"
14 #include "item.hh"
15 #include "engraver.hh"
16 #include "warn.hh"
17
18 /**
19   make balls and rests
20  */
21 class Note_heads_engraver : public Engraver
22 {
23   Link_array<Item> note_p_arr_;
24   
25   Link_array<Item> dot_p_arr_;
26   Link_array<Note_req> note_req_l_arr_;
27
28 public:
29   TRANSLATOR_DECLARATIONS(Note_heads_engraver);
30
31 protected:
32   virtual void start_translation_timestep ();
33   virtual bool try_music (Music *req_l) ;
34   virtual void process_music ();
35
36   virtual void stop_translation_timestep ();
37
38 private:
39   bool in_ligature;
40 };
41
42 Note_heads_engraver::Note_heads_engraver()
43 {
44   in_ligature = 0;
45 }
46
47 bool
48 Note_heads_engraver::try_music (Music *m) 
49 {
50   if (Note_req * n =dynamic_cast <Note_req *> (m))
51     {
52       note_req_l_arr_.push (n);
53       return true;
54     }
55   else if (dynamic_cast<Busy_playing_req*> (m))
56     {
57       return note_req_l_arr_.size ();
58     }
59   else if (Span_req *req_ = dynamic_cast<Span_req*> (m))
60     {
61       if (scm_equal_p (req_->get_mus_property ("span-type"),
62                        ly_str02scm ("abort")) == SCM_BOOL_T)
63         {
64           in_ligature = 0;
65         }
66       else if (scm_equal_p (req_->get_mus_property ("span-type"),
67                             ly_str02scm ("ligature")) == SCM_BOOL_T)
68         {
69           in_ligature = (req_->get_span_dir () == START);
70         }
71     }
72   
73   return false;
74 }
75
76
77 void
78 Note_heads_engraver::process_music ()
79 {
80   for (int i=0; i < note_req_l_arr_.size (); i++)
81     {
82       Item *note_p =
83         new Item (get_property ((in_ligature) ? "LigatureHead" : "NoteHead"));
84
85       Music * req = note_req_l_arr_[i];
86       
87       Duration dur = *unsmob_duration (req->get_mus_property ("duration"));
88
89       note_p->set_grob_property ("duration-log", gh_int2scm (dur.duration_log ()));
90
91       if (dur.dot_count ())
92         {
93           Item * d = new Item (get_property ("Dots"));
94           Rhythmic_head::set_dots (note_p, d);
95           
96           if (dur.dot_count ()
97               != gh_scm2int (d->get_grob_property ("dot-count")))
98             d->set_grob_property ("dot-count", gh_int2scm (dur.dot_count ()));
99
100           d->set_parent (note_p, Y_AXIS);
101           announce_grob (d, SCM_EOL);
102           dot_p_arr_.push (d);
103         }
104
105       Pitch *pit =unsmob_pitch (req->get_mus_property ("pitch"));
106
107       int pos = pit->steps ();
108       SCM c0 = get_property ("centralCPosition");
109       if (gh_number_p (c0))
110         pos += gh_scm2int (c0);
111
112       note_p->set_grob_property ("staff-position",   gh_int2scm (pos));
113       announce_grob (note_p,req->self_scm());
114       note_p_arr_.push (note_p);
115     }
116 }
117
118 void
119 Note_heads_engraver::stop_translation_timestep ()
120 {
121   for (int i=0; i < note_p_arr_.size (); i++)
122     {
123       typeset_grob (note_p_arr_[i]);
124     }
125
126   note_p_arr_.clear ();
127   for (int i=0; i < dot_p_arr_.size (); i++)
128     {
129       typeset_grob (dot_p_arr_[i]);
130     }
131   dot_p_arr_.clear ();
132   
133   note_req_l_arr_.clear ();
134 }
135
136 void
137 Note_heads_engraver::start_translation_timestep ()
138 {
139 }
140
141
142 ENTER_DESCRIPTION(Note_heads_engraver,
143 /* descr */       "Generate one or more noteheads from Music of type Note_req.",
144 /* creats*/       "NoteHead Dots",
145 /* acks  */       "",
146 /* reads */       "centralCPosition",
147 /* write */       "");