]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
* scm/engraver-documentation-lib.scm
[lilypond.git] / lily / custos-engraver.cc
1 /*
2   custos-engraver.cc -- implement Custos_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6  (C) 2000 Juergen Reuter <reuterj@ira.uka.de>,
7
8   Han-Wen Nienhuys <hanwen@cs.uu.nl>
9   
10 */
11
12 #include "engraver.hh"
13 #include "bar-line.hh"
14 #include "item.hh"
15 #include "note-head.hh"
16 #include "staff-symbol-referencer.hh"
17 #include "warn.hh"
18 #include "request.hh"
19
20 /*
21   This class implements an engraver for custos symbols.
22 */
23 class Custos_engraver : public Engraver
24 {
25 public:
26 TRANSLATOR_DECLARATIONS(  Custos_engraver);
27   virtual void start_translation_timestep ();
28   virtual void acknowledge_grob (Grob_info);
29   virtual void process_acknowledged_grobs ();
30   virtual void stop_translation_timestep ();
31   virtual void finalize ();
32
33
34 private:
35   Item * create_custos ();
36   bool custos_permitted;
37   Link_array<Grob> custodes_;
38   Array<Pitch> pitches_;
39 };
40
41 Custos_engraver::Custos_engraver ()
42 {
43   custos_permitted = false;
44 }
45
46
47 void
48 Custos_engraver::stop_translation_timestep ()
49 {
50   /*
51     delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
52    */
53 }
54
55 void
56 Custos_engraver::start_translation_timestep ()
57 {
58   for (int i = custodes_.size (); i--;)
59     {
60       typeset_grob (custodes_[i]);
61     }
62   custodes_.clear ();
63   pitches_.clear ();
64
65   custos_permitted = false;
66 }
67
68
69 void
70 Custos_engraver::acknowledge_grob (Grob_info info)
71 {
72   Item *item = dynamic_cast <Item *> (info.grob_);
73   if (item)
74     {
75       Music * m = info.music_cause();
76       if (Bar_line::has_interface (info.grob_))
77         custos_permitted = true;
78       else if (Note_head::has_interface (info.grob_)
79                && m
80                && m->is_mus_type ("note-event"))
81         {
82
83           /*
84             ideally, we'd do custos->set_parent (Y_AXIS, notehead),
85             but since the note head lives on the other system, we can't
86
87             So we copy the position from the note head pitch.  We
88             don't look at the staff-position, since we can't be sure
89             whether Clef_engraver already applied a vertical shift.
90           */
91             pitches_.push (*unsmob_pitch (m->get_mus_property ("pitch")));
92         }
93     }
94 }
95
96 void
97 Custos_engraver::process_acknowledged_grobs ()
98 {
99   if (gh_string_p (get_property ("whichBar")))
100     custos_permitted = true;
101   
102   if (custos_permitted)
103     {
104       for (int i = pitches_.size (); i--;)
105         {
106           Item *c = create_custos ();
107
108           int p = pitches_[i].steps ();
109           SCM c0 = get_property ("centralCPosition");
110           if (gh_number_p (c0))
111             p += gh_scm2int (c0);
112
113           
114           c->set_grob_property ("staff-position",
115                                 gh_int2scm (p));
116           
117         }
118
119       pitches_.clear ();
120     }
121 }
122
123 Item* 
124 Custos_engraver::create_custos ()
125 {
126   SCM basicProperties = get_property ("Custos");
127   Item* custos = new Item (basicProperties);
128   
129   announce_grob(custos, SCM_EOL);
130   custodes_.push (custos);
131   
132   return custos;
133 }
134
135 void
136 Custos_engraver::finalize ()
137 {
138   for (int i = custodes_.size (); i--;)
139     {
140       custodes_[i]->suicide ();
141       typeset_grob (custodes_[i]);
142     }
143   custodes_.clear ();
144 }
145
146
147
148 ENTER_DESCRIPTION(Custos_engraver,
149 /* descr */       "",
150 /* creats*/       "Custos",
151 /* accepts */     "",
152 /* acks  */      "bar-line-interface note-head-interface",
153 /* reads */       "",
154 /* write */       "");