2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
20 #include "note-head.hh"
24 #include <algorithm> // min, max
28 #include "directional-element-interface.hh"
29 #include "font-interface.hh"
31 #include "international.hh"
32 #include "staff-symbol.hh"
33 #include "staff-symbol-referencer.hh"
37 internal_print (Grob
*me
, string
*font_char
)
39 SCM style
= me
->get_property ("style");
40 if (!scm_is_symbol (style
))
41 style
= ly_symbol2scm ("default");
43 string suffix
= to_string (min (robust_scm2int (me
->get_property ("duration-log"), 2), 2));
44 if (style
!= ly_symbol2scm ("default"))
46 SCM gn
= me
->get_property ("glyph-name");
47 if (scm_is_string (gn
))
48 suffix
= ly_scm2string (gn
);
51 Font_metric
*fm
= Font_interface::get_default_font (me
);
56 idx_symmetric
= idx_either
= "noteheads.s" + suffix
;
57 Stencil out
= fm
->find_by_name (idx_symmetric
);
60 string prefix
= "noteheads.";
62 Grob
*stem
= unsmob_grob (me
->get_object ("stem"));
63 Direction stem_dir
= stem
? get_grob_direction (stem
) : CENTER
;
65 if (stem_dir
== CENTER
)
66 programming_error ("must have stem dir for note head");
68 idx_directed
= idx_either
=
69 prefix
+ ((stem_dir
== UP
) ? "u" : "d") + suffix
;
70 out
= fm
->find_by_name (idx_directed
);
76 me
->warning (_f ("none of note heads `%s' or `%s' found",
77 idx_symmetric
.c_str (), idx_directed
.c_str ()));
78 out
= Stencil (Box (Interval (0, 0), Interval (0, 0)), SCM_EOL
);
81 *font_char
= idx_either
;
87 TODO: make stem X-parent of notehead.
89 MAKE_SCHEME_CALLBACK (Note_head
, stem_x_shift
, 1);
91 Note_head::stem_x_shift (SCM smob
)
93 Grob
*me
= unsmob_grob (smob
);
94 Grob
*stem
= unsmob_grob (me
->get_object ("stem"));
96 (void) stem
->get_property ("positioning-done");
98 return scm_from_int (0);
101 MAKE_SCHEME_CALLBACK (Note_head
, print
, 1);
103 Note_head::print (SCM smob
)
105 Grob
*me
= unsmob_grob (smob
);
108 return internal_print (me
, &idx
).smobbed_copy ();
111 MAKE_SCHEME_CALLBACK (Note_head
, include_ledger_line_height
, 1);
113 Note_head::include_ledger_line_height (SCM smob
)
115 Grob
*me
= unsmob_grob (smob
);
116 Grob
*staff
= Staff_symbol_referencer::get_staff_symbol (me
);
120 Real ss
= Staff_symbol::staff_space (staff
);
121 Interval lines
= Staff_symbol::line_span (staff
) * (ss
/ 2.0);
122 Real my_pos
= Staff_symbol_referencer::get_position (me
) * ss
/ 2.0;
123 Interval my_ext
= me
->extent (me
, Y_AXIS
) + my_pos
;
125 // The +1 and -1 come from the fact that we only want to add
126 // the interval between the note and the first ledger line, not
127 // the whole interval between the note and the staff.
128 Interval
iv (min (0.0, lines
[UP
] - my_ext
[DOWN
] + 1),
129 max (0.0, lines
[DOWN
] - my_ext
[UP
] - 1));
130 return ly_interval2scm (iv
);
133 return ly_interval2scm (Interval (0, 0));
137 Note_head::stem_attachment_coordinate (Grob
*me
, Axis a
)
139 Offset off
= robust_scm2offset (me
->get_property ("stem-attachment"),
146 Note_head::get_stem_attachment (Font_metric
*fm
, string key
)
150 int k
= fm
->name_to_index (key
);
153 Box b
= fm
->get_indexed_char_dimensions (k
);
154 Offset wxwy
= fm
->attachment_point (key
);
155 for (int i
= X_AXIS
; i
< NO_AXES
; i
++)
162 att
[a
] = (2 * (wxwy
[a
] - v
.center ()) / v
.length ());
170 MAKE_SCHEME_CALLBACK (Note_head
, calc_stem_attachment
, 1);
172 Note_head::calc_stem_attachment (SCM smob
)
174 Grob
*me
= unsmob_grob (smob
);
175 Font_metric
*fm
= Font_interface::get_default_font (me
);
177 internal_print (me
, &key
);
179 return ly_offset2scm (get_stem_attachment (fm
, key
));
183 ADD_INTERFACE (Note_head
,
184 "A note head. There are many possible values for"
185 " @code{style}. For a complete list, see"
186 " @ruser{Note head styles}.",