]> git.donarmstrong.com Git - lilypond.git/blob - lily/shape-note-heads-engraver.cc
*** empty log message ***
[lilypond.git] / lily / shape-note-heads-engraver.cc
1 /*
2   shape-note-heads-engraver.cc -- part of GNU LilyPond
3
4   (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
5 */
6
7 #include <cctype>
8
9 #include "rhythmic-head.hh"
10 #include "output-def.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 class Shape_note_heads_engraver : public Engraver
19 {
20   Link_array<Item> notes_;
21   Link_array<Item> dots_;
22   Link_array<Music> note_evs_;
23
24 public:
25   TRANSLATOR_DECLARATIONS (Shape_note_heads_engraver);
26
27 protected:
28   virtual bool try_music (Music *ev) ;
29   virtual void process_music ();
30   virtual void stop_translation_timestep ();
31 };
32
33 Shape_note_heads_engraver::Shape_note_heads_engraver ()
34 {
35 }
36
37 bool
38 Shape_note_heads_engraver::try_music (Music *m) 
39 {
40   if (m->is_mus_type ("note-event"))
41     {
42       note_evs_.push (m);
43       return true;
44     }
45   else if (m->is_mus_type ("busy-playing-event"))
46     return note_evs_.size ();
47   
48   return false;
49 }
50
51
52 void
53 Shape_note_heads_engraver::process_music ()
54 {
55   if (!note_evs_.size())
56     return ;
57   
58   for (int i=0; i < note_evs_.size (); i++)
59     {
60
61       Music * ev = note_evs_[i];
62       Item *note = make_item ("NoteHead", ev->self_scm ());
63       
64       Duration dur = *unsmob_duration (ev->get_property ("duration"));
65
66       note->set_property ("duration-log", scm_int2num (dur.duration_log ()));
67       if (dur.dot_count ())
68         {
69           Item * d = make_item ("Dots", note->self_scm ());
70           Rhythmic_head::set_dots (note, d);
71           
72           if (dur.dot_count ()
73               != robust_scm2int (d->get_property ("dot-count"), 0))
74             d->set_property ("dot-count", scm_int2num (dur.dot_count ()));
75
76           d->set_parent (note, Y_AXIS);
77           
78           dots_.push (d);
79         }
80
81       Pitch *pit = unsmob_pitch (ev->get_property ("pitch"));
82
83       SCM scm_tonic = get_property ("tonic");
84       Pitch tonic (0,0,0); 
85       if (unsmob_pitch (scm_tonic))
86         tonic = *unsmob_pitch (scm_tonic);
87       
88       unsigned int delta = (pit->get_notename() - tonic.get_notename() + 7) % 7;
89       SCM shape_vector = get_property ("shapeNoteStyles");
90
91       SCM style = SCM_EOL;
92       if (ly_c_vector_p (shape_vector)
93           && SCM_VECTOR_LENGTH (shape_vector) > delta
94           && scm_is_symbol (scm_vector_ref (shape_vector, scm_from_int (delta))))
95         {
96           style = scm_vector_ref (shape_vector, scm_from_int (delta));
97         }
98       if (scm_is_symbol (style))
99         {
100           note->set_property ("style", style);
101         }
102       
103       int pos = pit ? pit->steps () : 0;
104       SCM c0 = get_property ("middleCPosition");
105       if (scm_is_number (c0))
106         pos += scm_to_int (c0);
107
108       note->set_property ("staff-position",   scm_int2num (pos));
109       notes_.push (note);
110
111
112       
113       
114       
115     }
116 }
117
118 void
119 Shape_note_heads_engraver::stop_translation_timestep ()
120 {
121   notes_.clear ();
122   dots_.clear ();
123   note_evs_.clear ();
124 }
125
126
127
128 ENTER_DESCRIPTION (Shape_note_heads_engraver,
129 /* descr */       "Generate noteheads.",
130 /* creats*/       "NoteHead Dots",
131 /* accepts */     "note-event busy-playing-event",
132 /* acks  */      "",
133 /* reads */       "middleCPosition shapeNoteStyles",
134 /* write */       "");