]> git.donarmstrong.com Git - lilypond.git/blob - lily/tex-slur.cc
release: 0.1.7
[lilypond.git] / lily / tex-slur.cc
1 /*
2   tex-slur.cc -- implement Lookup::*slur
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1996,1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include <math.h>
10 #include "misc.hh"
11 #include "lookup.hh"
12 #include "molecule.hh"
13 #include "dimen.hh"
14 #include "debug.hh"
15 #include "paper-def.hh"
16
17
18
19 static
20 char direction_char(int y_sign)
21 {
22     char c='#';
23     switch(y_sign){
24     case -1:
25         c = 'd';
26         break;
27     case 0:
28         c = 'h';
29         break;
30     case 1:
31         c = 'u';
32         break;
33     default:
34         assert(false);
35     }
36     return c;
37 }
38
39 Symbol
40 Lookup::half_slur_middlepart(Real &dx, int dir) const
41 {
42     if (dx >= 400 PT) {// todo
43         WARN<<"halfslur too large" <<print_dimen(dx)<< "shrinking (ugh)\n";
44         dx = 400 PT;
45     }
46     int widx = int(floor(dx / 4.0));
47     dx = widx * 4.0;
48     if (widx) widx --;
49     else {
50         WARN <<  "slur too narrow\n";
51     }
52
53     Symbol s;
54     
55     s.dim.y() = Interval(min(0,0), max(0,0)); // todo
56     s.dim.x() = Interval(0,dx);
57
58     String f =  String("\\hslurchar");
59     f += direction_char(0);
60
61     int idx = widx;
62     if (dir < 0)
63         idx += 128;
64
65     assert (idx < 256);
66
67     f+=String( "{" ) + String( idx ) + "}";
68     s.tex = f;
69     Atom a(s);
70     a.translate(dx/2, X_AXIS);
71     s.tex = a.TeX_string();
72
73     return s;
74 }
75 Symbol
76 Lookup::half_slur(int dy, Real &dx, int dir, int xpart) const
77 {
78     Real orig_dx = dx;
79     if (!xpart)
80         return half_slur_middlepart(dx, dir);
81
82     int widx;
83                 
84     if (dx >= 96 PT) {
85         WARN << "Slur half too wide." << print_dimen(orig_dx) << " shrinking (ugh)\n";
86         dx =  96 PT;
87     }
88
89     widx = int(rint(dx/12.0));
90     dx = widx*12.0;
91     if (widx)
92         widx --;
93     else {
94         WARN <<  "slur too narrow " << print_dimen(orig_dx)<<"\n";
95     }
96         
97     Symbol s;
98     s.dim.x() = Interval(0,dx);
99     s.dim.y() = Interval(min(0,dy), max(0,dy));
100
101
102     String f = String("\\hslurchar");
103
104     f+= direction_char(dir);
105
106     int hidx = dy;
107     if (hidx <0)
108         hidx = -hidx;
109     hidx --;
110     int idx =-1;
111
112     idx = widx * 16 + hidx;
113     if (xpart < 0)
114         idx += 128;
115     
116     assert (idx < 256);
117     f+=String( "{" ) + String( idx ) + "}";
118
119     
120     s.tex = f;
121  
122     return s;
123 }
124
125 Symbol
126 Lookup::slur (int dy , Real &dx, int dir) const
127 {
128     assert(dx >=0 && abs(dir) <= 1);
129     int y_sign = sign(dy);
130
131     bool large = abs(dy) > 8;
132
133     if (y_sign) {
134         large |= dx>= 4*16 PT;
135     } else
136         large |= dx>= 4*54 PT;
137     
138     if (large) {
139         return big_slur(dy, dx, dir);
140     }
141     Real orig_dx = dx;
142     int widx = int(floor(dx/4.0)); // slurs better too small..
143     dx = 4.0 * widx;
144     if (widx)
145         widx --;
146     else {
147         WARN <<  "slur too narrow: " << print_dimen(orig_dx) << "\n";
148     }
149
150     int hidx = dy;
151     if (hidx <0)
152         hidx = -hidx;
153     hidx --; 
154     if (hidx > 8) {
155         WARN<<"slur to steep: " << dy << " shrinking (ugh)\n";
156     }
157     
158     Symbol s;
159     s.dim.x() = Interval(0,dx);
160     s.dim.y() = Interval(min(0,dy), max(0,dy));
161
162     String f = String("\\slurchar") + String( direction_char(y_sign) );
163
164     int idx=-1;
165     if (y_sign) {       
166         idx = hidx * 16 + widx;
167         if (dir < 0)
168             idx += 128;
169     } else {
170         if (dx >= 4*54 PT) {
171             WARN << "slur too wide: " << print_dimen(dx) <<
172                 " shrinking (ugh)\n";
173             dx = 4*54 PT;
174         }
175         idx = widx;
176         if (dir < 0)
177             idx += 54;          
178     }
179     
180     assert (idx < 256);
181     f+=String( "{" ) + String( idx ) + "}";
182     s.tex = f;
183
184     Atom a(s);
185     a.translate(dx/2, X_AXIS);
186     s.dim = a.extent();
187     s.tex = a.TeX_string();
188     return s;    
189 }
190
191 Symbol
192 Lookup::big_slur(int dy , Real &dx, int dir) const
193 {
194     assert(dx >= 24 PT);
195     Real slur_extra =abs(dy)  /2.0 + 2; 
196     int l_dy = int(Real (dy)/2 + slur_extra*dir);
197     int r_dy =  dy - l_dy;
198
199     Real internote_f = paper_l_->internote_f();
200     Real left_wid = dx/4.0;
201     Real right_wid = left_wid;
202
203     Atom l = half_slur(l_dy, left_wid, dir, -1);
204     Atom r = half_slur(r_dy, right_wid, dir, 1);
205     Real mid_wid = dx - left_wid - right_wid;
206
207     Atom m = half_slur(0, mid_wid, dir, 0);
208
209     Molecule mol;
210     mol.add(l);
211     Atom a(m);
212     a.translate(slur_extra * internote_f, Y_AXIS);
213     mol.add_right(m);
214     mol.add_right(r);
215     mol.translate( l_dy * internote_f, Y_AXIS);
216     Symbol s;
217     s.tex = mol.TeX_string();
218     s.dim = mol.extent();
219     return s;
220 }
221
222