2 key-item.cc -- implement Key_signature_interface
4 source file of the GNU LilyPond music typesetter
6 (c) 1996--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
8 keyplacement by Mats Bengtsson
11 #include "accidental-interface.hh"
12 #include "font-interface.hh"
13 #include "international.hh"
16 #include "output-def.hh"
17 #include "staff-symbol-referencer.hh"
18 #include "rational.hh"
20 struct Key_signature_interface
22 DECLARE_SCHEME_CALLBACK (print
, (SCM
));
23 DECLARE_GROB_INTERFACE ();
29 - space the `natural' signs wider
31 MAKE_SCHEME_CALLBACK (Key_signature_interface
, print
, 1);
33 Key_signature_interface::print (SCM smob
)
35 Item
*me
= dynamic_cast<Item
*> (unsmob_grob (smob
));
37 Real inter
= Staff_symbol_referencer::staff_space (me
) / 2.0;
41 SCM c0s
= me
->get_property ("c0-position");
43 bool is_cancellation
= me
->internal_has_interface
44 (ly_symbol2scm ("key-cancellation-interface"));
47 SCM lists are stacks, so we work from right to left, ending with
48 the cancellation signature.
52 SCM last_glyph_name
= SCM_BOOL_F
;
53 SCM padding_pairs
= me
->get_property ("padding-pairs");
55 Font_metric
*fm
= Font_interface::get_default_font (me
);
56 SCM alist
= me
->get_property ("glyph-name-alist");
58 for (SCM s
= me
->get_property ("alteration-alist"); scm_is_pair (s
); s
= scm_cdr (s
))
60 SCM alt
= is_cancellation
64 SCM glyph_name_scm
= ly_assoc_get (alt
, alist
, SCM_BOOL_F
);
65 if (!scm_is_string (glyph_name_scm
))
67 me
->warning (_f ("No glyph found for alteration: %s",
68 ly_scm2rational (alt
).to_string ().c_str ()));
72 string glyph_name
= ly_scm2string (glyph_name_scm
);
74 Stencil
acc (fm
->find_by_name (glyph_name
));
77 me
->warning (_ ("alteration not found"));
80 SCM what
= scm_caar (s
);
82 SCM proc
= ly_lily_module_constant ("key-signature-interface::alteration-position");
84 int pos
= scm_to_int (scm_call_3 (proc
, what
, scm_cdar (s
), c0s
));
85 acc
.translate_axis (pos
* inter
, Y_AXIS
);
88 The natural sign (unlike flat & sharp)
89 has vertical edges on both sides. A little padding is
90 needed to prevent collisions.
92 Real padding
= robust_scm2double (me
->get_property ("padding"),
94 SCM handle
= scm_assoc (scm_cons (glyph_name_scm
, last_glyph_name
),
96 if (scm_is_pair (handle
))
97 padding
= robust_scm2double (scm_cdr (handle
), 0.0);
98 else if (glyph_name
== "accidentals.natural"
100 && last_pos
> pos
- 6)
103 mol
.add_at_edge (X_AXIS
, LEFT
, acc
, padding
);
106 last_glyph_name
= glyph_name_scm
;
110 mol
.align_to (X_AXIS
, LEFT
);
112 return mol
.smobbed_copy ();
115 ADD_INTERFACE (Key_signature_interface
,
116 "A group of accidentals, to be printed as signature sign.",