2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2001--2014 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 "accidental-interface.hh"
21 #include "font-interface.hh"
22 #include "international.hh"
24 #include "output-def.hh"
25 #include "paper-column.hh"
28 #include "skyline-pair.hh"
31 parenthesize (Grob *me, Stencil m)
34 = Font_interface::get_default_font (me);
36 = font->find_by_name ("accidentals.leftparen");
38 = font->find_by_name ("accidentals.rightparen");
40 m.add_at_edge (X_AXIS, LEFT, Stencil (open), 0);
41 m.add_at_edge (X_AXIS, RIGHT, Stencil (close), 0);
46 /* If this gets called before line breaking, we will return a non-trivial
47 extent even if we belong to a tie and won't actually get printed. */
49 get_extent (Grob *me, Axis a)
51 Stencil *s = unsmob_stencil (Accidental_interface::get_stencil (me));
54 return ly_interval2scm (s->extent (a));
55 return ly_interval2scm (Interval ());
58 MAKE_SCHEME_CALLBACK (Accidental_interface, height, 1);
60 Accidental_interface::height (SCM smob)
62 return get_extent (unsmob_grob (smob), Y_AXIS);
65 MAKE_SCHEME_CALLBACK (Accidental_interface, width, 1);
67 Accidental_interface::width (SCM smob)
69 return get_extent (unsmob_grob (smob), X_AXIS);
72 MAKE_SCHEME_CALLBACK (Accidental_interface, horizontal_skylines, 1);
74 Accidental_interface::horizontal_skylines (SCM smob)
76 Grob *me = unsmob_grob (smob);
78 return Skyline_pair ().smobbed_copy ();
81 * Using the print function may trigger a suicide
82 * before line breaking. It is therefore `unpure' (c).
83 * We use the more basic get_stencil.
85 Stencil *my_stencil = unsmob_stencil (get_stencil (me));
87 return Skyline_pair ().smobbed_copy ();
91 (Stencil::skylines_from_stencil
92 (my_stencil->smobbed_copy (), 0.0, Y_AXIS));
94 SCM alist = me->get_property ("glyph-name-alist");
95 SCM alt = me->get_property ("alteration");
96 string glyph_name = robust_scm2string (ly_assoc_get (alt, alist, SCM_BOOL_F),
98 if (glyph_name == "accidentals.flat"
99 || glyph_name == "accidentals.flatflat")
101 // a bit more padding for the right of the stem
102 // we raise the stem horizontally to a bit less than the average
103 // horizontal "height" of the entire glyph. This will bring flats
104 // closer to doubleflats, which looks better (MS opinion).
105 // this should work for all fonts where the flat is not
106 // completely bizarre
107 Real left = my_stencil->extent (X_AXIS)[LEFT];
108 Real right = my_stencil->extent (X_AXIS)[RIGHT] * 0.375;
109 Real down = my_stencil->extent (Y_AXIS)[DOWN];
110 Real up = my_stencil->extent (Y_AXIS)[UP];
112 boxes.push_back (Box (Interval (left, right), Interval (down, up)));
113 Skyline merge_with_me (boxes, Y_AXIS, RIGHT);
114 (*sky)[RIGHT].merge (merge_with_me);
116 return sky->smobbed_copy ();
119 MAKE_SCHEME_CALLBACK (Accidental_interface, pure_height, 3);
121 Accidental_interface::pure_height (SCM smob, SCM start_scm, SCM)
123 Item *me = dynamic_cast<Item *> (unsmob_grob (smob));
124 int start = scm_to_int (start_scm);
125 int rank = me->get_column ()->get_rank ();
127 if (to_boolean (me->get_property ("forced"))
128 || !unsmob_grob (me->get_object ("tie"))
129 || (rank == start + 1 && /* we are at the start of a line */
130 !to_boolean (me->get_property ("hide-tied-accidental-after-break"))))
132 Stencil *s = unsmob_stencil (get_stencil (me));
134 return ly_interval2scm (s->extent (Y_AXIS));
137 return ly_interval2scm (Interval ());
140 MAKE_SCHEME_CALLBACK (Accidental_interface, print, 1);
142 Accidental_interface::print (SCM smob)
144 Grob *me = unsmob_grob (smob);
145 Grob *tie = unsmob_grob (me->get_object ("tie"));
148 && (to_boolean (me->get_property ("hide-tied-accidental-after-break"))
149 || (!tie->original () && !to_boolean (me->get_property ("forced")))))
155 return get_stencil (me);
159 Accidental_interface::get_stencil (Grob *me)
161 Font_metric *fm = Font_interface::get_default_font (me);
163 SCM alist = me->get_property ("glyph-name-alist");
164 SCM alt = me->get_property ("alteration");
165 SCM glyph_name = ly_assoc_get (alt, alist, SCM_BOOL_F);
168 if (!scm_is_string (glyph_name))
170 me->warning (_f ("Could not find glyph-name for alteration %s",
171 ly_scm_write_string (alt).c_str ()));
172 mol = fm->find_by_name ("noteheads.s1cross");
175 mol = fm->find_by_name (ly_scm2string (glyph_name));
177 if (to_boolean (me->get_property ("restore-first")))
180 this isn't correct for ancient accidentals, but they don't
181 use double flats/sharps anyway.
183 Stencil acc (fm->find_by_name ("accidentals.natural"));
186 me->warning (_ ("natural alteration glyph not found"));
188 mol.add_at_edge (X_AXIS, LEFT, acc, 0.1);
191 if (to_boolean (me->get_property ("parenthesized")))
192 mol = parenthesize (me, mol);
194 return mol.smobbed_copy ();
197 ADD_INTERFACE (Accidental_interface,
198 "A single accidental.",
206 "hide-tied-accidental-after-break "