2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1996--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 Jan Nieuwenhuizen <janneke@gnu.org>
7 LilyPond is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
23 #include "directional-element-interface.hh"
24 #include "font-interface.hh"
26 #include "international.hh"
27 #include "output-def.hh"
28 #include "staff-symbol-referencer.hh"
35 DECLARE_SCHEME_CALLBACK (print, (SCM));
36 DECLARE_SCHEME_CALLBACK (width, (SCM));
37 DECLARE_SCHEME_CALLBACK (calc_y_offset, (SCM));
38 DECLARE_SCHEME_CALLBACK (calc_x_offset, (SCM));
39 DECLARE_GROB_INTERFACE ();
42 MAKE_SCHEME_CALLBACK (Flag, width, 1);
44 Flag::width (SCM smob)
46 Grob *me = unsmob_grob (smob);
47 Stencil *sten = unsmob_stencil (me->get_property ("stencil"));
49 return ly_interval2scm (Interval (0.0, 0.0));
51 Grob *stem = me->get_parent (X_AXIS);
55 This reproduces a bad hard-coding that has been in the code for quite some time:
56 the bounding boxes for the flags are slightly off and need to be fixed.
59 return ly_interval2scm (sten->extent (X_AXIS) - stem->extent (stem, X_AXIS)[RIGHT]);
61 MAKE_SCHEME_CALLBACK (Flag, print, 1);
63 Flag::print (SCM smob)
65 Grob *me = unsmob_grob (smob);
66 Grob *stem = me->get_parent (X_AXIS);
68 Direction d = get_grob_direction (stem);
69 int log = Stem::duration_log (stem);
72 SCM flag_style_scm = me->get_property ("style");
73 if (scm_is_symbol (flag_style_scm))
74 flag_style = ly_symbol2string (flag_style_scm);
76 if (flag_style == "no-flag")
77 return Stencil ().smobbed_copy ();
81 string staffline_offs;
82 if (flag_style == "mensural")
83 /* Mensural notation: For notes on staff lines, use different
84 flags than for notes between staff lines. The idea is that
85 flags are always vertically aligned with the staff lines,
86 regardless if the note head is on a staff line or between two
87 staff lines. In other words, the inner end of a flag always
93 Real ss = Staff_symbol_referencer::staff_space (me);
94 int p = (int) (rint (stem->extent (stem, Y_AXIS)[d] * 2 / ss));
96 = Staff_symbol_referencer::on_line (stem, p) ? "0" : "1";
104 char dir = (d == UP) ? 'u' : 'd';
105 string font_char = flag_style
106 + to_string (dir) + staffline_offs + to_string (log);
107 Font_metric *fm = Font_interface::get_default_font (me);
108 Stencil flag = fm->find_by_name ("flags." + font_char);
109 if (flag.is_empty ())
110 me->warning (_f ("flag `%s' not found", font_char));
113 TODO: maybe property stroke-style should take different values,
114 e.g. "" (i.e. no stroke), "single" and "double" (currently, it's
116 SCM stroke_style_scm = me->get_property ("stroke-style");
117 if (scm_is_string (stroke_style_scm))
119 string stroke_style = ly_scm2string (stroke_style_scm);
120 if (!stroke_style.empty ())
122 string font_char = flag_style + to_string (dir) + stroke_style;
123 Stencil stroke = fm->find_by_name ("flags." + font_char);
124 if (stroke.is_empty ())
126 font_char = to_string (dir) + stroke_style;
127 stroke = fm->find_by_name ("flags." + font_char);
129 if (stroke.is_empty ())
130 me->warning (_f ("flag stroke `%s' not found", font_char));
132 flag.add_stencil (stroke);
136 return flag.smobbed_copy ();
139 MAKE_SCHEME_CALLBACK (Flag, calc_y_offset, 1);
141 Flag::calc_y_offset (SCM smob)
143 Grob *me = unsmob_grob (smob);
144 Grob *stem = me->get_parent (X_AXIS);
145 Direction d = get_grob_direction (stem);
148 = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
150 Real y2 = stem->extent (stem, Y_AXIS)[d];
152 return scm_from_double (y2 - d * blot / 2);
155 MAKE_SCHEME_CALLBACK (Flag, calc_x_offset, 1);
157 Flag::calc_x_offset (SCM smob)
159 Grob *me = unsmob_grob (smob);
160 Grob *stem = me->get_parent (X_AXIS);
161 return scm_from_double (stem->extent (stem, X_AXIS)[RIGHT]);
165 "A flag that gets attached to a stem."
166 "The style property is symbol determining"
167 " what style of flag glyph is typeset on a"
168 " @code{Stem}. Valid options include @code{'()}"
169 " for standard flags, @code{'mensural} and"
170 " @code{'no-flag}, which switches off the flag.",