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