]> git.donarmstrong.com Git - lilypond.git/blob - lily/bar.cc
bdb41250ff60bd371122f23165b44761988e840c
[lilypond.git] / lily / bar.cc
1 /*
2   bar.cc -- implement 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 #include <math.h>
9
10 #include "main.hh"
11 #include "dimensions.hh"
12 #include "dimension-cache.hh"
13 #include "bar.hh"
14 #include "string.hh"
15 #include "molecule.hh"
16 #include "paper-def.hh"
17 #include "lookup.hh"
18 #include "debug.hh"
19 #include "all-font-metrics.hh"
20
21 Bar::Bar ()
22 {
23   set_elt_property ("breakable", SCM_BOOL_T);
24 }
25
26
27 Real
28 Bar::get_bar_size () const
29 {
30   // Never called!
31   return 0;
32 }
33
34
35 Molecule 
36 Bar::do_brew_molecule () const
37 {
38   SCM s = get_elt_property ("glyph");
39   if (gh_string_p (s))
40     {
41       String str  =ly_scm2string (s);
42       if (str == "bracket")
43         return staff_bracket (get_bar_size ());
44       else if  (str == "brace")
45         return staff_brace (get_bar_size ());
46       else
47         return compound_barline (str, get_bar_size ());
48     }
49   return Molecule ();
50 }
51
52
53 Molecule
54 Bar::staff_bracket (Real height) const 
55 {
56   Paper_def* p= paper_l ();
57   Real arc_height = p->get_var("bracket_arch_height");
58   SCM at = gh_list (ly_symbol2scm ("bracket"),
59                     gh_double2scm (p->get_var("bracket_arch_angle")),
60                     gh_double2scm (p->get_var("bracket_arch_width")),
61                     gh_double2scm (arc_height),
62                     gh_double2scm (p->get_var("bracket_width")),
63                     gh_double2scm (height),
64                     gh_double2scm (p->get_var("bracket_arch_thick")),
65                     gh_double2scm (p->get_var("bracket_thick")),
66                     SCM_UNDEFINED);
67
68   Real staff_space = p->get_var ("interline");
69   Real h = height + 2 * arc_height;
70   Box b (Interval (0, 1.5 * staff_space), Interval (-h/2, h/2));
71   Molecule mol (b, at);
72   
73   mol.translate_axis (- mol.dim_[X_AXIS].length () / 2, X_AXIS);
74   return mol;
75 }
76
77 Molecule
78 Bar::compound_barline (String str, Real h) const
79 {
80   Real kern = paper_l()->get_var ("bar_kern");
81   Real thinkern = paper_l()->get_var ("bar_thinkern");
82
83   Molecule thin = simple_barline (paper_l()->get_var ("barthick_thin"), h);
84   Molecule thick = simple_barline (paper_l()->get_var ("barthick_thick"), h);
85   Molecule colon = lookup_l ()->afm_find ("dots-repeatcolon");  
86
87   Molecule m;
88   
89   if (str == "")
90     {
91       return lookup_l ()->blank (Box (Interval(0, 0), Interval (-h/2, h/2)));
92     }
93   if (str == "scorepostbreak")
94     {
95       return simple_barline (paper_l ()->get_var ("barthick_score"), h);
96     }
97   else if (str == "|")
98     {
99       return thin;
100     }
101   else if (str == "|.")
102     {
103       m.add_at_edge (X_AXIS, LEFT, thick, 0);      
104       m.add_at_edge (X_AXIS, LEFT, thin, kern);
105     }
106   else if (str == ".|")
107     {
108       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
109       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
110     }
111   else if (str == ":|")
112     {
113       m.add_at_edge (X_AXIS, LEFT, thick, 0);
114       m.add_at_edge (X_AXIS, LEFT, thin, kern);
115       m.add_at_edge (X_AXIS, LEFT, colon, kern);      
116     }
117   else if (str == "|:")
118     {
119       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
120       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
121       m.add_at_edge (X_AXIS, RIGHT, colon, kern);      
122     }
123   else if (str == ":|:")
124     {
125 //        m.add_at_edge (X_AXIS, LEFT, thick, thinkern);
126 //        m.add_at_edge (X_AXIS, LEFT, colon, kern);      
127 //        m.add_at_edge (X_AXIS, RIGHT, thick, kern);
128 //        m.add_at_edge (X_AXIS, RIGHT, colon, kern);      
129       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
130       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
131       m.add_at_edge (X_AXIS, RIGHT, colon, kern);      
132       m.add_at_edge (X_AXIS, LEFT, thin, kern);
133       m.add_at_edge (X_AXIS, LEFT, colon, kern);      
134     }
135   else if (str == ";|;")
136     {
137       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
138       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
139       m.add_at_edge (X_AXIS, LEFT, thin, kern);
140     }
141   else if (str == ".|.")
142     {
143       m.add_at_edge (X_AXIS, LEFT, thick, thinkern);
144       m.add_at_edge (X_AXIS, RIGHT, thick, kern);      
145     }
146   else if (str == "||")
147     {
148       m.add_at_edge (X_AXIS, RIGHT, thin, 0);
149       m.add_at_edge (X_AXIS, RIGHT, thin, thinkern);      
150     }
151
152   return m;
153 }
154
155 /*
156   ugh. Suck me plenty.
157  */
158 Molecule
159 Bar::staff_brace (Real y)  const
160 {
161   Real staffht  = paper_l ()->get_var ("staffheight");
162   int staff_size  = int (rint (staffht ));
163
164   // URG
165   Real step  = 1.0;
166   int minht  = 2 * staff_size;
167   int maxht = 7 *  minht;
168   int idx = int (((maxht - step) <? y - minht) / step);
169   idx = idx >? 0;
170
171   SCM l = scm_eval (gh_list (ly_symbol2scm ("style-to-cmr"),
172                             ly_str02scm ("brace"),
173                             SCM_UNDEFINED));
174   
175   String nm = "feta-braces";
176   if (l != SCM_BOOL_F)
177     nm = ly_scm2string (gh_cdr (l));
178   nm += to_str (staff_size);
179   SCM e =gh_list (ly_symbol2scm ("char"), gh_int2scm (idx), SCM_UNDEFINED);
180   SCM at = (e);
181
182   at = fontify_atom (all_fonts_global_p->find_font (nm), at);
183   
184   Box b (Interval (0,0), Interval (-y/2, y/2));
185
186   return Molecule(b, at);
187 }
188   
189
190 Molecule
191 Bar::simple_barline (Real w, Real h) const
192 {
193   return lookup_l ()->filledbox (Box (Interval(0,w), Interval(-h/2, h/2)));
194 }
195
196
197 void
198 Bar::before_line_breaking ()
199 {
200   SCM g = get_elt_property ("glyph");
201   Direction bsd = break_status_dir ();
202   if (gh_string_p (g))
203     {
204       if (bsd)
205         {
206           SCM breakdir = gh_int2scm (bsd);
207           g = scm_eval (gh_list (ly_symbol2scm ("break-barline"),
208                                  g,
209                                  breakdir,
210                                  SCM_UNDEFINED));
211         }
212     }
213   else
214     {
215       g = SCM_UNDEFINED;
216     }
217   
218   if (!gh_string_p (g))
219     {
220       set_elt_property ("transparent", SCM_BOOL_T);
221       set_empty (X_AXIS);      
222     }
223   else
224     set_elt_property ("glyph", g);
225 }
226   
227