]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-heads-engraver.cc
* lily/musical-request.cc (music-duration-length,
[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> notes_;
24   
25   Link_array<Item> dots_;
26   Link_array<Music> note_reqs_;
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) ;
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 (m->is_mus_type ("note-event"))
51     {
52       note_reqs_.push (m);
53       return true;
54     }
55   else if (m->is_mus_type ("busy-playing-event"))
56     return note_reqs_.size ();
57   else if (m->is_mus_type ("abort-event"))
58     {
59       in_ligature = 0;
60     }
61   else if (m->is_mus_type ("ligature-event"))
62     {
63       /*
64         Urg ; this is not protocol. We should accept and return
65         true, or ignore.
66       */
67       in_ligature = (m->get_mus_property("span-direction")
68                      == gh_int2scm (START));
69     }
70   
71   return false;
72 }
73
74
75 void
76 Note_heads_engraver::process_music ()
77 {
78   for (int i=0; i < note_reqs_.size (); i++)
79     {
80       Item *note =
81         new Item (get_property ((in_ligature) ? "LigatureHead" : "NoteHead"));
82
83       Music * req = note_reqs_[i];
84       
85       Duration dur = *unsmob_duration (req->get_mus_property ("duration"));
86
87       note->set_grob_property ("duration-log", gh_int2scm (dur.duration_log ()));
88
89       if (dur.dot_count ())
90         {
91           Item * d = new Item (get_property ("Dots"));
92           Rhythmic_head::set_dots (note, d);
93           
94           if (dur.dot_count ()
95               != gh_scm2int (d->get_grob_property ("dot-count")))
96             d->set_grob_property ("dot-count", gh_int2scm (dur.dot_count ()));
97
98           d->set_parent (note, Y_AXIS);
99           announce_grob (d, SCM_EOL);
100           dots_.push (d);
101         }
102
103       Pitch *pit =unsmob_pitch (req->get_mus_property ("pitch"));
104
105       int pos = pit->steps ();
106       SCM c0 = get_property ("centralCPosition");
107       if (gh_number_p (c0))
108         pos += gh_scm2int (c0);
109
110       note->set_grob_property ("staff-position",   gh_int2scm (pos));
111       announce_grob (note,req->self_scm());
112       notes_.push (note);
113     }
114 }
115
116 void
117 Note_heads_engraver::stop_translation_timestep ()
118 {
119   for (int i=0; i < notes_.size (); i++)
120     {
121       typeset_grob (notes_[i]);
122     }
123
124   notes_.clear ();
125   for (int i=0; i < dots_.size (); i++)
126     {
127       typeset_grob (dots_[i]);
128     }
129   dots_.clear ();
130   note_reqs_.clear ();
131 }
132
133 void
134 Note_heads_engraver::start_translation_timestep ()
135 {
136 }
137
138
139 ENTER_DESCRIPTION(Note_heads_engraver,
140 /* descr */       "Generate noteheads (also serves a double functions: makes ligatures.",
141 /* creats*/       "NoteHead LigatureHead Dots",
142 /* accepts */     "note-event busy-playing-event ligature-event abort-event",
143 /* acks  */      "",
144 /* reads */       "centralCPosition",
145 /* write */       "");