]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
release: 1.5.13
[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.hh"
14 #include "item.hh"
15 #include "note-head.hh"
16 #include "staff-symbol-referencer.hh"
17 #include "warn.hh"
18 #include "musical-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 create_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> custos_arr_;
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 = custos_arr_.size (); i--;)
59     {
60       typeset_grob (custos_arr_[i]);
61     }
62   custos_arr_.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_l_);
73   if (item)
74     {
75       if (Bar::has_interface (info.grob_l_))
76         custos_permitted = true;
77       else if (Note_head::has_interface (info.grob_l_))
78         {
79
80           /*
81             ideally, we'd do custos->set_parent (Y_AXIS, notehead),
82             but since the note head lives on the other system, we can't
83
84             So we copy the position from the note head pitch.  We
85             don't look at the staff-position, since we can't be sure
86             whether Clef_engraver already applied a vertical shift.
87           */
88           Note_req * nr = dynamic_cast<Note_req*> (info.req_l_);
89           if (nr)
90             pitches_.push (*unsmob_pitch (nr->get_mus_property ("pitch")));
91         }
92     }
93 }
94
95 void
96 Custos_engraver::create_grobs ()
97 {
98   if (gh_string_p (get_property ("whichBar")))
99     custos_permitted = true;
100   
101   if (custos_permitted)
102     {
103       for (int i = pitches_.size (); i--;)
104         {
105           Item *c = create_custos ();
106
107           int p = pitches_[i].steps ();
108           SCM c0 = get_property ("centralCPosition");
109           if (gh_number_p (c0))
110             p += gh_scm2int (c0);
111
112           
113           c->set_grob_property ("staff-position",
114                                 gh_int2scm (p));
115           
116         }
117
118       pitches_.clear ();
119     }
120 }
121
122 Item* 
123 Custos_engraver::create_custos ()
124 {
125   SCM basicProperties = get_property ("Custos");
126   Item* custos = new Item (basicProperties);
127   
128   announce_grob (custos, 0);
129   custos_arr_.push (custos);
130   
131   return custos;
132 }
133
134 void
135 Custos_engraver::finalize ()
136 {
137   for (int i = custos_arr_.size (); i--;)
138     {
139       custos_arr_[i]->suicide ();
140       typeset_grob (custos_arr_[i]);
141     }
142   custos_arr_.clear ();
143 }
144
145
146
147 ENTER_DESCRIPTION(Custos_engraver,
148 /* descr */       "",
149 /* creats*/       "Custos",
150 /* acks  */       "bar-line-interface note-head-interface",
151 /* reads */       "",
152 /* write */       "");