]> git.donarmstrong.com Git - lilypond.git/blob - lily/span-bar.cc
patch::: 1.3.93.jcn2
[lilypond.git] / lily / span-bar.cc
1 /*
2   span-bar.cc -- implement Span_bar
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "span-bar.hh"
10 #include "lookup.hh"
11 #include "dimensions.hh"
12 #include "paper-def.hh"
13 #include "molecule.hh"
14 #include "warn.hh"
15 #include "axis-group-interface.hh"
16 #include "group-interface.hh"
17 #include "score-element.hh"
18 #include "bar.hh"
19
20 void
21 Span_bar::add_bar (Score_element*me, Score_element*b)
22 {
23   Pointer_group_interface gi (me);
24   gi.add_element (b);
25
26   me->add_dependency (b);
27 }
28
29 Interval
30 Span_bar::width_callback (Score_element *se, Axis )
31 {
32   String gl = ly_scm2string (se->get_elt_property ("glyph"));
33
34   /*
35     urg.
36    */
37   Molecule m = Bar::compound_barline (se, gl, 40 PT);
38   
39   return m.extent (X_AXIS);
40 }
41
42 MAKE_SCHEME_CALLBACK(Span_bar,before_line_breaking,1);
43 SCM
44 Span_bar::before_line_breaking (SCM smob)
45 {
46   evaluate_empty (unsmob_element (smob));
47   evaluate_glyph (unsmob_element (smob));
48
49   /*
50     no need to call   Bar::before_line_breaking (), because the info
51     in ELEMENTS already has been procced by Bar::before_line_breaking().
52    */
53   return SCM_UNSPECIFIED;
54 }
55
56 MAKE_SCHEME_CALLBACK(Span_bar,center_on_spanned_callback,2);
57 SCM
58 Span_bar::center_on_spanned_callback (SCM element_smob, SCM axis)
59 {
60   Score_element *me = unsmob_element (element_smob);
61   Axis a = (Axis) gh_scm2int (axis);
62   assert (a == Y_AXIS);
63   Interval i (get_spanned_interval (me));
64
65   /*
66     Bar::brew_molecule delivers a barline of y-extent (-h/2,h/2), so
67     we have to translate ourselves to be in the center of the 
68     interval that we span.  */
69
70   return gh_double2scm (i.center ());
71 }
72
73 void
74 Span_bar::evaluate_empty (Score_element*me)
75 {
76   /*
77     TODO: filter all hara-kiried out of ELEMENS list, and then
78     optionally do suicide. Call this cleanage function from
79     center_on_spanned_callback() as well.
80     
81    */
82   if (!gh_pair_p (me->get_elt_property ("elements")))
83     {
84       me->suicide ();
85     }
86 }
87
88 void
89 Span_bar::evaluate_glyph (Score_element*me)
90 {
91   SCM elts = me->get_elt_property ("elements");
92   Score_element * b = unsmob_element (gh_car (elts));
93   SCM glsym =ly_symbol2scm ("glyph");
94   SCM gl =b ->get_elt_property (glsym);
95   if (!gh_string_p (gl))
96     {
97       me->suicide ();
98       return ; 
99     }
100
101   String type = ly_scm2string (gl);
102   
103   if (type == "|:") 
104     {
105       type = ".|";
106     }
107   else if (type== ":|")
108     {
109       type = "|.";
110     }
111   else if (type== ":|:")
112     {
113       type = ".|.";
114     }
115
116   gl = ly_str02scm (type.ch_C());
117   if (scm_equal_p (me->get_elt_property (glsym), gl) != SCM_BOOL_T)
118     me->set_elt_property (glsym, gl);
119 }
120
121 Interval
122 Span_bar::get_spanned_interval (Score_element*me) 
123 {
124   return Axis_group_interface::group_extent_callback (me, Y_AXIS);  
125 }
126
127
128 MAKE_SCHEME_CALLBACK(Span_bar,get_bar_size,1);
129 SCM
130 Span_bar::get_bar_size (SCM smob)
131 {
132   Score_element* me =  unsmob_element (smob);
133   Interval iv (get_spanned_interval (me));
134   if (iv.empty_b ())
135     {
136       /*
137         This happens if the bars are hara-kiried from under us.
138        */
139       me->suicide ();
140       return gh_double2scm (-1);
141     }
142   return gh_double2scm (iv.length ());
143 }
144
145 void
146 Span_bar::set_interface (Score_element *me)
147 {
148   Bar::set_interface (me);
149   
150   Pointer_group_interface(me).set_interface ();
151   me->set_extent_callback (width_callback, X_AXIS);
152   me->add_offset_callback (Span_bar_center_on_spanned_callback_proc, Y_AXIS);
153   me->set_interface (ly_symbol2scm ("span-bar-interface"));
154   me->set_extent_callback (0, Y_AXIS);
155 }
156
157 bool
158 Span_bar::has_interface (Score_element*m)
159 {
160   return m && m->has_interface (ly_symbol2scm ("span-bar-interface"));
161 }