]> git.donarmstrong.com Git - lilypond.git/blob - lily/breathing-sign.cc
f8d02996f49a564f90d1d2e3bff3a4870239b689
[lilypond.git] / lily / breathing-sign.cc
1 /*
2   breathing_sign.cc -- implement Breathing_sign
3
4   (c) 1999--2006 Michael Krause
5
6   written for the GNU LilyPond music typesetter
7
8   TODO: --> see breathing-sign-engraver.cc
9
10   Extensions for ancient notation (c) 2003--2006 by Juergen Reuter
11 */
12
13 #include "breathing-sign.hh"
14
15 #include "staff-symbol-referencer.hh"
16 #include "directional-element-interface.hh"
17 #include "output-def.hh"
18 #include "lookup.hh"
19 #include "dimensions.hh"
20 #include "direction.hh"
21 #include "text-interface.hh"
22 #include "font-interface.hh"
23
24 /*
25   TODO: thickness should be a grob property (unit: linethickness)
26   rather than hardwired to (staff_space / 6).
27 */
28
29 /*
30   UGH : this is full of C&P code. Consolidate!  --hwn
31 */
32
33 /*
34   Gregorian chant divisio minima.  (Actually, this was the original
35   breathing sign by Michael. -- jr)
36 */
37 MAKE_SCHEME_CALLBACK (Breathing_sign, divisio_minima, 1);
38 SCM
39 Breathing_sign::divisio_minima (SCM smob)
40 {
41   Grob *me = unsmob_grob (smob);
42   Real staff_space = Staff_symbol_referencer::staff_space (me);
43   Real staff_size;
44
45   Real thickness = Staff_symbol_referencer::line_thickness (me);
46   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
47   if (Staff_symbol_referencer::get_staff_symbol (me))
48     staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
49   else
50     staff_size = 0.0;
51
52   Real blotdiameter = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
53
54   /*
55    * Draw a small vertical line through the uppermost (or, depending
56    * on direction, lowermost) staff line.
57    */
58   Interval xdim (0, thickness);
59   Interval ydim (-0.5 * staff_space, +0.5 * staff_space);
60   Box b (xdim, ydim);
61   Stencil out = Lookup::round_filled_box (b, blotdiameter);
62   return out.smobbed_copy ();
63 }
64
65 /*
66   Gregorian chant divisio maior.
67 */
68 MAKE_SCHEME_CALLBACK (Breathing_sign, divisio_maior, 1);
69 SCM
70 Breathing_sign::divisio_maior (SCM smob)
71 {
72   Grob *me = unsmob_grob (smob);
73   Real staff_space = Staff_symbol_referencer::staff_space (me);
74   Real staff_size;
75   Real thickness = Staff_symbol_referencer::line_thickness (me);
76   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
77
78   if (Staff_symbol_referencer::get_staff_symbol (me))
79     staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
80   else
81     staff_size = 0.0;
82
83   Real blotdiameter = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
84
85   /*
86    * Draw a vertical line that is vertically centered in the staff
87    * (just like a bar).  The height of this line should be a little
88    * more than half the size of the staff, such that the endings of
89    * the line are in the middle of a staff space.
90    */
91   int lines = Staff_symbol_referencer::line_count (me);
92   int height = lines / 2; // little more than half of staff size
93   if ((lines & 1) != (height & 1))
94     height++; // ensure endings are centered in staff space
95
96   Interval xdim (0, thickness);
97   Interval ydim (-0.5 * height, +0.5 * height);
98   Box b (xdim, ydim);
99   Stencil out = Lookup::round_filled_box (b, blotdiameter);
100   return out.smobbed_copy ();
101 }
102
103 /*
104   Gregorian chant divisio maxima.
105 */
106 MAKE_SCHEME_CALLBACK (Breathing_sign, divisio_maxima, 1);
107 SCM
108 Breathing_sign::divisio_maxima (SCM smob)
109 {
110   Grob *me = unsmob_grob (smob);
111   Real staff_space = Staff_symbol_referencer::staff_space (me);
112   Real staff_size;
113   Real thickness = Staff_symbol_referencer::line_thickness (me);
114   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
115
116   if (Staff_symbol_referencer::get_staff_symbol (me))
117     staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
118   else
119     staff_size = 0.0;
120
121   Real blotdiameter = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
122
123   // like a "|" type bar
124   Interval xdim (0, thickness);
125   Interval ydim (-0.5 * staff_size, +0.5 * staff_size);
126   Box b (xdim, ydim);
127   Stencil out = Lookup::round_filled_box (b, blotdiameter);
128   return out.smobbed_copy ();
129 }
130
131 /*
132   Gregorian chant finalis.
133 */
134 MAKE_SCHEME_CALLBACK (Breathing_sign, finalis, 1);
135 SCM
136 Breathing_sign::finalis (SCM smob)
137 {
138   Grob *me = unsmob_grob (smob);
139   Real staff_space = Staff_symbol_referencer::staff_space (me);
140   Real staff_size;
141   Real thickness = Staff_symbol_referencer::line_thickness (me);
142   thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
143
144   if (Staff_symbol_referencer::get_staff_symbol (me))
145     staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space;
146   else
147     staff_size = 0.0;
148
149   Real blotdiameter = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
150
151   // like a "||" type bar
152   Interval xdim (0, thickness);
153   Interval ydim (-0.5 * staff_size, +0.5 * staff_size);
154   Box b (xdim, ydim);
155   Stencil line1 = Lookup::round_filled_box (b, blotdiameter);
156   Stencil line2 (line1);
157   line2.translate_axis (0.5 * staff_space, X_AXIS);
158   line1.add_stencil (line2);
159
160   return line1.smobbed_copy ();
161 }
162
163 MAKE_SCHEME_CALLBACK (Breathing_sign, offset_callback, 1);
164 SCM
165 Breathing_sign::offset_callback (SCM smob)
166 {
167   Grob *me = unsmob_grob (smob);
168
169   Direction d = get_grob_direction (me);
170   if (!d)
171     {
172       d = UP;
173       set_grob_direction (me, d);
174     }
175
176   Real inter = Staff_symbol_referencer::staff_space (me) / 2;
177   int sz = Staff_symbol_referencer::line_count (me) - 1;
178   return scm_from_double (inter * sz * d);
179 }
180
181 ADD_INTERFACE (Breathing_sign, "breathing-sign-interface",
182                "A breathing sign.",
183                
184                "direction "
185
186                );