2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1996--2011 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 ();
44 MAKE_SCHEME_CALLBACK (Flag, width, 1);
46 Flag::width (SCM smob)
48 Grob *me = unsmob_grob (smob);
49 Stencil *sten = unsmob_stencil (me->get_property ("stencil"));
51 return ly_interval2scm (Interval (0.0, 0.0));
53 Grob *stem = me->get_parent (X_AXIS);
57 This reproduces a bad hard-coding that has been in the code for quite some time:
58 the bounding boxes for the flags are slightly off and need to be fixed.
61 return ly_interval2scm (sten->extent (X_AXIS) - stem->extent (stem, X_AXIS)[RIGHT]);
63 MAKE_SCHEME_CALLBACK (Flag, print, 1);
65 Flag::print (SCM smob)
67 Grob *me = unsmob_grob (smob);
68 Grob *stem = me->get_parent (X_AXIS);
70 Direction d = get_grob_direction (stem);
71 int log = Stem::duration_log (stem);
74 SCM flag_style_scm = me->get_property ("style");
75 if (scm_is_symbol (flag_style_scm))
76 flag_style = ly_symbol2string (flag_style_scm);
78 if (flag_style == "no-flag")
79 return Stencil ().smobbed_copy ();
83 string staffline_offs;
84 if (flag_style == "mensural")
85 /* Mensural notation: For notes on staff lines, use different
86 flags than for notes between staff lines. The idea is that
87 flags are always vertically aligned with the staff lines,
88 regardless if the note head is on a staff line or between two
89 staff lines. In other words, the inner end of a flag always
95 Real ss = Staff_symbol_referencer::staff_space (me);
96 int p = (int) (rint (stem->extent (stem, Y_AXIS)[d] * 2 / ss));
98 = Staff_symbol_referencer::on_line (stem, p) ? "0" : "1";
101 staffline_offs = "2";
106 char dir = (d == UP) ? 'u' : 'd';
107 string font_char = flag_style
108 + to_string (dir) + staffline_offs + to_string (log);
109 Font_metric *fm = Font_interface::get_default_font (me);
110 Stencil flag = fm->find_by_name ("flags." + font_char);
111 if (flag.is_empty ())
112 me->warning (_f ("flag `%s' not found", font_char));
115 TODO: maybe property stroke-style should take different values,
116 e.g. "" (i.e. no stroke), "single" and "double" (currently, it's
118 SCM stroke_style_scm = me->get_property ("stroke-style");
119 if (scm_is_string (stroke_style_scm))
121 string stroke_style = ly_scm2string (stroke_style_scm);
122 if (!stroke_style.empty ())
124 string font_char = flag_style + to_string (dir) + stroke_style;
125 Stencil stroke = fm->find_by_name ("flags." + font_char);
126 if (stroke.is_empty ())
128 font_char = to_string (dir) + stroke_style;
129 stroke = fm->find_by_name ("flags." + font_char);
131 if (stroke.is_empty ())
132 me->warning (_f ("flag stroke `%s' not found", font_char));
134 flag.add_stencil (stroke);
138 return flag.smobbed_copy ();
141 MAKE_SCHEME_CALLBACK (Flag, calc_y_offset, 1);
143 Flag::calc_y_offset (SCM smob)
145 Grob *me = unsmob_grob (smob);
146 Grob *stem = me->get_parent (X_AXIS);
147 Direction d = get_grob_direction (stem);
150 = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
152 Real y2 = stem->extent (stem, Y_AXIS)[d];
154 return scm_from_double (y2 - d * blot / 2);
157 MAKE_SCHEME_CALLBACK (Flag, calc_x_offset, 1);
159 Flag::calc_x_offset (SCM smob)
161 Grob *me = unsmob_grob (smob);
162 Grob *stem = me->get_parent (X_AXIS);
163 return scm_from_double (stem->extent (stem, X_AXIS)[RIGHT]);
167 "A flag that gets attached to a stem."
168 "The style property is symbol determining"
169 " what style of flag glyph is typeset on a"
170 " @code{Stem}. Valid options include @code{'()}"
171 " for standard flags, @code{'mensural} and"
172 " @code{'no-flag}, which switches off the flag.",