]> git.donarmstrong.com Git - lilypond.git/blob - lily/tex-slur.cc
release: 0.0.72pre
[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
66     f+=String( "{" ) + String( idx ) + "}";
67     s.tex = f;
68     Atom a(s);
69     a.translate_x(dx/2);
70     s.tex = a.TeX_string();
71
72     return s;
73 }
74 Symbol
75 Lookup::half_slur(int dy, Real &dx, int dir, int xpart) const
76 {
77     Real orig_dx = dx;
78     if (!xpart)
79         return half_slur_middlepart(dx, dir);
80
81     int widx;
82                 
83     if (dx >= 96 PT) {
84         WARN << "Slur half too wide." << print_dimen(orig_dx) << " shrinking (ugh)\n";
85         dx =  96 PT;
86     }
87
88     widx = int(rint(dx/12.0));
89     dx = widx*12.0;
90     if (widx)
91         widx --;
92     else {
93         WARN <<  "slur too narrow " << print_dimen(orig_dx)<<"\n";
94     }
95         
96     Symbol s;
97     s.dim.x = Interval(0,dx);
98     s.dim.y = Interval(min(0,dy), max(0,dy));
99
100
101     String f = String("\\hslurchar");
102
103     f+= direction_char(dir);
104
105     int hidx = dy;
106     if (hidx <0)
107         hidx = -hidx;
108     hidx --;
109     int idx =-1;
110     
111
112     idx = widx * 16 + hidx;
113     if (xpart < 0)
114         idx += 128;
115     
116     f+=String( "{" ) + String( idx ) + "}";
117
118     
119     s.tex = f;
120  
121     return s;
122 }
123
124 Symbol
125 Lookup::slur (int dy , Real &dx, int dir) const
126 {
127     assert(dx >=0 && abs(dir) <= 1);
128     int y_sign = sign(dy);
129
130     bool large = dy > 16;
131
132     if (y_sign) {
133         large |= dx>= 4*16 PT;
134     } else
135         large |= dx>= 4*54 PT;
136     
137     if (large) {
138         return big_slur(dy, dx, dir);
139     }
140     Real orig_dx = dx;
141     int widx = int(floor(dx/4.0)); // slurs better too small..
142     dx = 4.0 * widx;
143     if (widx)
144         widx --;
145     else {
146         WARN <<  "slur too narrow: " << print_dimen(orig_dx) << "\n";
147     }
148
149     int hidx = dy;
150     if (hidx <0)
151         hidx = -hidx;
152     hidx --; 
153     if (hidx > 16) {
154         WARN<<"slur to steep: " << dy << " shrinking (ugh)\n";
155     }
156     
157     Symbol s;
158     s.dim.x = Interval(0,dx);
159     s.dim.y = Interval(min(0,dy), max(0,dy));
160
161     String f = String("\\slurchar") + String( direction_char(y_sign) );
162
163     int idx=-1;
164     if (y_sign) {       
165         idx = hidx * 16 + widx;
166         if (dir < 0)
167             idx += 128;
168     } else {
169         if (dx >= 4*54 PT) {
170             WARN << "slur too wide: " << print_dimen(dx) <<
171                 " shrinking (ugh)\n";
172             dx = 4*54 PT;
173         }
174         idx = widx;
175         if (dir < 0)
176             idx += 54;          
177     }
178     
179     f+=String( "{" ) + String( idx ) + "}";
180     s.tex = f;
181
182     Atom a(s);
183     a.translate_x(dx/2);
184     s.dim = a.extent();
185     s.tex = a.TeX_string();
186     return s;    
187 }
188
189 Symbol
190 Lookup::big_slur(int dy , Real &dx, int dir) const
191 {
192     assert(dx >= 24 PT);
193     Real slur_extra =abs(dy)  /2.0 + 2; 
194     int l_dy = int(Real (dy)/2 + slur_extra*dir);
195     int r_dy =  dy - l_dy;
196
197     Real internote_f = paper_l_->internote_f();
198     Real left_wid = dx/4.0;
199     Real right_wid = left_wid;
200
201     Atom l = half_slur(l_dy, left_wid, dir, -1);
202     Atom r = half_slur(r_dy, right_wid, dir, 1);
203     Real mid_wid = dx - left_wid - right_wid;
204
205     Atom m = half_slur(0, mid_wid, dir, 0);
206
207     Molecule mol;
208     mol.add(l);
209     Atom a(m);
210     a.translate_y(slur_extra * internote_f);
211     mol.add_right(m);
212     mol.add_right(r);
213     mol.translate_y( l_dy * internote_f);
214     Symbol s;
215     s.tex = mol.TeX_string();
216     s.dim = mol.extent();
217     return s;
218 }
219
220