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