]> git.donarmstrong.com Git - lilypond.git/blob - lily/bar.cc
release: 1.3.33
[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   SCM at = gh_list (ly_symbol2scm ("bracket"),
58                     gh_double2scm (p->get_var("bracket_arch_angle")),
59                     gh_double2scm (p->get_var("bracket_arch_width")),
60                     gh_double2scm (p->get_var("bracket_arch_height")),
61                     gh_double2scm (p->get_var("bracket_width")),
62                     gh_double2scm (height),
63                     gh_double2scm (p->get_var("bracket_arch_thick")),
64                     gh_double2scm (p->get_var("bracket_thick")),
65                     SCM_UNDEFINED);
66
67   Real staff_space = p->get_var ("interline");
68   Box b (Interval (0, 1.5 * staff_space), Interval (-height/2,height/2));
69   Molecule mol (b, at);
70   
71   mol.translate_axis (- mol.dim_[X_AXIS].length () / 2, X_AXIS);
72   return mol;
73 }
74
75 Molecule
76 Bar::compound_barline (String str, Real h) const
77 {
78   Real kern = paper_l()->get_var ("bar_kern");
79   Real thinkern = paper_l()->get_var ("bar_thinkern");
80
81   Molecule thin = simple_barline (paper_l()->get_var ("barthick_thin"), h);
82   Molecule thick = simple_barline (paper_l()->get_var ("barthick_thick"), h);
83   Molecule colon = lookup_l ()->afm_find ("dots-repeatcolon");  
84
85   Molecule m;
86   
87   if (str == "")
88     {
89       return lookup_l ()->blank (Box (Interval(0, 0), Interval (-h/2, h/2)));
90     }
91   if (str == "scorepostbreak")
92     {
93       return simple_barline (paper_l ()->get_var ("barthick_score"), h);
94     }
95   else if (str == "|")
96     {
97       return thin;
98     }
99   else if (str == "|.")
100     {
101       m.add_at_edge (X_AXIS, LEFT, thick, 0);      
102       m.add_at_edge (X_AXIS, LEFT, thin, kern);
103     }
104   else if (str == ".|")
105     {
106       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
107       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
108     }
109   else if (str == ":|")
110     {
111       m.add_at_edge (X_AXIS, LEFT, thick, 0);
112       m.add_at_edge (X_AXIS, LEFT, thin, kern);
113       m.add_at_edge (X_AXIS, LEFT, colon, kern);      
114     }
115   else if (str == "|:")
116     {
117       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
118       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
119       m.add_at_edge (X_AXIS, RIGHT, colon, kern);      
120     }
121   else if (str == ":|:")
122     {
123       m.add_at_edge (X_AXIS, LEFT, thick, thinkern);
124       m.add_at_edge (X_AXIS, LEFT, colon, kern);      
125       m.add_at_edge (X_AXIS, RIGHT, thick, kern);
126       m.add_at_edge (X_AXIS, RIGHT, colon, kern);      
127     }
128   else if (str == ".|.")
129     {
130       m.add_at_edge (X_AXIS, LEFT, thick, thinkern);
131       m.add_at_edge (X_AXIS, RIGHT, thick, kern);      
132     }
133   else if (str == "||")
134     {
135       m.add_at_edge (X_AXIS, RIGHT, thin, 0);
136       m.add_at_edge (X_AXIS, RIGHT, thin, thinkern);      
137     }
138
139   return m;
140 }
141
142 /*
143   ugh. Suck me plenty.
144  */
145 Molecule
146 Bar::staff_brace (Real y)  const
147 {
148   Real staffht  = paper_l ()->get_var ("staffheight");
149   int staff_size  = int (rint (staffht ));
150
151   // URG
152   Real step  = 1.0;
153   int minht  = 2 * staff_size;
154   int maxht = 7 *  minht;
155   int idx = int (((maxht - step) <? y - minht) / step);
156   idx = idx >? 0;
157
158   SCM l = ly_eval_str ("(style-to-cmr \"brace\")");
159   String nm = "feta-braces";
160   if (l != SCM_BOOL_F)
161     nm = ly_scm2string (gh_cdr (l));
162   nm += to_str (staff_size);
163   SCM e =gh_list (ly_symbol2scm ("char"), gh_int2scm (idx), SCM_UNDEFINED);
164   SCM at = (e);
165
166   at = fontify_atom (all_fonts_global_p->find_font (nm), at);
167   
168   Box b ( Interval (-y/2,y/2),
169            Interval (0,0));
170   return Molecule(b, at);
171 }
172   
173
174 Molecule
175 Bar::simple_barline (Real w, Real h) const
176 {
177   return lookup_l ()->filledbox (Box (Interval(0,w), Interval(-h/2, h/2)));
178 }
179
180
181 void
182 Bar::before_line_breaking ()
183 {
184   SCM g = get_elt_property ("glyph");
185   Direction bsd = break_status_dir ();
186   if (gh_string_p (g))
187     {
188       if (bsd)
189         {
190           SCM breakdir = gh_int2scm (bsd);
191           g = scm_eval (gh_list (ly_symbol2scm ("break-barline"),
192                                  g,
193                                  breakdir,
194                                  SCM_UNDEFINED));
195         }
196     }
197   else
198     {
199       g = SCM_UNDEFINED;
200     }
201   
202   if (!gh_string_p (g))
203     {
204       set_elt_property ("transparent", SCM_BOOL_T);
205       set_empty (X_AXIS);      
206     }
207   else
208     set_elt_property ("glyph", g);
209 }
210   
211