]> git.donarmstrong.com Git - lilypond.git/blob - lily/tex-slur.cc
release: 0.1.12
[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 Symbol
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   Symbol 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   Atom a (s);
73   a.translate (dx/2, X_AXIS);
74   s.tex = a.TeX_string();
75
76   return s;
77 }
78
79 Symbol
80 Lookup::half_slur (int dy, Real &dx, Direction dir, int xpart) const
81 {
82   Real orig_dx = dx;
83   if (!xpart)
84     return half_slur_middlepart (dx, dir);
85
86   int widx;
87                 
88   if (dx >= 96 PT) 
89     {
90       WARN << "Slur half too wide." << print_dimen (orig_dx) << " shrinking (ugh)\n";
91       dx =  96 PT;
92     }
93
94   widx = int (rint (dx/12.0));
95   dx = widx*12.0;
96   if (widx)
97     widx --;
98   else 
99     {
100       WARN <<  "slur too narrow " << print_dimen (orig_dx)<<"\n";
101     }
102         
103   Symbol s;
104   s.dim.x() = Interval (0,dx);
105   s.dim.y() = Interval (min (0,dy), max (0,dy));
106
107
108   String f = String ("\\hslurchar");
109
110   f+= direction_char (dir);
111
112   int hidx = dy;
113   if (hidx <0)
114     hidx = -hidx;
115   hidx --;
116   int idx =-1;
117
118   idx = widx * 16 + hidx;
119   if (xpart < 0)
120     idx += 128;
121   
122   assert (idx < 256);
123   f+=String ("{") + String (idx) + "}";
124
125   
126   s.tex = f;
127  
128   return s;
129 }
130
131 Symbol
132 Lookup::slur (int dy , Real &dx, Direction dir) const
133 {
134   
135   assert (abs (dir) <= 1);
136   if  (dx < 0)
137     {
138       warning ("Negative slur/tie length: " + print_dimen (dx));
139       dx = 4.0 PT;
140     }
141   Direction y_sign = (Direction) sign (dy);
142
143   bool large = abs (dy) > 8;
144
145   if (y_sign) 
146     {
147       large |= dx>= 4*16 PT;
148     }
149   else
150     large |= dx>= 4*54 PT;
151   
152   if (large) 
153     {
154       return big_slur (dy, dx, dir);
155     }
156   Real orig_dx = dx;
157   int widx = int (floor (dx/4.0)); // slurs better too small..
158   dx = 4.0 * widx;
159   if (widx)
160     widx --;
161   else 
162     {
163       WARN <<  "slur too narrow: " << print_dimen (orig_dx) << "\n";
164     }
165
166   int hidx = dy;
167   if (hidx <0)
168     hidx = -hidx;
169   hidx --; 
170   if (hidx > 8) 
171     {
172       WARN<<"slur to steep: " << dy << " shrinking (ugh)\n";
173     }
174   
175   Symbol s;
176   s.dim.x() = Interval (0,dx);
177   s.dim.y() = Interval (min (0,dy), max (0,dy));
178
179   String f = String ("\\slurchar") + String (direction_char (y_sign));
180
181   int idx=-1;
182   if (y_sign) { 
183     idx = hidx * 16 + widx;
184     if (dir < 0)
185       idx += 128;
186   }
187   else 
188     {
189       if (dx >= 4*54 PT) 
190         {
191           WARN << "slur too wide: " << print_dimen (dx) <<
192             " shrinking (ugh)\n";
193           dx = 4*54 PT;
194         }
195       idx = widx;
196       if (dir < 0)
197         idx += 54;              
198     }
199   
200   assert (idx < 256);
201   f+=String ("{") + String (idx) + "}";
202   s.tex = f;
203
204   Atom a (s);
205   a.translate (dx/2, X_AXIS);
206   s.dim = a.extent();
207   s.tex = a.TeX_string();
208   return s;    
209 }
210
211 Symbol
212 Lookup::big_slur (int dy , Real &dx, Direction dir) const
213 {
214   if (dx < 24 PT) 
215     {
216       warning ("big_slur too small " + print_dimen (dx) + " (stretching)");
217       dx = 24 PT;
218     }
219   
220   Real slur_extra =abs (dy)  /2.0 + 2; 
221   int l_dy = int (Real (dy)/2 + slur_extra*dir);
222   int r_dy =  dy - l_dy;
223
224   Real internote_f = paper_l_->internote_f();
225   Real left_wid = dx/4.0;
226   Real right_wid = left_wid;
227
228   Atom l = half_slur (l_dy, left_wid, dir, -1);
229   Atom r = half_slur (r_dy, right_wid, dir, 1);
230   Real mid_wid = dx - left_wid - right_wid;
231
232   Atom m = half_slur (0, mid_wid, dir, 0);
233
234   Molecule mol;
235   mol.add (l);
236   Atom a (m);
237   a.translate (slur_extra * internote_f, Y_AXIS);
238   mol.add_right (m);
239   mol.add_right (r);
240   mol.translate (l_dy * internote_f, Y_AXIS);
241   Symbol s;
242   s.tex = mol.TeX_string();
243   s.dim = mol.extent();
244   return s;
245 }
246
247