]> git.donarmstrong.com Git - lilypond.git/blob - lily/system-start-delimiter.cc
5ebe1920230bd258f6ada4118faf2d088fb643ee
[lilypond.git] / lily / system-start-delimiter.cc
1 /*   
2   system-start-delimiter.cc --  implement System_start_delimiter
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9 #include <math.h>
10
11 #include "axis-group-interface.hh"
12 #include "system-start-delimiter.hh"
13 #include "paper-def.hh"
14 #include "molecule.hh"
15 #include "font-interface.hh"
16 #include "all-font-metrics.hh"
17 #include "grob.hh"
18 #include "staff-symbol-referencer.hh"
19 #include "lookup.hh"
20
21 Molecule
22 System_start_delimiter::staff_bracket (Grob*me,Real height)  
23 {
24   Real arc_height = gh_scm2double (me->get_grob_property ("arch-height")) ;
25   
26   SCM at = gh_list (ly_symbol2scm ("bracket"),
27                     me->get_grob_property ("arch-angle"),
28                     me->get_grob_property ("arch-width"),
29                     gh_double2scm (arc_height),
30                     gh_double2scm (height),
31                     me->get_grob_property ("arch-thick"),
32                     me->get_grob_property ("bracket-thick"),
33                     SCM_UNDEFINED);
34
35   /*
36 TODO: sort this out.
37     
38 Another thing:
39 In system-start-delimiter.cc I see the line
40
41   Real h = height + 2 * arc_height;
42
43 But I really think that you mean
44
45  Real h = height + 2 * arc_width;
46
47 (arc_height changes the x-axis-size of arc ; arc_width changes the
48 y-axis-size)
49 Will not fix it since I'm not sure.
50
51 -Rune
52   
53    */
54   Real h = height + 2 * arc_height;
55   Box b (Interval (0, 1.5), Interval (-h/2, h/2));
56   Molecule mol (b, at);
57   mol.align_to (X_AXIS, CENTER);
58   return mol;
59 }
60
61 void
62 System_start_delimiter::set_interface (Grob*me)
63 {
64   me->set_interface (ly_symbol2scm ("system-start-delimiter-interface"));
65 }
66
67 bool
68 System_start_delimiter::has_interface (Grob*me)
69 {
70   return  me->has_interface (ly_symbol2scm ("system-start-delimiter-interface"));
71 }
72
73 Molecule
74 System_start_delimiter::simple_bar (Grob*me,Real h) 
75 {
76   Real w = me->paper_l ()->get_var ("stafflinethickness") *
77     gh_scm2double (me->get_grob_property ("thickness"));
78   return Lookup::filledbox (Box (Interval (0,w), Interval (-h/2, h/2)));
79 }
80
81 MAKE_SCHEME_CALLBACK (System_start_delimiter,after_line_breaking,1);
82
83 SCM
84 System_start_delimiter::after_line_breaking (SCM smob)
85 {
86   try_collapse (unsmob_grob (smob));
87   return SCM_UNSPECIFIED;
88 }
89
90 void
91 System_start_delimiter::try_collapse (Grob*me)
92 {
93   SCM   gl = me->get_grob_property ("glyph");
94   
95   if (scm_ilength (me->get_grob_property ("elements")) <=  1 && gl == ly_symbol2scm ("bar-line"))
96     {
97       me->suicide ();
98     }
99   
100 }
101
102
103 MAKE_SCHEME_CALLBACK (System_start_delimiter,brew_molecule,1);
104
105 SCM
106 System_start_delimiter::brew_molecule (SCM smob)
107 {
108   Grob * me = unsmob_grob (smob);
109
110   SCM s = me->get_grob_property ("glyph");
111   if (!gh_symbol_p (s))
112     return SCM_EOL;
113   
114   SCM c = me->get_grob_property ((ly_symbol2string (s) + "-collapse-height")
115                                  .ch_C ());
116   
117   Real staff_space = Staff_symbol_referencer::staff_space (me);
118   Interval ext = ly_scm2interval (Axis_group_interface::group_extent_callback
119  (me->self_scm (), gh_int2scm (Y_AXIS)));
120   Real l = ext.length () / staff_space;
121   
122   if (ext.empty_b ()
123       || (gh_number_p (c) && l <= gh_scm2double (c)))
124     {
125       me->suicide ();
126       return SCM_EOL;
127     }
128
129   Molecule m;
130   if (s == ly_symbol2scm ("bracket"))
131     m = staff_bracket (me,l);
132   else if (s == ly_symbol2scm ("brace"))
133     m =  staff_brace (me,l);
134   else if (s == ly_symbol2scm ("bar-line"))
135     m = simple_bar (me,l);
136   
137   m.translate_axis (ext.center (), Y_AXIS);
138   return m.smobbed_copy ();
139 }
140
141 Molecule
142 System_start_delimiter::staff_brace (Grob*me,Real y)  
143 {
144
145   /*
146     FIXME:
147     * should look at afm/tfm file for dimensions.
148      (This breaks ascii-art output: it hasn't got 255 symbols)
149     
150     * more glyphs (or maybe just better sized (fixed # of staff-spaces)),
151       the size mismatches with the staffs are very ugly
152          
153    */
154
155   // ugrhn
156   int lo = 0;
157   int hi = 255;
158   
159   Font_metric *fm = Font_interface::get_default_font (me);
160   Box b;
161
162   /* do a binary search for each Y, not very efficient, but passable?  */
163   do
164   {
165     int cmp = (lo + hi) / 2;
166
167     b = fm->get_char (cmp);
168     if (b[Y_AXIS].empty_b () || b[Y_AXIS].length () > y)
169       hi = cmp;
170     else
171       lo = cmp;
172     }
173   while (hi - lo > 1);
174
175   SCM at = gh_list (ly_symbol2scm ("char"), gh_int2scm (lo), SCM_UNDEFINED);
176   at = fontify_atom (fm, at);
177   
178   b = fm->get_char (lo);
179   b[X_AXIS] = Interval (0,0);
180
181   return Molecule (b, at);
182 }
183