]> git.donarmstrong.com Git - lilypond.git/blob - lily/a2-engraver.cc
patch::: 1.3.130.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       // || Tie::has_interface (i.elem_l_)
136       || i.elem_l_->has_interface (ly_symbol2scm ("tie-interface"))
137       /*
138         Usually, dynamics are removed by *_devnull_engravers for the
139         second voice.  On the one hand, we don't want all dynamics for
140         the first voice to be placed above the staff.  On the other
141         hand, colliding of scripts may be worse */
142 #if 0
143       || i.elem_l_->has_interface (ly_symbol2scm ("dynamic-interface"))
144       || i.elem_l_->has_interface (ly_symbol2scm ("text-interface"))
145 #endif
146       )
147     {
148       /*
149         Hmm.  We must set dir when solo, in order to get
150         the rests collided to the right position
151       */
152       if ((unirhythm != SCM_BOOL_T) || (solo == SCM_BOOL_T)
153           || ((unisilence == SCM_BOOL_T && previous_state != UNISON))
154           || (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T
155               && (unison != SCM_BOOL_T || solo_adue != SCM_BOOL_T)))
156         {
157           if (daddy_trans_l_->id_str_.left_str (3) == "one")
158             {
159               i.elem_l_->set_grob_property ("direction", gh_int2scm (1));
160             }
161           else if (daddy_trans_l_->id_str_.left_str (3) == "two")
162             {
163               i.elem_l_->set_grob_property ("direction", gh_int2scm (-1));
164             }
165         }
166     }
167 }
168
169 void 
170 A2_engraver::stop_translation_timestep ()
171 {
172   if (text_p_)
173     {
174       Side_position::add_staff_support (text_p_);
175       typeset_grob (text_p_);
176       text_p_ = 0;
177     }
178 }
179