]> git.donarmstrong.com Git - lilypond.git/blob - lily/rest.cc
Nitpick run.
[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--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "rest.hh"
10
11 #include "stencil.hh"
12 #include "output-def.hh"
13 #include "font-interface.hh"
14 #include "dots.hh"
15 #include "paper-score.hh"
16 #include "staff-symbol-referencer.hh"
17 #include "directional-element-interface.hh"
18
19 // -> offset callback
20 MAKE_SCHEME_CALLBACK (Rest, after_line_breaking, 1);
21 SCM
22 Rest::after_line_breaking (SCM smob)
23 {
24   Grob *me = unsmob_grob (smob);
25   int bt = scm_to_int (me->get_property ("duration-log"));
26   int lc = Staff_symbol_referencer::line_count (me);
27   Real ss = Staff_symbol_referencer::staff_space (me);
28   if (lc % 2)
29     {
30       if (bt == 0 && lc > 1)
31         me->translate_axis (ss, Y_AXIS);
32     }
33   else
34     me->translate_axis (ss / 2, Y_AXIS);
35
36   Grob *d = unsmob_grob (me->get_object ("dot"));
37   if (d && bt > 4) // UGH.
38     {
39       d->set_property ("staff-position",
40                        scm_from_int ((bt == 7) ? 4 : 3));
41     }
42   if (d && bt >= -1 && bt <= 1) // UGH again.
43     {
44       d->set_property ("staff-position",
45                        scm_from_int ((bt == 0) ? -1 : 1));
46     }
47   return SCM_UNSPECIFIED;
48 }
49
50 /*
51   make this function easily usable in C++
52 */
53 String
54 Rest::glyph_name (Grob *me, int balltype, String style, bool try_ledgers)
55 {
56   bool ledgered_b = false;
57   if (try_ledgers && (balltype == 0 || balltype == 1))
58     {
59       Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
60       Real pos = Staff_symbol_referencer::get_position (me);
61
62       /*
63         Figure out when the rest is far enough outside the staff. This
64         could bemore generic, but hey, we understand this even after
65         dinner.
66       */
67       ledgered_b |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
68       ledgered_b |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
69     }
70
71   String actual_style (style.to_str0 ());
72
73   if ((style == "mensural") || (style == "neomensural"))
74     {
75
76       /*
77         FIXME: Currently, ancient font does not provide ledgered rests;
78         hence the "o" suffix in the glyph name is bogus.  But do we need
79         ledgered rests at all now that we can draw ledger lines with
80         variable width, length and blotdiameter? -- jr
81       */
82       ledgered_b = 0;
83
84       /*
85         There are no 32th/64th/128th mensural/neomensural rests.  In
86         these cases, revert back to default style.
87       */
88       if (balltype > 4)
89         actual_style = "";
90     }
91
92   if ((style == "classical") && (balltype != 2))
93     {
94       /*
95         classical style: revert back to default style for any rest other
96         than quarter rest
97       */
98       actual_style = "";
99     }
100
101   if (style == "default")
102     {
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" : "")
111           + actual_style);
112 }
113
114 MAKE_SCHEME_CALLBACK (Rest, print, 1);
115
116 SCM
117 Rest::brew_internal_stencil (SCM smob, bool ledgered)
118 {
119   Grob *me = unsmob_grob (smob);
120
121   SCM balltype_scm = me->get_property ("duration-log");
122   if (!scm_is_number (balltype_scm))
123     return Stencil ().smobbed_copy ();
124
125   int balltype = scm_to_int (balltype_scm);
126
127   String style;
128   SCM style_scm = me->get_property ("style");
129   if (scm_is_symbol (style_scm))
130     style = ly_scm2string (scm_symbol_to_string (style_scm));
131
132   Font_metric *fm = Font_interface::get_default_font (me);
133   String font_char = glyph_name (me, balltype, style, ledgered);
134   Stencil out = fm->find_by_name (font_char);
135   if (out.is_empty ())
136     me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
137
138   return out.smobbed_copy ();
139 }
140
141 SCM
142 Rest::print (SCM smob)
143 {
144   return brew_internal_stencil (smob, true);
145 }
146
147 MAKE_SCHEME_CALLBACK (Rest, extent_callback, 2);
148 /*
149   We need the callback. The real stencil has ledgers depending on
150   Y-position. The Y-position is known only after line breaking.  */
151 SCM
152 Rest::extent_callback (SCM smob, SCM ax)
153 {
154   Axis a = (Axis) scm_to_int (ax);
155
156   /*
157     Don't want ledgers: ledgers depend on Y position, which depends on
158     rest collision, which depends on stem size which depends on beam
159     slop of opposite note column.
160
161     consequence: we get too small extents and potential collisions
162     with ledgered rests.
163   */
164   SCM m = brew_internal_stencil (smob, a != X_AXIS);
165   return ly_interval2scm (unsmob_stencil (m)->extent (a));
166 }
167
168 MAKE_SCHEME_CALLBACK (Rest, polyphonic_offset_callback, 2);
169 SCM
170 Rest::polyphonic_offset_callback (SCM smob, SCM)
171 {
172   Grob *me = unsmob_grob (smob);
173   if (scm_is_number (me->get_property ("staff-position")))
174     return scm_from_double (0);
175
176   Direction d = get_grob_direction (me);
177   Real off = 2 * d;
178   if (off)
179     off *= Staff_symbol_referencer::staff_space (me);
180
181   return scm_from_double (off);
182 }
183
184 ADD_INTERFACE (Rest, "rest-interface",
185                "A rest symbol.",
186                "style direction minimum-distance");
187