]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-heads-engraver.cc
243783adb2590a17d8a1c5b68ed408b1688d5560
[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<Note_req> 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 (Note_req * n =dynamic_cast <Note_req *> (m))
51     {
52       note_reqs_.push (n);
53       return true;
54     }
55   else if (dynamic_cast<Busy_playing_req*> (m))
56     {
57       return note_reqs_.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                        scm_makfrom0str ("abort")) == SCM_BOOL_T)
63         {
64           in_ligature = 0;
65         }
66       else if (scm_equal_p (req_->get_mus_property ("span-type"),
67                             scm_makfrom0str ("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_reqs_.size (); i++)
81     {
82       Item *note =
83         new Item (get_property ((in_ligature) ? "LigatureHead" : "NoteHead"));
84
85       Music * req = note_reqs_[i];
86       
87       Duration dur = *unsmob_duration (req->get_mus_property ("duration"));
88
89       note->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, 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, Y_AXIS);
101           announce_grob (d, SCM_EOL);
102           dots_.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->set_grob_property ("staff-position",   gh_int2scm (pos));
113       announce_grob (note,req->self_scm());
114       notes_.push (note);
115     }
116 }
117
118 void
119 Note_heads_engraver::stop_translation_timestep ()
120 {
121   for (int i=0; i < notes_.size (); i++)
122     {
123       typeset_grob (notes_[i]);
124     }
125
126   notes_.clear ();
127   for (int i=0; i < dots_.size (); i++)
128     {
129       typeset_grob (dots_[i]);
130     }
131   dots_.clear ();
132   
133   note_reqs_.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 /* accepts */     "general-music",
146 /* acks  */      "",
147 /* reads */       "centralCPosition",
148 /* write */       "");