]> git.donarmstrong.com Git - lilypond.git/blob - lily/tex-slur.cc
664460f8b9c542e4942071d24f8605273d559386
[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() = Interval (min (0,0), max (0,0)); // todo
59   s.dim_.x() = Interval (0,dx);
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 (dx/2, X_AXIS);
73
74   return s;
75 }
76
77 Atom
78 Lookup::half_slur (int dy, Real &dx, Direction 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   Atom 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 Atom
130 Lookup::slur (int dy , Real &dx, Direction dir) const
131 {
132   
133   assert (abs (dir) <= 1);
134   if  (dx < 0)
135     {
136       warning ("Negative slur/tie length: " + print_dimen (dx));
137       dx = 4.0 PT;
138     }
139   Direction y_sign = (Direction) sign (dy);
140
141   bool large = abs (dy) > 8;
142
143   if (y_sign) 
144     {
145       large |= dx>= 4*16 PT;
146     }
147   else
148     large |= dx>= 4*54 PT;
149   
150   if (large) 
151     {
152       return big_slur (dy, dx, dir);
153     }
154   Real orig_dx = dx;
155   int widx = int (floor (dx/4.0)); // slurs better too small..
156   dx = 4.0 * widx;
157   if (widx)
158     widx --;
159   else 
160     {
161       WARN <<  "slur too narrow: " << print_dimen (orig_dx) << "\n";
162     }
163
164   int hidx = dy;
165   if (hidx <0)
166     hidx = -hidx;
167   hidx --; 
168   if (hidx > 8) 
169     {
170       WARN<<"slur to steep: " << dy << " shrinking (ugh)\n";
171     }
172   
173   Atom s;
174   s.dim_.x() = Interval (-dx/2,dx/2);
175   s.dim_.y() = Interval (min (0,dy), max (0,dy));
176
177   String f = String ("\\slurchar") + String (direction_char (y_sign));
178
179   int idx=-1;
180   if (y_sign) { 
181     idx = hidx * 16 + widx;
182     if (dir < 0)
183       idx += 128;
184   }
185   else 
186     {
187       if (dx >= 4*54 PT) 
188         {
189           WARN << "slur too wide: " << print_dimen (dx) <<
190             " shrinking (ugh)\n";
191           dx = 4*54 PT;
192         }
193       idx = widx;
194       if (dir < 0)
195         idx += 54;              
196     }
197   
198   assert (idx < 256);
199   f+=String ("{") + String (idx) + "}";
200   s.tex_ = f;
201
202
203   s.translate (dx/2, X_AXIS);
204   return s;    
205 }
206
207 Atom
208 Lookup::big_slur (int dy , Real &dx, Direction dir) const
209 {
210   if (dx < 24 PT) 
211     {
212       warning ("big_slur too small " + print_dimen (dx) + " (stretching)");
213       dx = 24 PT;
214     }
215   
216   Real slur_extra =abs (dy)  /2.0 + 2; 
217   int l_dy = int (Real (dy)/2 + slur_extra*dir);
218   int r_dy =  dy - l_dy;
219
220   Real internote_f = paper_l_->internote_f();
221   Real left_wid = dx/4.0;
222   Real right_wid = left_wid;
223
224   Atom l = half_slur (l_dy, left_wid, dir, -1);
225   Atom r = half_slur (r_dy, right_wid, dir, 1);
226   Real mid_wid = dx - left_wid - right_wid;
227
228   Molecule mol;
229   mol.add (l);
230   Atom a (half_slur (0, mid_wid, dir, 0));
231   a.translate (slur_extra * internote_f, Y_AXIS);
232   mol.add_at_edge (X_AXIS, RIGHT, a);
233   mol.add_at_edge (X_AXIS, RIGHT, r);
234   mol.translate (l_dy * internote_f, Y_AXIS);
235   
236   Atom s;
237   s.tex_ = mol.TeX_string();
238   s.dim_ = mol.extent();
239   return s;
240 }
241
242