]> git.donarmstrong.com Git - lilypond.git/blob - lily/key-item.cc
release: 1.1.4
[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--1998 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
19 const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */
20 const int SHARP_TOP_PITCH=4; /*  ais and bis typeset in lower octave */
21
22 Key_item::Key_item ()
23 {
24   breakable_b_ =true;
25   default_b_ = false;
26   set_c_position (0);
27 }
28
29 void 
30 Key_item::set_c_position (int c0)
31 {
32   c0_position = c0;
33   // Find the c in the range -4 through 2
34   int from_bottom_pos = c0 + 4; 
35   from_bottom_pos = from_bottom_pos%7;
36   from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive.
37   c_position  = from_bottom_pos - 4;
38 }
39
40
41 void
42 Key_item::add (int p, int a)
43 {
44   pitch_arr_.push (p);
45   acc_arr_.push (a);
46 }
47
48 void
49 Key_item::add_old (int p, int a)
50 {
51   old_pitch_arr_.push (p);
52   old_acc_arr_.push (a);
53 }
54
55
56 int
57 Key_item::calculate_position(int p, int a) const
58 {
59   if (multi_octave_b_) 
60     {
61       return p + c0_position;
62     }
63   else {
64     if ((a<0 && ((p>FLAT_TOP_PITCH) || (p+c_position>4)) && (p+c_position>1)) 
65         ||
66         (a>0 && ((p>SHARP_TOP_PITCH) || (p+c_position>5)) && (p+c_position>2))) 
67       {
68         p -= 7; /* Typeset below c_position */
69       }
70     return p + c_position;
71   }
72 }
73
74 /*
75   TODO space the `natural' signs wider
76  */
77 Molecule*
78 Key_item::brew_molecule_p() const
79 {
80   Molecule*output = new Molecule;
81   Real inter = paper()->internote_f ();
82   
83   int j;
84   if ((break_status_dir_ == LEFT || break_status_dir_ == CENTER)
85       || old_pitch_arr_.size ())
86     {
87       for (int i =0; i < old_pitch_arr_.size(); i++) 
88         {
89           for (j =0; (j < pitch_arr_.size())
90                  && (old_pitch_arr_[i] != pitch_arr_[j]); j++) 
91             ;
92           
93           if (j == pitch_arr_.size()
94               || (old_pitch_arr_[i] == pitch_arr_[j]
95                   && old_acc_arr_[i] != acc_arr_[j]))
96             {
97               Molecule m =lookup_l ()->accidental (0,false);
98               m.translate_axis (calculate_position(old_pitch_arr_[i], old_acc_arr_[i]) * inter, Y_AXIS);
99               output->add_at_edge (X_AXIS, RIGHT, m);   
100             }
101         }
102
103       /*
104         Add half a space between  cancellation and key sig.
105
106         As suggested by [Ross], p.148.
107        */
108       Interval x(0, inter);
109       Interval y(0,0);
110
111       output->add_at_edge (X_AXIS, RIGHT, lookup_l()->fill (Box(x,y)));
112     }
113  
114   for (int i =0; i < pitch_arr_.size(); i++) 
115     {
116       Molecule m =lookup_l ()->accidental (acc_arr_[i],false);
117       m.translate_axis (calculate_position(pitch_arr_[i], acc_arr_[i]) * inter, Y_AXIS);
118       output->add_at_edge (X_AXIS, RIGHT, m);   
119     }
120   if (pitch_arr_.size()) 
121     {
122       Molecule m (lookup_l ()->fill (Box (
123                                           Interval (0, paper()->note_width ()),
124                                           Interval (0,0))));
125       
126       output->add_at_edge (X_AXIS, RIGHT, m);
127     }
128   return output;
129 }
130
131 IMPLEMENT_IS_TYPE_B1(Key_item,Item);
132
133 void 
134 Key_item::do_pre_processing()
135 {
136   if (default_b_) 
137     {
138       transparent_b_ = (break_status_dir() != RIGHT);
139       set_empty (transparent_b_);
140     }
141 }