Fixes Issue 1504, allowing feather beam line breaking.
[lilypond/patrick.git] / lily / key-signature-interface.cc
blobf05dc7dabe9019dc3ef49de900d47420a79410da
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 keyplacement by Mats Bengtsson
8 LilyPond is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 LilyPond is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
22 #include "accidental-interface.hh"
23 #include "font-interface.hh"
24 #include "international.hh"
25 #include "item.hh"
26 #include "lookup.hh"
27 #include "output-def.hh"
28 #include "staff-symbol-referencer.hh"
29 #include "rational.hh"
31 struct Key_signature_interface
33 DECLARE_SCHEME_CALLBACK (print, (SCM));
34 DECLARE_GROB_INTERFACE ();
39 TODO
40 - space the `natural' signs wider
42 MAKE_SCHEME_CALLBACK (Key_signature_interface, print, 1);
43 SCM
44 Key_signature_interface::print (SCM smob)
46 Item *me = dynamic_cast<Item *> (unsmob_grob (smob));
48 Real inter = Staff_symbol_referencer::staff_space (me) / 2.0;
50 Stencil mol;
52 SCM c0s = me->get_property ("c0-position");
54 bool is_cancellation = me->internal_has_interface
55 (ly_symbol2scm ("key-cancellation-interface"));
58 SCM lists are stacks, so we work from right to left, ending with
59 the cancellation signature.
62 int last_pos = -1000;
63 SCM last_glyph_name = SCM_BOOL_F;
64 SCM padding_pairs = me->get_property ("padding-pairs");
66 Font_metric *fm = Font_interface::get_default_font (me);
67 SCM alist = me->get_property ("glyph-name-alist");
69 for (SCM s = me->get_property ("alteration-alist"); scm_is_pair (s); s = scm_cdr (s))
71 SCM alt = is_cancellation
72 ? scm_from_int (0)
73 : scm_cdar (s);
75 SCM glyph_name_scm = ly_assoc_get (alt, alist, SCM_BOOL_F);
76 if (!scm_is_string (glyph_name_scm))
78 me->warning (_f ("No glyph found for alteration: %s",
79 ly_scm2rational (alt).to_string ().c_str ()));
80 continue;
83 string glyph_name = ly_scm2string (glyph_name_scm);
85 Stencil acc (fm->find_by_name (glyph_name));
87 if (acc.is_empty ())
88 me->warning (_ ("alteration not found"));
89 else
91 SCM what = scm_caar (s);
93 SCM proc = ly_lily_module_constant ("key-signature-interface::alteration-position");
95 int pos = scm_to_int (scm_call_3 (proc, what, scm_cdar (s), c0s));
96 acc.translate_axis (pos * inter, Y_AXIS);
99 The natural sign (unlike flat & sharp)
100 has vertical edges on both sides. A little padding is
101 needed to prevent collisions.
103 Real padding = robust_scm2double (me->get_property ("padding"),
104 0.0);
105 SCM handle = scm_assoc (scm_cons (glyph_name_scm, last_glyph_name),
106 padding_pairs);
107 if (scm_is_pair (handle))
108 padding = robust_scm2double (scm_cdr (handle), 0.0);
109 else if (glyph_name == "accidentals.natural"
110 && last_pos < pos + 2
111 && last_pos > pos - 6)
112 padding += 0.3;
114 mol.add_at_edge (X_AXIS, LEFT, acc, padding);
116 last_pos = pos;
117 last_glyph_name = glyph_name_scm;
121 mol.align_to (X_AXIS, LEFT);
123 return mol.smobbed_copy ();
126 ADD_INTERFACE (Key_signature_interface,
127 "A group of accidentals, to be printed as signature sign.",
129 /* properties */
130 "alteration-alist "
131 "c0-position "
132 "glyph-name-alist "
133 "padding "
134 "padding-pairs "