]> git.donarmstrong.com Git - lilypond.git/blob - lily/key-item.cc
release: 1.3.34
[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--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_elt_property ("c0-position", gh_int2scm (0));
27 }
28
29 void
30 Key_item::add (int p, int a)
31 {
32   pitch_arr_.push (p);
33   acc_arr_.push (a);
34 }
35
36 void
37 Key_item::add_old (int p, int a)
38 {
39   old_pitch_arr_.push (p);
40   old_acc_arr_.push (a);
41 }
42
43
44 int
45 Key_item::calculate_position(int p, int a) const
46 {
47   if (to_boolean (get_elt_property ("multi-octave")))
48     {
49       return p + gh_scm2int (get_elt_property ("c0-position"));
50     }
51   else {
52     // Find the c in the range -4 through 2
53     int from_bottom_pos = gh_scm2int (get_elt_property ("c0-position")) + 4;
54     from_bottom_pos = from_bottom_pos%7;
55     from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive.
56     int c0 = from_bottom_pos - 4;
57
58     
59     if ((a<0 && ((p>FLAT_TOP_PITCH) || (p+c0>4)) && (p+c0>1)) 
60         ||
61         (a>0 && ((p>SHARP_TOP_PITCH) || (p+c0>5)) && (p+c0>2))) 
62       {
63         p -= 7; /* Typeset below c_position */
64       }
65     /* Provide for the four cases in which there's a glitch */
66     /* it's a hack, but probably not worth */
67     /* the effort of finding a nicer solution. dl. */
68     if (c0==2 && a>0 && p==3)
69       p -= 7;
70     if (c0==-3 && a>0 && p==-1)
71       p += 7;
72     if (c0==-4 && a<0 && p==-1)
73       p += 7;
74     if (c0==-2 && a<0 && p==-3)
75       p += 7;
76     
77     return p + c0;
78   }
79 }
80
81 /*
82   TODO
83   - space the `natural' signs wider
84   - dehair this
85  */
86 Molecule 
87 Key_item::do_brew_molecule() const
88 {
89   Molecule mol;
90
91   Staff_symbol_referencer_interface si (this);
92   Real inter = si.staff_space ()/2.0;
93   
94   int j;
95   if ((break_status_dir () == LEFT || break_status_dir () == CENTER)
96       || old_pitch_arr_.size ())
97     {
98       for (int i =0; i < old_pitch_arr_.size(); i++) 
99         {
100           for (j =0; (j < pitch_arr_.size())
101                  && (old_pitch_arr_[i] != pitch_arr_[j]); j++) 
102             ;
103           
104           if (j == pitch_arr_.size()
105               || (old_pitch_arr_[i] == pitch_arr_[j]
106                   && old_acc_arr_[i] != acc_arr_[j]))
107             {
108               Molecule m =lookup_l ()->afm_find ("accidentals-0");
109
110               m.translate_axis (calculate_position(old_pitch_arr_[i], old_acc_arr_[i]) * inter, Y_AXIS);
111               mol.add_at_edge (X_AXIS, RIGHT, m,0);     
112             }
113         }
114
115       /*
116         Add half a space between  cancellation and key sig.
117
118         As suggested by [Ross], p.148.
119        */
120       Interval x(0, inter);
121       Interval y(0,0);
122
123       mol.add_at_edge (X_AXIS, RIGHT, lookup_l()->blank (Box(x,y)),0);
124     }
125  
126   for (int i =0; i < pitch_arr_.size(); i++) 
127     {
128       Molecule m = lookup_l ()->afm_find ("accidentals-" + to_str (acc_arr_[i]));
129       m.translate_axis (calculate_position(pitch_arr_[i], acc_arr_[i]) * inter, Y_AXIS);
130       mol.add_at_edge (X_AXIS, RIGHT, m, 0);
131     }
132
133   return mol;
134 }
135
136
137
138