]> git.donarmstrong.com Git - lilypond.git/blob - lily/key-item.cc
release: 1.3.19
[lilypond.git] / lily / key-item.cc
1 /*
2   key-item.cc -- implement Key_item
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1996, 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8   keyplacement by Mats Bengtsson
9 */
10
11 #include "key-item.hh"
12 #include "key.hh"
13 #include "debug.hh"
14 #include "molecule.hh"
15 #include "paper-def.hh"
16 #include "lookup.hh"
17 #include "musical-pitch.hh"
18 #include "staff-symbol-referencer.hh"
19
20 const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */
21 const int SHARP_TOP_PITCH=4; /*  ais and bis typeset in lower octave */
22
23 Key_item::Key_item ()
24 {
25   set_elt_property ("breakable", SCM_BOOL_T);
26   set_c_position (0);
27 }
28
29 int
30 Key_item::get_c_position () const
31 {
32   // Find the c in the range -4 through 2
33   int from_bottom_pos = c0_position_ + 4;       
34   from_bottom_pos = from_bottom_pos%7;
35   from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive.
36   return from_bottom_pos - 4;
37 }
38
39
40 void 
41 Key_item::set_c_position (int c0)
42 {
43   c0_position_ = c0;
44 }
45
46
47 void
48 Key_item::add (int p, int a)
49 {
50   pitch_arr_.push (p);
51   acc_arr_.push (a);
52 }
53
54 void
55 Key_item::add_old (int p, int a)
56 {
57   old_pitch_arr_.push (p);
58   old_acc_arr_.push (a);
59 }
60
61
62 int
63 Key_item::calculate_position(int p, int a) const
64 {
65   if (to_boolean (get_elt_property ("multi-octave")))
66     {
67       return p + c0_position_;
68     }
69   else {
70     if ((a<0 && ((p>FLAT_TOP_PITCH) || (p+get_c_position ()>4)) && (p+get_c_position ()>1)) 
71         ||
72         (a>0 && ((p>SHARP_TOP_PITCH) || (p+get_c_position ()>5)) && (p+get_c_position ()>2))) 
73       {
74         p -= 7; /* Typeset below c_position */
75       }
76     /* Provide for the four cases in which there's a glitch */
77     /* it's a hack, but probably not worth */
78     /* the effort of finding a nicer solution. dl. */
79     if (get_c_position ()==2 && a>0 && p==3)
80       p -= 7;
81     if (get_c_position ()==-3 && a>0 && p==-1)
82       p += 7;
83     if (get_c_position ()==-4 && a<0 && p==-1)
84       p += 7;
85     if (get_c_position ()==-2 && a<0 && p==-3)
86       p += 7;
87     return p + get_c_position ();
88   }
89 }
90
91 /*
92   TODO
93   - space the `natural' signs wider
94   - dehair this
95  */
96 Molecule*
97 Key_item::do_brew_molecule_p() const
98 {
99   Molecule*output = new Molecule;
100
101   Staff_symbol_referencer_interface si (this);
102   Real inter = si.staff_space ()/2.0;
103   
104   int j;
105   if ((break_status_dir () == LEFT || break_status_dir () == CENTER)
106       || old_pitch_arr_.size ())
107     {
108       for (int i =0; i < old_pitch_arr_.size(); i++) 
109         {
110           for (j =0; (j < pitch_arr_.size())
111                  && (old_pitch_arr_[i] != pitch_arr_[j]); j++) 
112             ;
113           
114           if (j == pitch_arr_.size()
115               || (old_pitch_arr_[i] == pitch_arr_[j]
116                   && old_acc_arr_[i] != acc_arr_[j]))
117             {
118               Molecule m =lookup_l ()->afm_find ("accidentals-0");
119
120               m.translate_axis (calculate_position(old_pitch_arr_[i], old_acc_arr_[i]) * inter, Y_AXIS);
121               output->add_at_edge (X_AXIS, RIGHT, m,0); 
122             }
123         }
124
125       /*
126         Add half a space between  cancellation and key sig.
127
128         As suggested by [Ross], p.148.
129        */
130       Interval x(0, inter);
131       Interval y(0,0);
132
133       output->add_at_edge (X_AXIS, RIGHT, lookup_l()->fill (Box(x,y)),0);
134     }
135  
136   for (int i =0; i < pitch_arr_.size(); i++) 
137     {
138       Molecule m = lookup_l ()->afm_find ("accidentals-" + to_str (acc_arr_[i]));
139       m.translate_axis (calculate_position(pitch_arr_[i], acc_arr_[i]) * inter, Y_AXIS);
140       output->add_at_edge (X_AXIS, RIGHT, m, 0);
141     }
142
143   return output;
144 }
145
146
147
148