]> git.donarmstrong.com Git - lilypond.git/blob - lily/a2-engraver.cc
patch::: 1.3.126.jcn1
[lilypond.git] / lily / a2-engraver.cc
1 /*
2   a2-engraver.cc -- implement A2_engraver
3
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "engraver.hh"
10 #include "item.hh"
11 #include "note-head.hh"
12 #include "stem.hh"
13 #include "slur.hh"
14 #include "translator-group.hh"
15 #include "side-position-interface.hh"
16 #include "directional-element-interface.hh"
17
18
19 class A2_engraver : public Engraver
20 {
21 public:
22   A2_engraver ();
23   VIRTUAL_COPY_CONS (Translator);
24 protected:
25   virtual void acknowledge_grob (Grob_info);
26   virtual void create_grobs ();
27   virtual void stop_translation_timestep ();
28 private:
29   Item* text_p_;
30   enum State { SOLO, SPLIT_INTERVAL, UNIRHYTHM, UNISILENCE, UNISON } state_;
31 };
32
33 ADD_THIS_TRANSLATOR (A2_engraver);
34
35 A2_engraver::A2_engraver ()
36 {
37   text_p_ = 0;
38   state_ = UNISILENCE;
39 }
40
41 void
42 A2_engraver::create_grobs ()
43 {
44   if (!to_boolean (get_property ("combineParts")))
45     return ;
46   if (!text_p_)
47     {
48       SCM unison = get_property ("unison");
49       SCM solo = get_property ("solo");
50       SCM solo_adue = get_property ("soloADue");
51
52       if (solo_adue == SCM_BOOL_T
53           && ((solo == SCM_BOOL_T && state_ != SOLO)
54               || (unison == SCM_BOOL_T && state_ != UNISON
55                   && daddy_trans_l_->id_str_.left_str (3) == "one")))
56         {
57           text_p_ = new Item (get_property ("TextScript"));
58           Side_position::set_axis (text_p_, Y_AXIS);
59           announce_grob (text_p_, 0);
60       
61           Direction dir = UP;
62           SCM text;
63           if (solo == SCM_BOOL_T)
64             {
65               state_ = SOLO;
66               if (daddy_trans_l_->id_str_.left_str (3) == "one")
67                 {
68                   text = get_property ("soloText");
69                 }
70               else
71                 {
72                   text = get_property ("soloIIText");
73                   dir = DOWN;
74                 }
75             }
76           else if (unison == SCM_BOOL_T)
77             {
78               state_ = UNISON;
79               if (daddy_trans_l_->id_str_.left_str (3) == "one")
80                 text = get_property ("aDueText");
81             }
82           
83           Side_position::set_direction (text_p_, dir);
84           text_p_->set_grob_property ("text", text);
85         }
86     }
87 }
88
89 void
90 A2_engraver::acknowledge_grob (Grob_info i)
91 {
92   if (!to_boolean (get_property ("combineParts")))
93     return ;
94   
95   if (text_p_)
96     {
97       if (Note_head::has_interface (i.elem_l_))
98         {
99           Grob*t = text_p_;
100           Side_position::add_support (t, i.elem_l_);
101           if (Side_position::get_axis (t) == X_AXIS
102               && !t->parent_l (Y_AXIS))
103             t->set_parent (i.elem_l_, Y_AXIS);
104         }
105       if (Stem::has_interface (i.elem_l_))
106         {
107           Side_position::add_support (text_p_, i.elem_l_);
108         }
109     }
110           
111   SCM unisilence = get_property ("unisilence");
112   SCM unison = get_property ("unison");
113   SCM unirhythm = get_property ("unirhythm");
114   SCM solo = get_property ("solo");
115   SCM split_interval = get_property ("split-interval");
116   SCM solo_adue = get_property ("soloADue");
117   
118   State previous_state = state_;
119   if (unisilence == SCM_BOOL_T)
120     /*
121       state_ = UNISILENCE;
122     */
123     ;
124   else if (solo == SCM_BOOL_T)
125     state_ = SOLO;
126   else if (unison == SCM_BOOL_T)
127     state_ = UNISON;
128   else if (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T)
129     state_ = SPLIT_INTERVAL;
130   else if (unirhythm)
131     state_ = UNIRHYTHM;
132           
133   if (Stem::has_interface (i.elem_l_)
134       || Slur::has_interface (i.elem_l_)
135       /*
136         Usually, dynamics are removed by *_devnull_engravers for the
137         second voice.  We don't want all dynamics for the first voice
138         to be placed above the staff.  */
139 #if 0
140       || i.elem_l_->has_interface (ly_symbol2scm ("dynamic-interface"))
141       || i.elem_l_->has_interface (ly_symbol2scm ("text-interface"))
142 #endif
143       )
144     {
145       /*
146         Hmm.  We must set dir when solo, in order to get
147         the rests collided to the right position
148       */
149       if ((unirhythm != SCM_BOOL_T) || (solo == SCM_BOOL_T)
150           || ((unisilence == SCM_BOOL_T && previous_state != UNISON))
151           || (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T
152               && (unison != SCM_BOOL_T || solo_adue != SCM_BOOL_T)))
153         {
154           if (daddy_trans_l_->id_str_.left_str (3) == "one")
155             {
156               i.elem_l_->set_grob_property ("direction", gh_int2scm (1));
157             }
158           else if (daddy_trans_l_->id_str_.left_str (3) == "two")
159             {
160               i.elem_l_->set_grob_property ("direction", gh_int2scm (-1));
161             }
162         }
163     }
164 }
165
166 void 
167 A2_engraver::stop_translation_timestep ()
168 {
169   if (text_p_)
170     {
171       Side_position::add_staff_support (text_p_);
172       typeset_grob (text_p_);
173       text_p_ = 0;
174     }
175 }
176