2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2000--2010 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 "system-start-delimiter.hh"
21 #include "text-interface.hh"
22 #include "all-font-metrics.hh"
23 #include "axis-group-interface.hh"
24 #include "font-interface.hh"
26 #include "line-interface.hh"
28 #include "output-def.hh"
29 #include "pointer-group-interface.hh"
31 #include "staff-symbol-referencer.hh"
34 System_start_delimiter::staff_bracket (Grob
*me
, Real height
)
36 Font_metric
*fm
= Font_interface::get_default_font (me
);
38 Drul_array
<Stencil
> tips (fm
->find_by_name ("brackettips.down"),
39 fm
->find_by_name ("brackettips.up"));
41 Real thickness
= robust_scm2double (me
->get_property ("thickness"), 0.25);
43 Real overlap
= 0.1 * thickness
;
45 Box
box (Interval (0, thickness
),
47 * (height
/ 2 + overlap
));
49 Stencil bracket
= Lookup::filled_box (box
);
52 bracket
.add_at_edge (Y_AXIS
, d
, tips
[d
], -overlap
);
53 while (flip (&d
) != DOWN
);
54 bracket
= Stencil (box
, bracket
.expr ());
56 bracket
.translate_axis (-0.8, X_AXIS
);
62 System_start_delimiter::line_bracket (Grob
*me
, Real height
)
65 = me
->layout ()->get_dimension (ly_symbol2scm ("line-thickness"))
66 * robust_scm2double (me
->get_property ("thickness"), 1);
69 Stencil tip1
= Line_interface::make_line (thick
,
70 Offset (0, -height
/2),
71 Offset (w
, -height
/2));
72 Stencil tip2
= Line_interface::make_line (thick
,
74 Offset (w
, height
/2));
75 Stencil vline
= Line_interface::make_line (thick
,
76 Offset (0, -height
/2),
77 Offset (0, height
/2));
79 vline
.add_stencil (tip1
);
80 vline
.add_stencil (tip2
);
81 vline
.translate_axis (-w
, X_AXIS
);
86 System_start_delimiter::simple_bar (Grob
*me
, Real h
)
88 Real lt
= me
->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
89 Real w
= lt
* robust_scm2double (me
->get_property ("thickness"), 1);
90 return Lookup::round_filled_box (Box (Interval (0, w
), Interval (-h
/ 2, h
/ 2)),
94 MAKE_SCHEME_CALLBACK (System_start_delimiter
, print
, 1);
96 System_start_delimiter::print (SCM smob
)
98 Spanner
*me
= unsmob_spanner (smob
);
99 extract_grob_set (me
, "elements", elts
);
100 Grob
*common
= common_refpoint_of_array (elts
, me
, Y_AXIS
);
103 int non_empty_count
= 0;
104 for (vsize i
= elts
.size (); i
--;)
106 Spanner
*sp
= dynamic_cast<Spanner
*> (elts
[i
]);
109 && sp
->get_bound (LEFT
) == me
->get_bound (LEFT
))
111 Interval dims
= sp
->extent (common
, Y_AXIS
);
112 if (!dims
.is_empty ())
120 SCM glyph_sym
= me
->get_property ("style");
121 Real len
= ext
.length ();
123 || (robust_scm2double (me
->get_property ("collapse-height"), 0.0) >= ext
.length ()))
126 return SCM_UNSPECIFIED
;
130 if (glyph_sym
== ly_symbol2scm ("bracket"))
131 m
= staff_bracket (me
, len
);
132 else if (glyph_sym
== ly_symbol2scm ("brace"))
133 m
= staff_brace (me
, len
);
134 else if (glyph_sym
== ly_symbol2scm ("bar-line"))
135 m
= simple_bar (me
, len
);
136 else if (glyph_sym
== ly_symbol2scm ("line-bracket"))
137 m
= line_bracket (me
, len
);
139 m
.translate_axis (ext
.center (), Y_AXIS
);
140 return m
.smobbed_copy ();
144 System_start_delimiter::staff_brace (Grob
*me
, Real y
)
149 Find the default brace font if the user overrides it.
151 fm
= Font_interface::get_default_font (me
);
155 int hi
= max ((int) fm
->count () - 1, 2);
157 /* do a binary search for each Y, not very efficient, but passable? */
161 int cmp
= (lo
+ hi
) / 2;
162 b
= fm
->get_indexed_char_dimensions (cmp
);
163 if (b
[Y_AXIS
].is_empty () || b
[Y_AXIS
].length () > y
)
170 Stencil
stil (fm
->find_by_name ("brace" + to_string (lo
)));
171 stil
.translate_axis (-b
[X_AXIS
].length ()/2, X_AXIS
);
173 stil
.translate_axis (-0.2, X_AXIS
);
178 ADD_INTERFACE (System_start_delimiter
,
179 "The brace, bracket or bar in front of the system. The"
180 " following values for @code{style} are recognized:\n"
184 "A thick bracket, normally used to group similar"
185 " instruments in a score. Default for @code{StaffGroup}."
186 " @code{SystemStartBracket} uses this style.\n"
188 "A @q{piano style} brace normally used for an instrument"
189 " that uses two staves. The default style for"
190 " @code{GrandStaff}. @code{SystemStartBrace} uses this"
193 "A simple line between the staves in a score. Default"
194 " for staves enclosed in @code{<<} and @code{>>}."
195 " @code{SystemStartBar} uses this style.\n"
196 "@item line-bracket\n"
197 "A simple square, normally used for subgrouping"
198 " instruments in a score. @code{SystemStartSquare} uses"
202 "See also @file{input/regression/system-start-nesting.ly}.",