]> git.donarmstrong.com Git - lilypond.git/blob - lily/figured-bass-continuation.cc
(AncientRemoveEmptyStaffContext): switch on
[lilypond.git] / lily / figured-bass-continuation.cc
1 /*
2   figured-bass-continuation.cc -- implement Figured_bass_continuation
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
7
8 */
9
10 #include "line-interface.hh"
11 #include "lily-guile.hh"
12 #include "spanner.hh"
13 #include "output-def.hh"
14 #include "item.hh"
15 #include "stencil.hh"
16 #include "pointer-group-interface.hh"
17 #include "axis-group-interface.hh"
18
19
20 #include "horizontal-bracket.hh"
21
22 struct Figured_bass_bracket
23 {
24   static bool has_interface (Grob*);
25   
26 public:
27   DECLARE_SCHEME_CALLBACK(print, (SCM));
28 };
29
30
31 ADD_INTERFACE(Figured_bass_bracket,
32               "figured-bass-bracket-interface",
33               "Brackets alongside bass figures.",
34               
35               /* props */
36
37               /* ugh: should make bracket interface. */
38               "bracket-flare "
39               "shorten-pair "
40               "edge-height "
41               "padding "
42               "thickness "
43               "elements "
44               );
45
46 MAKE_SCHEME_CALLBACK (Figured_bass_bracket, print, 1);
47 SCM
48 Figured_bass_bracket::print (SCM grob)
49 {
50   Grob *me = unsmob_grob (grob);
51   extract_grob_set (me, "elements", elements);
52   if (elements.is_empty ())
53     {
54       me->suicide ();
55       return SCM_EOL;
56     }
57
58   Grob *common_x = common_refpoint_of_array (elements, me, X_AXIS); 
59   Interval xext = Axis_group_interface::relative_group_extent (elements, common_x, X_AXIS);
60   
61   Stencil left_br = Horizontal_bracket::make_bracket (me, me, elements,
62                                                       Y_AXIS, LEFT);
63   Stencil right_br = Horizontal_bracket::make_bracket (me, me, elements,
64                                                        Y_AXIS, RIGHT);
65
66   xext.widen (robust_scm2double (me->get_property ("padding"), 0.25));
67   left_br.translate_axis (xext[LEFT], X_AXIS);
68   right_br.translate_axis (xext[RIGHT], X_AXIS);
69
70   left_br.add_stencil (right_br);
71   left_br.translate_axis (-me->relative_coordinate (common_x, X_AXIS), X_AXIS);
72   return left_br.smobbed_copy ();
73 }
74
75
76 struct Figured_bass_continuation
77 {
78   static bool has_interface (Grob*);
79   
80 public:
81   DECLARE_SCHEME_CALLBACK(print, (SCM));
82   DECLARE_SCHEME_CALLBACK(center_on_figures, (SCM, SCM));
83 };
84
85 MAKE_SCHEME_CALLBACK (Figured_bass_continuation, center_on_figures, 2);
86 SCM
87 Figured_bass_continuation::center_on_figures (SCM grob, SCM axis)
88 {
89   Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (grob));
90   (void) axis;
91   
92   extract_grob_set (me, "figures", figures);
93   Grob *common = common_refpoint_of_array (figures, me, Y_AXIS);
94
95   Interval ext = Axis_group_interface::relative_group_extent (figures, common, Y_AXIS);
96   
97   return scm_from_double (ext.center () - me->relative_coordinate (common, Y_AXIS));
98 }
99
100 MAKE_SCHEME_CALLBACK (Figured_bass_continuation, print, 1);
101 SCM
102 Figured_bass_continuation::print (SCM grob)
103 {
104   Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (grob));
105
106   Real thick =
107     me->get_layout ()->get_dimension (ly_symbol2scm ("linethickness"))
108     * robust_scm2double (me->get_property ("thickness"), 1);
109   
110   Interval spanned;
111   Direction d = LEFT;
112   Grob *common = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT),
113                                                         X_AXIS);
114   do
115     {
116       spanned[d] 
117         = robust_relative_extent (me->get_bound (d), common, X_AXIS)[RIGHT]
118         - me->relative_coordinate (common, X_AXIS);
119     }
120   while (flip (&d) !=  LEFT);
121   spanned.widen (- robust_scm2double (me->get_property ("padding"), 0.2));
122   
123   Stencil extender;
124   if (!spanned.is_empty ())
125     extender = Line_interface::make_line (thick,
126                                           Offset (spanned[LEFT], 0),
127                                           Offset (spanned[RIGHT], 0));
128   
129   return extender.smobbed_copy ();
130 }
131
132 ADD_INTERFACE(Figured_bass_continuation,
133               "figured-bass-continuation-interface",
134               "Simple extender line between bounds.",
135               
136               /* props */
137               "thickness "
138               "padding "
139               "figures "
140               );
141