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