lilypond-1.3.11
[lilypond.git] / lily / key-item.cc
blobc39f0e4e5cfcec987d9f85ceec7844fcb8375bcd
1 /*
2 key-item.cc -- implement Key_item
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 keyplacement by Mats Bengtsson
9 */
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"
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 */
23 Key_item::Key_item ()
25 multi_octave_b_ = false;
26 set_elt_property ("breakable", SCM_BOOL_T);
27 set_c_position (0);
30 int
31 Key_item::get_c_position () const
33 // Find the c in the range -4 through 2
34 int from_bottom_pos = c0_position_ + 4;
35 from_bottom_pos = from_bottom_pos%7;
36 from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive.
37 return from_bottom_pos - 4;
41 void
42 Key_item::set_c_position (int c0)
44 c0_position_ = c0;
48 void
49 Key_item::add (int p, int a)
51 pitch_arr_.push (p);
52 acc_arr_.push (a);
55 void
56 Key_item::add_old (int p, int a)
58 old_pitch_arr_.push (p);
59 old_acc_arr_.push (a);
63 int
64 Key_item::calculate_position(int p, int a) const
66 if (multi_octave_b_)
68 return p + c0_position_;
70 else {
71 if ((a<0 && ((p>FLAT_TOP_PITCH) || (p+get_c_position ()>4)) && (p+get_c_position ()>1))
73 (a>0 && ((p>SHARP_TOP_PITCH) || (p+get_c_position ()>5)) && (p+get_c_position ()>2)))
75 p -= 7; /* Typeset below c_position */
77 /* Provide for the four cases in which there's a glitch */
78 /* it's a hack, but probably not worth */
79 /* the effort of finding a nicer solution. dl. */
80 if (get_c_position ()==2 && a>0 && p==3)
81 p -= 7;
82 if (get_c_position ()==-3 && a>0 && p==-1)
83 p += 7;
84 if (get_c_position ()==-4 && a<0 && p==-1)
85 p += 7;
86 if (get_c_position ()==-2 && a<0 && p==-3)
87 p += 7;
88 return p + get_c_position ();
93 TODO
94 - space the `natural' signs wider
95 - dehair this
97 Molecule*
98 Key_item::do_brew_molecule_p() const
100 Molecule*output = new Molecule;
102 Staff_symbol_referencer_interface si (this);
103 Real inter = si.staff_line_leading_f ()/2.0;
105 int j;
106 if ((break_status_dir () == LEFT || break_status_dir () == CENTER)
107 || old_pitch_arr_.size ())
109 for (int i =0; i < old_pitch_arr_.size(); i++)
111 for (j =0; (j < pitch_arr_.size())
112 && (old_pitch_arr_[i] != pitch_arr_[j]); j++)
115 if (j == pitch_arr_.size()
116 || (old_pitch_arr_[i] == pitch_arr_[j]
117 && old_acc_arr_[i] != acc_arr_[j]))
119 Molecule m =lookup_l ()->afm_find ("accidentals-0");
121 m.translate_axis (calculate_position(old_pitch_arr_[i], old_acc_arr_[i]) * inter, Y_AXIS);
122 output->add_at_edge (X_AXIS, RIGHT, m,0);
127 Add half a space between cancellation and key sig.
129 As suggested by [Ross], p.148.
131 Interval x(0, inter);
132 Interval y(0,0);
134 output->add_at_edge (X_AXIS, RIGHT, lookup_l()->fill (Box(x,y)),0);
137 for (int i =0; i < pitch_arr_.size(); i++)
139 Molecule m = lookup_l ()->afm_find ("accidentals-" + to_str (acc_arr_[i]));
140 m.translate_axis (calculate_position(pitch_arr_[i], acc_arr_[i]) * inter, Y_AXIS);
141 output->add_at_edge (X_AXIS, RIGHT, m, 0);
144 return output;