2 system-start-delimiter.cc -- implement Nested_system_start_delimiter
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
9 #include "system-start-delimiter.hh"
11 #include "axis-group-interface.hh"
12 #include "output-def.hh"
13 #include "font-interface.hh"
14 #include "all-font-metrics.hh"
15 #include "staff-symbol-referencer.hh"
19 #include "pointer-group-interface.hh"
22 struct Nested_system_start_delimiter
25 bool has_interface (Grob *);
26 Stencil static make_substencil (Spanner *, Grob *, SCM, SCM, SCM);
27 DECLARE_SCHEME_CALLBACK (print, (SCM));
31 flatten_hierarchy (SCM hier)
33 Link_array<Grob> retval;
34 if (unsmob_grob (hier))
35 retval.push (unsmob_grob (hier));
37 if (scm_is_pair (hier))
39 retval = flatten_hierarchy (scm_car (hier));
40 retval.concat (flatten_hierarchy (scm_cdr (hier)));
48 Nested_system_start_delimiter::make_substencil (Spanner *me,
56 Link_array<Grob> elts = flatten_hierarchy (hierarchy);
61 int non_empty_count = 0;
62 for (int i = elts.size (); i--;)
64 Spanner *sp = dynamic_cast<Spanner *> (elts[i]);
67 && sp->get_bound (LEFT) == me->get_bound (LEFT))
69 Interval dims = sp->extent (common, Y_AXIS);
70 if (!dims.is_empty ())
78 SCM glyph_sym = ly_symbol2scm ("bracket");
79 if (scm_is_pair (depth_styles))
80 glyph_sym = scm_car (depth_styles);
83 || (robust_scm2double (me->get_property ("collapse-height"), 0.0) >= ext.length()))
90 Real len = ext.length ();
91 if (glyph_sym == ly_symbol2scm ("bracket"))
92 total = System_start_delimiter::staff_bracket (me, len);
93 else if (glyph_sym == ly_symbol2scm ("brace"))
94 total = System_start_delimiter::staff_brace (me, len);
95 else if (glyph_sym == ly_symbol2scm ("bar-line"))
96 total = System_start_delimiter::simple_bar (me, len);
97 else if (glyph_sym == ly_symbol2scm ("line-bracket"))
98 total = System_start_delimiter::line_bracket (me, len);
100 total.translate_axis (ext.center (), Y_AXIS);
102 Real left_x = total.extent (X_AXIS)[LEFT];
103 for (SCM s = hierarchy; scm_is_pair (s); s = scm_cdr (s))
105 SCM entry = scm_car (s);
107 if (scm_is_pair (entry)
108 && !scm_is_symbol (scm_car (entry)))
110 Stencil sub = make_substencil (me, common, entry,
111 scm_is_pair (depth_styles)
112 ? scm_cdr (depth_styles) : SCM_EOL,
114 sub.translate_axis (left_x, X_AXIS);
115 total.add_stencil (sub);
122 MAKE_SCHEME_CALLBACK (Nested_system_start_delimiter, print, 1);
124 Nested_system_start_delimiter::print (SCM smob)
126 Spanner *me = unsmob_spanner (smob);
130 SCM hierarchy = me->get_object ("staff-hierarchy");
131 Link_array<Grob> elts = flatten_hierarchy (hierarchy);
132 Grob *common = common_refpoint_of_array (elts, me, Y_AXIS);
134 SCM default_style = me->get_property ("style");
135 if (!scm_is_symbol (default_style))
136 default_style = ly_symbol2scm ("line-bracket");
138 Stencil total = make_substencil (me, common, hierarchy, me->get_property ("styles"),
140 total.translate_axis (- me->relative_coordinate (common, Y_AXIS), Y_AXIS);
142 return total.smobbed_copy ();
146 ADD_INTERFACE (Nested_system_start_delimiter,
147 "nested-system-start-delimiter-interface",
149 "The brace, bracket or bar in front of the system. By setting "
150 "@code{staff-hierarchy}, eg. to @code{(a (b d) c)}, nesting for staff "
151 "braces can be produced."