]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest.cc
* VERSION (MY_PATCH_LEVEL): make 1.7.0
[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--2002 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
45   return SCM_UNSPECIFIED;
46 }
47
48 /*
49   make this function easily usable in C++
50  */
51 String
52 Rest::glyph_name (Grob *me, int balltype, String style)
53 {
54   bool ledgered_b = false;
55
56   if (balltype == 0 || balltype == 1)
57     {
58       Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
59       Real pos = Staff_symbol_referencer::get_position (me);
60
61       /*
62         Figure out when the rest is far enough outside the staff. This
63         could bemore generic, but hey, we understand this even after
64         dinner.
65        */
66       ledgered_b |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
67       ledgered_b |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
68     }
69
70   String actual_style (style.to_str0 ());
71
72   if ((style == "mensural") || (style == "neo_mensural")) {
73
74     /*
75       FIXME: Currently, ancient font does not provide ledgered rests;
76       hence the "o" suffix in the glyph name is bogus.  But do we need
77       ledgered rests at all now that we can draw ledger lines with
78       variable width, length and blotdiameter? -- jr
79     */
80     ledgered_b = 0;
81
82     /*
83       There are no 32th/64th/128th mensural/neo_mensural rests.  In
84       these cases, revert back to default style.
85     */
86     if (balltype > 4)
87       actual_style = "";
88   }
89
90   if ((style == "classical") && (balltype != 2)) {
91     /*
92       classical style: revert back to default style for any rest other
93       than quarter rest
94     */
95     actual_style = "";
96   }
97
98   if (style == "default") {
99     /*
100       Some parts of lily still prefer style "default" over "".
101       Correct this here. -- jr
102     */
103     actual_style = "";
104   }
105
106   return ("rests-") + to_string (balltype) + (ledgered_b ? "o" : "") + actual_style;
107 }
108
109
110 MAKE_SCHEME_CALLBACK (Rest,brew_molecule,1);
111
112 SCM
113 Rest::brew_internal_molecule (SCM smob)
114 {
115   Grob* me = unsmob_grob (smob);
116
117   SCM balltype_scm = me->get_grob_property ("duration-log");
118   if (!gh_number_p (balltype_scm))
119     return Molecule ().smobbed_copy ();
120
121   int balltype = gh_scm2int (balltype_scm);
122   
123   String style; 
124   SCM style_scm = me->get_grob_property ("style");
125   if (gh_symbol_p (style_scm))
126     {
127       style = ly_scm2string (scm_symbol_to_string (style_scm));
128     }
129
130   Font_metric *fm = Font_interface::get_default_font (me);
131   String font_char = glyph_name (me, balltype, style);
132   Molecule out = fm->find_by_name (font_char);
133   if (out.empty_b())
134     {
135       me->warning (_f ("rest `%s' not found, ", font_char.to_str0 ()));
136     }
137
138   return out.smobbed_copy();
139 }
140
141 SCM 
142 Rest::brew_molecule (SCM smob) 
143 {
144   return brew_internal_molecule (smob);
145 }
146 MAKE_SCHEME_CALLBACK (Rest,extent_callback,2);
147 /*
148   We need the callback. The real molecule has ledgers depending on
149   Y-position. The Y-position is known only after line breaking.  */
150 SCM
151 Rest::extent_callback (SCM smob, SCM ax)
152 {
153   Axis a = (Axis) gh_scm2int (ax);
154   SCM m = brew_internal_molecule (smob);
155   return ly_interval2scm (unsmob_molecule (m)->extent (a));
156 }
157
158
159
160 ADD_INTERFACE (Rest,"rest-interface",
161   "a rest",
162   "style minimum-beam-collision-distance");
163