]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-heads-engraver.cc
*** empty log message ***
[lilypond.git] / lily / note-heads-engraver.cc
1 /*
2   head-grav.cc -- part of GNU LilyPond
3
4   (c)  1997--2003 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 "event.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
22 /*
23  * TODO: junk bool in_ligature (and all the messy code around it).
24  * This can be done by also junking LigatureHead in
25  * scm/grob-description.scm.  Instead, NoteHead should be used
26  * throughout typesetting of ligatures; ligature-(start/stop)-events
27  * should simply modify NoteHead properties values of
28  * molecule-callback ligature-primitive-callback.  --jr
29  */
30 class Note_heads_engraver : public Engraver
31 {
32   Link_array<Item> notes_;
33   
34   Link_array<Item> dots_;
35   Link_array<Music> note_reqs_;
36
37 public:
38   TRANSLATOR_DECLARATIONS(Note_heads_engraver);
39
40 protected:
41   virtual void start_translation_timestep ();
42   virtual bool try_music (Music *req) ;
43   virtual void process_music ();
44
45   virtual void stop_translation_timestep ();
46
47 private:
48   bool in_ligature;
49 };
50
51 Note_heads_engraver::Note_heads_engraver()
52 {
53   in_ligature = 0;
54 }
55
56 bool
57 Note_heads_engraver::try_music (Music *m) 
58 {
59   if (m->is_mus_type ("note-event"))
60     {
61       note_reqs_.push (m);
62       return true;
63     }
64   else if (m->is_mus_type ("busy-playing-event"))
65     return note_reqs_.size ();
66   else if (m->is_mus_type ("abort-event"))
67     {
68       in_ligature = 0;
69     }
70   else if (m->is_mus_type ("ligature-event"))
71     {
72       /*
73         Urg ; this is not protocol. We should accept and return
74         true, or ignore.
75       */
76       in_ligature = (to_dir (m->get_mus_property("span-direction")) == START);
77       return false;
78     }
79   
80   return false;
81 }
82
83
84 void
85 Note_heads_engraver::process_music ()
86 {
87   for (int i=0; i < note_reqs_.size (); i++)
88     {
89       Item *note =
90         new Item (get_property ((in_ligature) ? "LigatureHead" : "NoteHead"));
91
92       Music * req = note_reqs_[i];
93       
94       Duration dur = *unsmob_duration (req->get_mus_property ("duration"));
95
96       note->set_grob_property ("duration-log", gh_int2scm (dur.duration_log ()));
97
98       if (dur.dot_count ())
99         {
100           Item * d = new Item (get_property ("Dots"));
101           Rhythmic_head::set_dots (note, d);
102           
103           if (dur.dot_count ()
104               != gh_scm2int (d->get_grob_property ("dot-count")))
105             d->set_grob_property ("dot-count", gh_int2scm (dur.dot_count ()));
106
107           d->set_parent (note, Y_AXIS);
108           announce_grob (d, SCM_EOL);
109           dots_.push (d);
110         }
111
112       Pitch *pit =unsmob_pitch (req->get_mus_property ("pitch"));
113
114       int pos = pit->steps ();
115       SCM c0 = get_property ("centralCPosition");
116       if (gh_number_p (c0))
117         pos += gh_scm2int (c0);
118
119       note->set_grob_property ("staff-position",   gh_int2scm (pos));
120       announce_grob (note,req->self_scm());
121       notes_.push (note);
122     }
123 }
124
125 void
126 Note_heads_engraver::stop_translation_timestep ()
127 {
128   for (int i=0; i < notes_.size (); i++)
129     {
130       typeset_grob (notes_[i]);
131     }
132
133   notes_.clear ();
134   for (int i=0; i < dots_.size (); i++)
135     {
136       typeset_grob (dots_[i]);
137     }
138   dots_.clear ();
139   note_reqs_.clear ();
140 }
141
142 void
143 Note_heads_engraver::start_translation_timestep ()
144 {
145 }
146
147
148 ENTER_DESCRIPTION(Note_heads_engraver,
149 /* descr */       "Generate noteheads (also serves a double functions: makes ligatures.",
150 /* creats*/       "NoteHead LigatureHead Dots",
151 /* accepts */     "note-event busy-playing-event ligature-event abort-event",
152 /* acks  */      "",
153 /* reads */       "centralCPosition",
154 /* write */       "");