]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest.cc
0a1b7be668c95ae49632c53c1a4b967d22dd8d97
[lilypond.git] / lily / rest.cc
1 /*
2  rest.cc -- implement Rest
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "molecule.hh"
10 #include "paper-def.hh"
11 #include "font-interface.hh"
12 #include "rest.hh"
13 #include "dots.hh"
14 #include "paper-score.hh"
15 #include "staff-symbol-referencer.hh"
16
17 // -> offset callback
18 MAKE_SCHEME_CALLBACK (Rest,after_line_breaking,1);
19 SCM
20 Rest::after_line_breaking (SCM smob)
21 {
22   Grob *me = unsmob_grob (smob);
23   int bt = gh_scm2int (me->get_grob_property ("duration-log"));
24   int lc = Staff_symbol_referencer::line_count (me);
25   Real ss = Staff_symbol_referencer::staff_space (me);
26   if(lc % 2)
27     {
28       if (bt == 0 && lc > 1)
29         {
30           me->translate_axis (ss , Y_AXIS);
31         }
32     }
33   else
34     {
35       me->translate_axis (ss/2 , Y_AXIS);
36     }
37
38   Grob * d = unsmob_grob (me->get_grob_property ("dot"));
39   if (d && bt > 4) // UGH.
40     {
41       d->set_grob_property ("staff-position",
42                             gh_int2scm ((bt == 7) ? 4 : 3));
43     }
44   if (d && bt >= -1 && bt <= 1) // UGH again.
45     {
46       d->set_grob_property ("staff-position",
47                             gh_int2scm ((bt == 0) ? -1 : 1));
48     }
49   return SCM_UNSPECIFIED;
50 }
51
52 /*
53   make this function easily usable in C++
54  */
55 String
56 Rest::glyph_name (Grob *me, int balltype, String style)
57 {
58   bool ledgered_b = false;
59
60   if (balltype == 0 || balltype == 1)
61     {
62       Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
63       Real pos = Staff_symbol_referencer::get_position (me);
64
65       /*
66         Figure out when the rest is far enough outside the staff. This
67         could bemore generic, but hey, we understand this even after
68         dinner.
69        */
70       ledgered_b |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
71       ledgered_b |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
72     }
73
74   String actual_style (style.to_str0 ());
75
76   if ((style == "mensural") || (style == "neo_mensural")) {
77
78     /*
79       FIXME: Currently, ancient font does not provide ledgered rests;
80       hence the "o" suffix in the glyph name is bogus.  But do we need
81       ledgered rests at all now that we can draw ledger lines with
82       variable width, length and blotdiameter? -- jr
83     */
84     ledgered_b = 0;
85
86     /*
87       There are no 32th/64th/128th mensural/neo_mensural rests.  In
88       these cases, revert back to default style.
89     */
90     if (balltype > 4)
91       actual_style = "";
92   }
93
94   if ((style == "classical") && (balltype != 2)) {
95     /*
96       classical style: revert back to default style for any rest other
97       than quarter rest
98     */
99     actual_style = "";
100   }
101
102   if (style == "default") {
103     /*
104       Some parts of lily still prefer style "default" over "".
105       Correct this here. -- jr
106     */
107     actual_style = "";
108   }
109
110   return ("rests-") + to_string (balltype) + (ledgered_b ? "o" : "") + actual_style;
111 }
112
113
114 MAKE_SCHEME_CALLBACK (Rest,brew_molecule,1);
115
116 SCM
117 Rest::brew_internal_molecule (SCM smob)
118 {
119   Grob* me = unsmob_grob (smob);
120
121   SCM balltype_scm = me->get_grob_property ("duration-log");
122   if (!gh_number_p (balltype_scm))
123     return Molecule ().smobbed_copy ();
124
125   int balltype = gh_scm2int (balltype_scm);
126   
127   String style; 
128   SCM style_scm = me->get_grob_property ("style");
129   if (gh_symbol_p (style_scm))
130     {
131       style = ly_scm2string (scm_symbol_to_string (style_scm));
132     }
133
134   Font_metric *fm = Font_interface::get_default_font (me);
135   String font_char = glyph_name (me, balltype, style);
136   Molecule out = fm->find_by_name (font_char);
137   if (out.is_empty ())
138     {
139       me->warning (_f ("rest `%s' not found, ", font_char.to_str0 ()));
140     }
141
142   return out.smobbed_copy();
143 }
144
145 SCM 
146 Rest::brew_molecule (SCM smob) 
147 {
148   return brew_internal_molecule (smob);
149 }
150 MAKE_SCHEME_CALLBACK (Rest,extent_callback,2);
151 /*
152   We need the callback. The real molecule has ledgers depending on
153   Y-position. The Y-position is known only after line breaking.  */
154 SCM
155 Rest::extent_callback (SCM smob, SCM ax)
156 {
157   Axis a = (Axis) gh_scm2int (ax);
158   SCM m = brew_internal_molecule (smob);
159   return ly_interval2scm (unsmob_molecule (m)->extent (a));
160 }
161
162
163
164 ADD_INTERFACE (Rest,"rest-interface",
165   "a rest",
166   "style minimum-distance");
167