]> git.donarmstrong.com Git - lilypond.git/blob - src/texslur.cc
release: 0.0.16
[lilypond.git] / src / texslur.cc
1 #include <math.h>
2
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)
30 {
31     if (dx >= convert_dimen(400,"pt")) // todo
32         error ("halfslur too large");
33     int    widx = int(floor(dx / 4.0));
34     dx = widx * 4.0;
35     if (widx) widx --;
36     else {
37         WARN <<  "slur too narrow\n";
38     }
39
40     Symbol s;
41     
42     s.dim.y = Interval(MIN(0,0), MAX(0,0));
43     s.dim.x = Interval(0,dx);
44
45     String f =  String("\\hslurchar");
46     f += direction_char(0);
47
48     int idx = widx;
49     if (dir < 0)
50         idx += 128;
51
52
53     f+=String( "{" ) + idx + "}";
54     s.tex = f;
55     Atom a(s);
56     a.translate(Offset(dx/2,0));
57     s.tex = a.TeXstring();
58
59     return s;
60 }
61 Symbol
62 Lookup::half_slur(int dy, Real &dx, int dir, int xpart)
63 {
64     if (!xpart)
65         return half_slur_middlepart(dx, dir);
66
67     int widx;
68                 
69     if (dx >= convert_dimen(96,"pt")) {
70         WARN << "Slur half too wide.";
71         dx =  convert_dimen(96,"pt");
72     }
73     
74     widx = int(rint(dx/12.0));
75     dx = widx*12.0;
76     if (widx)
77         widx --;
78     else {
79         WARN <<  "slur too narrow\n";
80     }
81         
82     Symbol s;
83     s.dim.x = Interval(0,dx);
84     s.dim.y = Interval(MIN(0,dy), MAX(0,dy));
85
86
87     String f = String("\\hslurchar");
88
89     f+= direction_char(dir);
90
91     int hidx = dy;
92     if (hidx <0)
93         hidx = -hidx;
94     hidx --;
95     int idx =-1;
96     
97
98     idx = widx * 16 + hidx;
99     if (xpart < 0)
100         idx += 128;
101     
102     f+=String( "{" ) + idx + "}";
103
104     
105     s.tex = f;
106  
107     return s;
108 }
109
110 Symbol
111 Lookup::slur (int dy , Real &dx, int dir)
112 {                               // ugh. assuming pt here.
113     assert(dx >=0);
114     int y_sign = sgn(dy);
115
116     bool large = dy > 16;
117
118     if (y_sign) {
119         large |= dx>= convert_dimen(4*16, "pt");
120     } else
121         large |= dx>= convert_dimen(4*54, "pt");
122     
123     if (large) {
124         return big_slur(dy, dx, dir);
125     }
126     
127     int widx = int(floor(dx/4.0)); // slurs better too small..
128     dx = 4.0 * widx;
129     if (widx)
130         widx --;
131     else {
132         WARN <<  "slur too narrow\n";
133     }
134
135     int hidx = dy;
136     if (hidx <0)
137         hidx = -hidx;
138     hidx --; 
139     if (hidx > 16)
140         error("slur to steep");
141     
142     
143     Symbol s;
144     s.dim.x = Interval(0,dx);
145     s.dim.y = Interval(MIN(0,dy), MAX(0,dy));
146
147     String f = String("\\slurchar") + direction_char(y_sign);
148
149     int idx=-1;
150     if (y_sign) {       
151         idx = hidx * 16 + widx;
152         if (dir < 0)
153             idx += 128;
154     } else {
155         if (dx >= convert_dimen(4*54, "pt"))
156             error("slur too wide");
157         idx = widx;
158         if (dir < 0)
159             idx += 54;          
160     }
161     
162     f+=String( "{" ) + idx + "}";
163     s.tex = f;
164
165     Atom a(s);
166     a.translate(Offset(dx/2,0));
167     s.dim = a.extent();
168     s.tex = a.TeXstring();
169     return s;    
170 }
171
172 Symbol
173 Lookup::big_slur(int dy , Real &dx, int dir)
174 {
175     assert(dx >= convert_dimen(24,"pt"));
176     Real slur_extra =ABS(dy)  /2.0 + 2; 
177     int l_dy = int(Real (dy)/2 + slur_extra*dir);
178     int r_dy =  dy - l_dy;
179     
180     Real left_wid = dx/4.0;
181     Real right_wid = left_wid;
182
183     Atom l = half_slur(l_dy, left_wid, dir, -1);
184     Atom r = half_slur(r_dy, right_wid, dir, 1);
185     Real mid_wid = dx - left_wid - right_wid;
186
187     Atom m = half_slur(0, mid_wid, dir, 0);
188
189     Molecule mol;
190     mol.add(l);
191     Atom a(m);
192     a.translate(Offset(0,slur_extra * internote()));
193     mol.add_right(m);
194     mol.add_right(r);
195     mol.translate(Offset(0, l_dy * internote()));
196     Symbol s;
197     s.tex = mol.TeXstring();
198     s.dim = mol.extent();
199     return s;
200 }
201
202