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