Introduction
Introduction Statistics Contact Development Disclaimer Help
music.h - abc2ps - A powerful sheet setting tool using the simple abc notation
git clone git://vernunftzentrum.de/abc2ps.git
Log
Files
Refs
---
music.h (108504B)
---
1 /*
2 * This file is part of abc2ps,
3 * Copyright (C) 1996,1997,1998 Michael Methfessel
4 * See file abc2ps.c for details.
5 */
6
7 /* subroutines connected with output of music */
8
9 #define XP_START 0
10 #define XP_END (maxSyms-1)
11
12 /* ----- nwid ----- */
13 /* Sets the prefered width for a note depending on the duration.
14 Return value is default space on right and left side.
15 Function is determined by values at 0, 1/2, 1.
16 Return value is 1.0 for quarter note. */
17 float nwid (dur)
18 float dur;
19 {
20 float a,b,x,p,x0,p0;
21
22 a=2*(f1p-2*f5p+f0p);
23 b=f1p-f0p-a;
24 x = dur/(float)BASE;
25 p = a*x*x + b*x + f0p;
26
27 x0 = 0.25;
28 p0 = a*x0*x0 + b*x0 + f0p;
29 p = p/p0;
30 return p;
31 }
32
33 /* ----- xwid -- --- */
34 /* same as nwid but for stretched system */
35 float xwid (dur)
36 float dur;
37 {
38 float a,b,x,p,x0,p0;
39
40 a=2*(f1x-2*f5x+f0x);
41 b=f1x-f0x-a;
42 x = dur/(float)BASE;
43 p = a*x*x + b*x + f0x;
44
45 x0 = 0.25;
46 p0 = a*x0*x0 + b*x0 + f0x;
47 p = p/p0;
48
49 return p;
50 }
51
52 /* ----- next_note, prec_note ------ */
53 int next_note (k,n,symb)
54 int k,n;
55 struct SYMBOL symb[];
56 {
57 int i;
58 for (i=k+1;i<n;i++) {
59 if ((symb[i].type==NOTE)||(symb[i].type==REST)) return i;
60 }
61 return -1;
62 }
63
64 int prec_note (k,n,symb)
65 int k,n;
66 struct SYMBOL symb[];
67 {
68 int i;
69 for (i=k-1;i>=0;i--) {
70 if ((symb[i].type==NOTE)||(symb[i].type==REST)) return i;
71 }
72 return -1;
73 }
74
75
76 /* ----- followed_by_note ------ */
77 int followed_by_note (k,n,symb)
78 int k,n;
79 struct SYMBOL symb[];
80 {
81 int i;
82
83 for (i=k+1;i<n;i++) {
84 switch (symb[i].type) {
85 case INVISIBLE:
86 break;
87 case NOTE:
88 case REST:
89 return i;
90 break;
91 default:
92 return -1;
93 }
94 }
95 return -1;
96 }
97
98 /* ----- preceded_by_note ------ */
99 int preceded_by_note (k,n,symb)
100 int k,n;
101 struct SYMBOL symb[];
102 {
103 int i;
104
105 for (i=k-1;i>=0;i--) {
106 switch (symb[i].type) {
107 case INVISIBLE:
108 break;
109 case NOTE:
110 case REST:
111 return i;
112 break;
113 default:
114 return -1;
115 }
116 }
117 return -1;
118 }
119
120
121 void xch (i,j) /* sub to exchange two integers */
122 int *i,*j;
123 {
124 int k;
125 k=*i;
126 *i=*j;
127 *j=k;
128 }
129
130
131
132 /* ----- print_linetype ----------- */
133 void print_linetype (t)
134 int t;
135 {
136
137 if (t== COMMENT) printf("COMMENT\n");
138 else if (t== MUSIC) printf("MUSIC\n");
139 else if (t== E_O_F) printf("E_O_F\n");
140 else if (t== INFO) printf("INFO\n");
141 else if (t== TITLE) printf("TITLE\n");
142 else if (t== METER) printf("METER\n");
143 else if (t== PARTS) printf("PARTS\n");
144 else if (t== KEY) printf("KEY\n");
145 else if (t== XREF) printf("XREF\n");
146 else if (t== DLEN) printf("DLEN\n");
147 else if (t== HISTORY) printf("HISTORY\n");
148 else if (t== TEMPO) printf("TEMPO\n");
149 else if (t== BLANK) printf("BLANK\n");
150 else if (t== VOICE) printf("VOICE\n");
151 else if (t== MWORDS) printf("MWORDS\n");
152 else if (t== PSCOMMENT) printf("PSCOMMENT\n");
153 else printf("UNKNOWN LINE TYPE\n");
154 }
155
156 /* ----- print_syms: show sym properties set by parser ------ */
157 void print_syms(num1,num2,symb)
158 int num1,num2;
159 struct SYMBOL symb[];
160 {
161 int i,t,j,y,nsh;
162 char dsym[21] = {' ','~','.','J','M','H','u','v','R','T','K'};
163 char bsym[10] = {'-', '1' ,'2', '3', '4', '5', '6', '7', '8', '9'};
164 char str[21];
165
166 printf ("\n---------- Symbol list ----------\n");
167 printf ("word slur eol num description\n");
168
169 for (i=num1;i<num2;i++) {
170 printf (" %c %c %c %c %c ",
171 bsym[symb[i].word_st], bsym[symb[i].word_end],
172 bsym[symb[i].slur_st], bsym[symb[i].slur_end],
173 bsym[symb[i].eoln] );
174 printf ("%4d ", i);
175 t=symb[i].type;
176 switch (t) {
177
178 case NOTE:
179 case REST:
180 if (t==NOTE) printf ("NOTE ");
181 if (t==REST) printf ("REST ");
182 if (symb[i].npitch>1) printf (" [");
183 for (j=0;j<symb[i].npitch;j++) {
184 printf (" ");
185 if (symb[i].accs[j]==A_SH) printf ("^");
186 if (symb[i].accs[j]==A_NT) printf ("=");
187 if (symb[i].accs[j]==A_FT) printf ("_");
188 if (symb[i].accs[j]==A_DS) printf ("^^");
189 if (symb[i].accs[j]==A_DF) printf ("__");
190 y=3*(symb[i].pits[j]-18)+symb[i].yadd;
191 strcpy (str,"z");
192 if (t==NOTE) symbolic_pitch (symb[i].pits[j],str);
193 printf ("%s(%d)", str, symb[i].lens[j]);
194 }
195 if (symb[i].npitch>1) printf (" ]");
196 if (symb[i].p_plet)
197 printf (" (%d:%d:%d", symb[i].p_plet,symb[i].q_plet,symb[i].r_p…
198 if (strlen(symb[i].text)>0) printf (" \"%s\"", symb[i].text);
199 if (symb[i].dc.n>0) {
200 printf (" deco ");
201 for (j=0;j<symb[i].dc.n;j++)
202 printf ("%c",dsym[symb[i].dc.t[j]]);
203 }
204 if (symb[i].gr.n>0) {
205 printf (" grace ");
206 for (j=0;j<symb[i].gr.n;j++) {
207 if (j>0) printf ("-");
208 if (symb[i].gr.a[j]==A_SH) printf ("^");
209 if (symb[i].gr.a[j]==A_NT) printf ("=");
210 if (symb[i].gr.a[j]==A_FT) printf ("_");
211 symbolic_pitch (symb[i].gr.p[j],str);
212 printf ("%s",str);
213 }
214 }
215 break;
216
217 case BAR:
218 printf ("BAR ======= ");
219 if (symb[i].u==B_SNGL) printf ("single");
220 if (symb[i].u==B_DBL) printf ("double");
221 if (symb[i].u==B_LREP) printf ("left repeat");
222 if (symb[i].u==B_RREP) printf ("right repeat");
223 if (symb[i].u==B_DREP) printf ("double repeat");
224 if (symb[i].u==B_FAT1) printf ("thick-thin");
225 if (symb[i].u==B_FAT2) printf ("thin-thick");
226 if (symb[i].u==B_INVIS) printf ("invisible");
227 if (symb[i].v) printf (", ending %d", symb[i].v);
228 if (strlen(symb[i].text)>0) printf (", label \"%s\"",symb[i].text);
229 break;
230
231 case CLEF:
232 if (symb[i].u==TREBLE) printf ("CLEF treble");
233 if (symb[i].u==BASS) printf ("CLEF bass");
234 if (symb[i].u==ALTO) printf ("CLEF alto");
235 break;
236
237 case TIMESIG:
238 printf ("TIMESIG ");
239 if (symb[i].w==1) printf ("C");
240 else if (symb[i].w==2) printf ("C|");
241 else printf ("%d/%d", symb[i].u,symb[i].v);
242 break;
243
244 case KEYSIG:
245 printf ("KEYSIG ");
246 if (symb[i].t==A_SH) printf ("sharps ");
247 if (symb[i].t==A_FT) printf ("flats ");
248 printf ("%d to %d", symb[i].u,symb[i].v);
249 if (symb[i].w <= symb[i].v)
250 printf (", neutrals from %d", symb[i].w);
251 break;
252
253 case INVISIBLE:
254 printf ("INVIS ");
255 break;
256
257 default:
258 printf ("UNKNOWN ");
259 break;
260 }
261 printf ("\n");
262
263 }
264 printf ("\n");
265 }
266
267 /* ----- print_vsyms: print symbols for all voices ----- */
268 void print_vsyms ()
269 {
270 int i;
271
272 printf("\n");
273 for (i=0;i<nvoice;i++) {
274 if (nvoice>1)
275 printf ("Voice <%s> (%d of %d)", voice[i].id,i,nvoice);
276 print_syms (0,voice[i].nsym,symv[i]);
277 }
278 }
279
280
281 /* ----- set_head_directions ----------- */
282
283 #define ABS(a) ((a)>0) ? (a) : (-a)
284
285 /* decide whether to shift heads to other side of stem on chords */
286 /* also position accidentals to avoid too much overlap */
287 void set_head_directions (s)
288 struct SYMBOL *s;
289 {
290 int i,n,nx,sig,d,da,shift,nac;
291 int i1,i2,m;
292 float dx,xx,xmn;
293
294 n=s->npitch;
295 sig=-1;
296 if (s->stem>0) sig=1;
297 for (i=0;i<n;i++) {
298 s->shhd[i]=0;
299 s->shac[i]=8;
300 if (s->head==H_OVAL) s->shac[i]+=3;
301 s->xmn=0;
302 s->xmx=0;
303 }
304 if (n<2) return;
305
306 /* sort heads by pitch */
307 for (;;) {
308 nx=0;
309 for (i=1;i<n;i++) {
310 if ( (s->pits[i]-s->pits[i-1])*sig>0 ) {
311 xch (&s->pits[i],&s->pits[i-1]);
312 xch (&s->lens[i],&s->lens[i-1]);
313 xch (&s->accs[i],&s->accs[i-1]);
314 xch (&s->sl1[i],&s->sl1[i-1]);
315 xch (&s->sl2[i],&s->sl2[i-1]);
316 xch (&s->ti1[i],&s->ti1[i-1]);
317 xch (&s->ti2[i],&s->ti2[i-1]);
318 nx++;
319 }
320 }
321 if (!nx) break;
322 }
323
324 shift=0; /* shift heads */
325 for (i=n-2;i>=0;i--) {
326 d=s->pits[i+1]-s->pits[i];
327 if (d<0) d=-d;
328 if ((d>=2) || (d==0))
329 shift=0;
330 else {
331 shift=1-shift;
332 if (shift) {
333 dx=7.8;
334 if (s->head==H_EMPTY) dx=7.8;
335 if (s->head==H_OVAL) dx=10.0;
336 if (s->stem==-1) s->shhd[i]=-dx;
337 else s->shhd[i]=dx;
338 }
339 }
340 if (s->shhd[i] < s->xmn) s->xmn = s->shhd[i];
341 if (s->shhd[i] > s->xmx) s->xmx = s->shhd[i];
342 }
343
344 shift=0; /* shift accidentals */
345 i1=0; i2=n-1;
346 if (sig<0) { i1=n-1; i2=0; }
347 for (i=i1; ; i=i+sig) { /* count down in terms of pitch */
348 xmn=0; /* left-most pos of a close head */
349 nac=99; /* relative pos of next acc above */
350 for (m=0;m<n;m++) {
351 xx=s->shhd[m];
352 d=s->pits[m]-s->pits[i];
353 da=ABS(d);
354 if ((da<=5) && (s->shhd[m]<xmn)) xmn=s->shhd[m];
355 if ((d>0) && (da<nac) && s->accs[m]) nac=da;
356 }
357 s->shac[i]=8.5-xmn+s->shhd[i]; /* aligns accidentals in column */
358 if (s->head==H_EMPTY) s->shac[i] += 1.0;
359 if (s->head==H_OVAL) s->shac[i] += 3.0;
360 if (s->accs[i]) {
361 if (nac>=6) /* no overlap */
362 shift=0;
363 else if (nac>=4) { /* weak overlap */
364 if (shift==0) shift=1;
365 else shift=shift-1;
366 }
367 else { /* strong overlap */
368 if (shift==0) shift=2;
369 else if (shift==1) shift=3;
370 else if (shift==2) shift=1;
371 else if (shift==3) shift=0;
372 }
373
374 while (shift>=4) shift -=4;
375 s->shac[i] += 3*shift;
376 }
377 if (i==i2) break;
378 }
379
380 }
381
382
383 /* ----- set_minsyms: want at least one symbol in each voice --- */
384 void set_minsyms(ivc)
385 int ivc;
386 {
387 int n2;
388
389 n2=voice[ivc].nsym;
390 printf ("set_minsyms: n2=%d\n",n2);
391 if (n2>0) return;
392
393 symv[ivc][n2]=zsym;
394 symv[ivc][n2].type = INVISIBLE;
395 symv[ivc][n2].u = 3;
396 symv[ivc][n2].v = 3;
397 symv[ivc][n2].w = 3;
398 voice[ivc].nsym++;
399
400 }
401
402
403 /* ----- set_sym_chars: set symbol characteristics --- */
404 void set_sym_chars (n1,n2,symb)
405 int n1,n2;
406 struct SYMBOL symb[];
407 {
408 int i,np,m,ymn,ymx;
409 float yav,yy;
410
411 for (i=n1;i<n2;i++) {
412 if ((symb[i].type==NOTE)||(symb[i].type==REST)) {
413 symb[i].y=3*(symb[i].pits[0]-18)+symb[i].yadd;
414 if (symb[i].type==REST) symb[i].y=12;
415 yav=0;
416 ymn=1000;
417 ymx=-1000;
418 np=symb[i].npitch;
419 for (m=0;m<np;m++) {
420 yy=3*(symb[i].pits[m]-18)+symb[i].yadd;
421 yav=yav+yy/np;
422 if (yy<ymn) ymn=yy;
423 if (yy>ymx) ymx=yy;
424 }
425 symb[i].ymn=ymn;
426 symb[i].ymx=ymx;
427 symb[i].yav=yav;
428 symb[i].ylo=ymn;
429 symb[i].yhi=ymx;
430
431 }
432 }
433 }
434
435 /* ----- set_beams: decide on beams ---- */
436 void set_beams (n1,n2,symb)
437 int n1,n2;
438 struct SYMBOL symb[];
439 {
440 int j,lastnote,start_flag;
441
442 /* separate words at notes without flags */
443 start_flag=0;
444 lastnote=-1;
445 for (j=n1;j<n2;j++) {
446 if (symb[j].type==NOTE) {
447 if (start_flag) {
448 symb[j].word_st=1;
449 start_flag=0;
450 }
451 if (symb[j].flags==0) {
452 if (lastnote>=0) symb[lastnote].word_end=1;
453 symb[j].word_st=1;
454 symb[j].word_end=1;
455 start_flag=1;
456 }
457 lastnote=j;
458 }
459 }
460
461 }
462
463 /* ----- set_stems: decide on stem directions and lengths ---- */
464 void set_stems (n1,n2,symb)
465 int n1,n2;
466 struct SYMBOL symb[];
467 {
468 int beam,j,k,n,stem,laststem;
469 float avg,slen,lasty,dy;
470
471 /* set stem directions; near middle, use previous direction */
472 beam=0;
473 laststem=0;
474 for (j=n1; j<n2; j++) {
475 if (symb[j].type!=NOTE) laststem=0;
476
477 if (symb[j].type==NOTE) {
478
479 symb[j].stem=0;
480 if (symb[j].len<WHOLE) symb[j].stem=1;
481 if (symb[j].yav>=12) symb[j].stem=-symb[j].stem;
482 if ((symb[j].yav>11) && (symb[j].yav<13) && (laststem!=0)) {
483 dy=symb[j].yav-lasty;
484 if ((dy>-7) && (dy<7)) symb[j].stem=laststem;
485 }
486
487 if (symb[j].word_st && (!symb[j].word_end)) { /* start of beam */
488 avg=0;
489 n=0;
490 for (k=j;k<n2;k++) {
491 if (symb[k].type==NOTE) {
492 avg=avg+symb[k].yav;
493 n++;
494 }
495 if (symb[k].word_end) break;
496 }
497 avg=avg/n;
498 stem=1;
499 if (avg>=12) stem=-1;
500 if ((avg>11) && (avg<13) && (laststem!=0)) stem=laststem;
501 beam=1;
502 }
503
504 if (beam) symb[j].stem=stem;
505 if (symb[j].word_end) beam=0;
506 if (bagpipe) symb[j].stem=-1;
507 if (symb[j].len>=WHOLE) symb[j].stem=0;
508 laststem=symb[j].stem;
509 if (symb[j].len>=HALF) laststem=0;
510 lasty=symb[j].yav;
511 }
512 }
513
514 /* shift notes in chords (need stem direction to do this) */
515 for (j=n1;j<n2;j++)
516 if (symb[j].type==NOTE) set_head_directions (&symb[j]);
517
518 /* set height of stem end, without considering beaming for now */
519 for (j=n1; j<n2; j++) if (symb[j].type==NOTE) {
520 slen=STEM;
521 if (symb[j].npitch>1) slen=STEM_CH;
522 if (symb[j].flags==3) slen += 4;
523 if (symb[j].flags==4) slen += 9;
524 if ((symb[j].flags>2) && (symb[j].stem==1)) slen -= 1;
525 if (symb[j].stem==1) {
526 symb[j].y=symb[j].ymn;
527 symb[j].ys=symb[j].ymx+slen;
528 }
529 else if (symb[j].stem==-1) {
530 symb[j].y=symb[j].ymx;
531 symb[j].ys=symb[j].ymn-slen;
532 }
533 else {
534 symb[j].y=symb[j].ymx;
535 symb[j].ys=symb[j].ymx;
536 }
537 }
538 }
539
540 /* ----- set_sym_times: set time axis; also count through bars ----- */
541 int set_sym_times (n1,n2,symb,meter0)
542 int n1,n2;
543 struct SYMBOL symb[];
544 struct METERSTR meter0;
545 {
546 int i,pp,qq,rr,meter1,meter2,count,bnum,lastb,bsave;
547 int qtab[] = {0,0,3,2,3,0,2,0,3,0};
548 float time,factor,fullmes;
549
550 meter1=meter0.meter1;
551 meter2=meter0.meter2;
552
553 lastb=bnum=0;
554 bsave=1;
555
556 time=0.0;
557 factor=1.0;
558 for (i=n1;i<n2;i++) {
559 symb[i].time=time;
560
561 /* count through bar numbers, put into symb.t */
562 if (symb[i].type==BAR) {
563 fullmes=(WHOLE*meter1)/meter2;
564 if (bnum==0) {
565 bnum=barinit;
566 if (fullmes<time+0.001) bnum++;
567 symb[i].t=bnum;
568 lastb=i;
569 }
570 else if (time-symb[lastb].time>=fullmes-0.001) {
571 bnum++;
572 while (symb[i+1].type==BAR) {i++; symb[i].time=time; }
573 symb[i].t=bnum;
574 lastb=i;
575 }
576 if (symb[i].v>1) {
577 bnum=bsave;
578 symb[i].t=0;
579 }
580 if (symb[i].v==1) bsave=bnum;
581 }
582
583 if ((symb[i].type==NOTE)||(symb[i].type==REST)) {
584 if (symb[i].p_plet) {
585 pp=symb[i].p_plet;
586 qq=symb[i].q_plet;
587 rr=symb[i].r_plet;
588 if (qq==0) {
589 qq=qtab[pp];
590 if (qq==0) {
591 qq=2;
592 if (meter1%3==0) qq=3;
593 }
594 }
595 factor=((float)qq)/((float)pp);
596 count=rr;
597 }
598 time=time+factor*symb[i].len;
599 if (count>0) count--;
600 if (count==0) factor=1;
601 }
602
603 if (symb[i].type==TIMESIG) { /* maintain meter as we go along */
604 meter1=symb[i].u;
605 meter2=symb[i].v;
606 }
607
608 }
609
610 return bnum;
611
612 }
613
614 /* ----- set_sym_widths: set widths and prefered space --- */
615 /* This routine sets the minimal left and right widths wl,wr
616 so that successive symbols are still separated when
617 no extra glue is put between them. It also sets the prefered
618 spacings pl,pr for good output and xl,xr for expanded layout.
619 All distances in pt relative to the symbol center. */
620
621 #define AT_LEAST(a,b) if((a)<(b)) a=b;
622 void set_sym_widths (ns1,ns2,symb,ivc)
623 int ns1,ns2,ivc;
624 struct SYMBOL symb[];
625 {
626 int i,n,j0,j,m,n1,n2,bt,k,sl,k1,k2,got_note,ok;
627 float xx,w,swfac,spc,dur,yy;
628 char t[81],tt[81];
629
630 swfac=1.0;
631 if (strstr(cfmt.vocalfont.name,"Times-Roman")) swfac=1.00;
632 if (strstr(cfmt.vocalfont.name,"Times-Bold")) swfac=1.05;
633 if (strstr(cfmt.vocalfont.name,"Helvetica")) swfac=1.10;
634 if (strstr(cfmt.vocalfont.name,"Helvetica-Bold")) swfac=1.15;
635
636 got_note=0;
637 for (i=ns1;i<ns2;i++) {
638 switch (symb[i].type) {
639
640 case INVISIBLE: /* empty space; shrink,space,stretch from u,v,w */
641 symb[i].wl=symb[i].wr=0.5*symb[i].u;
642 symb[i].pl=symb[i].pr=0.5*symb[i].v;
643 symb[i].xl=symb[i].xr=0.5*symb[i].w;
644 break;
645
646 case NOTE:
647 case REST:
648 got_note=1;
649 dur=symb[i].len;
650 symb[i].wl=symb[i].wr=4.5;
651 if (symb[i].head==H_EMPTY) {symb[i].wl=6.0; symb[i].wr=14.0;}
652 if (symb[i].head==H_OVAL) {symb[i].wl=8.0; symb[i].wr=18.0;}
653 symb[i].pl=symb[i].xl=symb[i].wl;
654 symb[i].pr=symb[i].xr=symb[i].wr;
655
656 /* room for shifted heads and accidental signs */
657 for (m=0;m<symb[i].npitch;m++) {
658 xx=symb[i].shhd[m];
659 AT_LEAST (symb[i].wr, xx+6);
660 AT_LEAST (symb[i].wl, -xx+6);
661 if (symb[i].accs[m]) {
662 xx=xx-symb[i].shac[m];
663 AT_LEAST (symb[i].wl, -xx+3);
664 }
665 AT_LEAST (symb[i].xl, -xx+3);
666 symb[i].pl=symb[i].wl;
667 symb[i].xl=symb[i].wl;
668 }
669
670 /* room for slide */
671 for (k=0;k<symb[i].dc.n;k++) {
672 if (symb[i].dc.t[k]==D_SLIDE) symb[i].wl += 10;
673 }
674
675 /* room for grace notes */
676 if (symb[i].gr.n>0) {
677 xx=GSPACE0;
678 if (symb[i].gr.a[0]) xx=xx+3.5;
679 for (j=1;j<symb[i].gr.n;j++) {
680 xx=xx+GSPACE;
681 if (symb[i].gr.a[j]) xx=xx+4;
682 }
683 symb[i].wl = symb[i].wl + xx+1;
684 symb[i].pl = symb[i].pl + xx+1;
685 symb[i].xl = symb[i].xl + xx+1;
686 }
687
688 /* space for flag if stem goes up on standalone note */
689 if (symb[i].word_st && symb[i].word_end)
690 if ((symb[i].stem==1) && symb[i].flags>0)
691 AT_LEAST (symb[i].wr, 12);
692
693 /* leave room for dots */
694 if (symb[i].dots>0) {
695 AT_LEAST (symb[i].wr,12+symb[i].xmx);
696 if (symb[i].dots>=2) symb[i].wr=symb[i].wr+3.5;
697 n=(int) symb[i].y;
698 /* special case: standalone with up-stem and flags */
699 if (symb[i].flags && (symb[i].stem==1) && !(n%6))
700 if ((symb[i].word_st==1) && (symb[i].word_end==1)) {
701 symb[i].wr=symb[i].wr+DOTSHIFT;
702 symb[i].pr=symb[i].pr+DOTSHIFT;
703 symb[i].xr=symb[i].xr+DOTSHIFT;
704 }
705 }
706
707 /* extra space when down stem follows up stem */
708 j0=preceded_by_note(i,ns2,symb);
709 if ((j0>=0) && (symb[j0].stem==1) && (symb[i].stem==-1))
710 AT_LEAST (symb[i].wl, 7);
711
712 /* make sure helper lines don't overlap */
713 if ((j0>=0) && (symb[i].y>27) && (symb[j0].y>27))
714 AT_LEAST (symb[i].wl, 7.5);
715
716 /* leave room guitar chord */
717 if (strlen(symb[i].text)>0) {
718 /* special case: guitar chord under ending 1 or 2 */
719 /* leave some room to the left of the note */
720 if ((i>0) && (symb[i-1].type==BAR)) {
721 bt=symb[i-1].v;
722 if (bt) AT_LEAST (symb[i].wl, 18);
723 }
724 /* rest is same for all guitar chord cases */
725 tex_str(symb[i].text,t,&w);
726 xx=cfmt.gchordfont.size*w;
727 xx=xx*1.05; /* extra space mainly for helvetica font */
728 spc=xx*GCHPRE;
729 k1=prec_note(i,ns2,symb);
730 k2=next_note(i,ns2,symb);
731 if (spc>8.0) spc=8.0;
732 if ((k1>0) && (strlen(symb[k1].text)>0))
733 AT_LEAST (symb[i].wl, spc);
734 if ((k2>0) && (strlen(symb[k2].text)>0))
735 AT_LEAST (symb[i].wr, xx-spc);
736 }
737
738 /* leave room for vocals under note */
739 for (j=0;j<NWLINE;j++) {
740 if (symb[i].wordp[j]) {
741 sl=tex_str(symb[i].wordp[j],t,&w);
742 xx=swfac*cfmt.vocalfont.size*(w+2*cwid(' '));
743 AT_LEAST (symb[i].wl,xx*VOCPRE);
744 AT_LEAST (symb[i].wr,xx*(1.0-VOCPRE));
745 }
746 }
747
748 AT_LEAST (symb[i].pl, symb[i].wl);
749 AT_LEAST (symb[i].xl, symb[i].wl);
750 AT_LEAST (symb[i].pr, symb[i].wr);
751 AT_LEAST (symb[i].xr, symb[i].wr);
752 break;
753
754 case BAR:
755 symb[i].wl=symb[i].wr=0;
756 if (symb[i].u==B_SNGL) symb[i].wl=symb[i].wr=3;
757 else if (symb[i].u==B_DBL) { symb[i].wl=7; symb[i].wr=4; }
758 else if (symb[i].u==B_LREP) { symb[i].wl=3; symb[i].wr=12; }
759 else if (symb[i].u==B_RREP) { symb[i].wl=12; symb[i].wr=3; }
760 else if (symb[i].u==B_DREP) symb[i].wl=symb[i].wr=12;
761 else if (symb[i].u==B_FAT1) { symb[i].wl=3; symb[i].wr=9; }
762 else if (symb[i].u==B_FAT2) { symb[i].wl=9; symb[i].wr=3; }
763
764 if (ivc==ivc0) { /* bar numbers and labels next */
765 ok=0;
766 if ((cfmt.barnums>0) && (symb[i].t%cfmt.barnums==0)) ok=1;
767 if (strlen(symb[i].text)>0) ok=1;
768 if (ok) {
769 if (strlen(symb[i].text)>0) {
770 tex_str(symb[i].text,t,&w);
771 xx=cfmt.barlabelfont.size*w*0.5;
772 }
773 else {
774 sprintf (tt,"%d",symb[i].t);
775 tex_str(tt,t,&w);
776 xx=cfmt.barnumfont.size*w*0.5;
777 }
778 yy=60;
779 if (!got_note) yy=0;
780 if ((i>0) && (symb[i-1].type==NOTE)) {
781 yy=symb[i-1].ymx;
782 if (symb[i-1].stem==1) yy=yy+26;
783 }
784 if ((i>0) && (strlen(symb[i-1].text)>0)) yy=60;
785 AT_LEAST (symb[i].wl, 2);
786 if (yy>BNUMHT-4.0) AT_LEAST (symb[i].wl, xx+1);
787 if (!got_note) AT_LEAST (symb[i].wl, xx+1);
788 yy=0;
789 if (symb[i+1].type==NOTE) yy=symb[i+1].ymx;
790 if (yy>BNUMHT-4.0) AT_LEAST (symb[i].wr, xx+2);
791 if (strlen(symb[i+1].text)>0) AT_LEAST (symb[i].wr, xx+4);
792 }
793 }
794
795 symb[i].pl=symb[i].wl;
796 symb[i].pr=symb[i].wr;
797 symb[i].xl=symb[i].wl;
798 symb[i].xr=symb[i].wr;
799 break;
800
801 case CLEF:
802 symb[i].wl=symb[i].wr=symb[i].xl=13.5;
803 symb[i].pl=symb[i].pr=symb[i].xr=11.5;
804 break;
805
806 case KEYSIG:
807 n1=symb[i].u;
808 n2=symb[i].v;
809 if (n2>=n1) {
810 symb[i].wl=2;
811 symb[i].wr=5*(n2-n1+1)+2;
812 symb[i].pl=symb[i].wl;
813 symb[i].pr=symb[i].wr;
814 symb[i].xl=symb[i].wl;
815 symb[i].xr=symb[i].wr;
816 }
817 else {
818 symb[i].wl=symb[i].pl=symb[i].xl=3;
819 symb[i].wr=symb[i].pr=symb[i].xr=3;
820 }
821 break;
822
823 case TIMESIG:
824 symb[i].wl=8+4*(strlen(symb[i].text)-1);
825 symb[i].wr=symb[i].wl+4;
826 symb[i].pl=symb[i].wl;
827 symb[i].pr=symb[i].wr;
828 symb[i].xl=symb[i].wl;
829 symb[i].xr=symb[i].wr;
830 break;
831
832 default:
833 printf (">>> cannot set width for sym type %d\n", symb[i].type);
834 symb[i].wl=symb[i].wr=symb[i].xl=0;
835 symb[i].pl=symb[i].pr=symb[i].xr=0;
836 break;
837 }
838
839 }
840 }
841
842
843
844 /* ----- contract_keysigs: delete duplicate keysigs at staff start ---- …
845 /* Depending on line breaks, a key and/or meter change can come
846 at the start of a staff. Solution: scan through symbols from start
847 of line as long as sym is a CLEF, KEYSIG, or TIMESIG. Remove all
848 these, but set flags so that set_initsyms will draw the
849 key and meter which result at the end of the scan. */
850 int contract_keysigs (ip1)
851 int ip1;
852 {
853 int i,k,v,t,n3,sf,jp1,m,mtop;
854
855 mtop=10000;
856 for (v=0;v<nvoice;v++) {
857 i=ip1;
858 m=0;
859 for (;;) {
860 m++;
861 k=xp[i].p[v];
862 if (k>=0) {
863 if (symv[v][k].type==CLEF) {
864 voice[v].key.ktype=symv[v][k].u;
865 symv[v][k].type=INVISIBLE;
866 }
867 else if (symv[v][k].type==KEYSIG) {
868 sf=symv[v][k].v;
869 n3=symv[v][k].w;
870 if (n3-1<sf) sf=n3-1;
871 t =symv[v][k].t;
872 if (t==A_FT) sf=-sf;
873 if (t==A_NT) sf=0;
874 voice[v].key.sf=sf;
875 symv[v][k].type=INVISIBLE;
876 }
877 else if (symv[v][k].type==TIMESIG) {
878 voice[v].meter.insert=1;
879 voice[v].meter.meter1=symv[v][k].u;
880 voice[v].meter.meter2=symv[v][k].v;
881 voice[v].meter.mflag =symv[v][k].w;
882 strcpy(voice[v].meter.top,symv[v][k].text);
883 symv[v][k].type=INVISIBLE;
884 }
885 else
886 break;
887 }
888 i=xp[i].next;
889 if (i==XP_END) {
890 i=xp[i].prec;
891 break;
892 }
893 }
894 if (m<mtop && i>=0) {mtop=m; jp1=i; }
895 }
896
897 /* set glue for first symbol */
898 xp[jp1].shrink = xp[jp1].wl+3;
899 xp[jp1].space = xp[jp1].wl+9;
900 xp[jp1].stretch= xp[jp1].wl+16;
901
902 return jp1;
903
904 }
905
906 /* ----- set_initsyms: set symbols at start of staff ----- */
907 int set_initsyms (v,wid0)
908 int v;
909 float *wid0;
910 {
911 int k,t,n;
912 float x;
913
914 k=0;
915
916 /* add clef */
917 sym_st[v][k]=zsym;
918 sym_st[v][k].type = CLEF;
919 sym_st[v][k].u = voice[ivc].key.ktype;
920 sym_st[v][k].v = 0;
921 k++;
922
923 /* add keysig */
924 sym_st[v][k]=zsym;
925 sym_st[v][k].type = KEYSIG;
926 n=voice[ivc].key.sf;
927 t=A_SH;
928 if (n<0) { n=-n; t=A_FT; }
929 sym_st[v][k].u = 1;
930 sym_st[v][k].v = n;
931 sym_st[v][k].w = 100;
932 sym_st[v][k].t = t;
933 k++;
934
935 /* add timesig */
936 if (voice[ivc].meter.insert) {
937 sym_st[v][k]=zsym;
938 sym_st[v][k].type = TIMESIG;
939 sym_st[v][k].u = voice[ivc].meter.meter1;
940 sym_st[v][k].v = voice[ivc].meter.meter2;
941 sym_st[v][k].w = voice[ivc].meter.mflag;
942 strcpy(sym_st[v][k].text,voice[ivc].meter.top);
943 k++;
944 voice[ivc].meter.insert=0;
945 }
946
947 if (voice[ivc].insert_btype) {
948 sym_st[v][k].type = BAR;
949 sym_st[v][k].u=voice[ivc].insert_btype;
950 sym_st[v][k].v=voice[ivc].insert_num;
951 sym_st[v][k].t=voice[ivc].insert_bnum;
952 strcpy(sym_st[v][k].text,voice[ivc].insert_text);
953 voice[ivc].insert_btype=0;
954 voice[ivc].insert_bnum=0;
955 k++;
956 }
957
958 n=k;
959 set_sym_widths (0,n,sym_st[v],ivc);
960
961 x=0;
962 for (k=0;k<n;k++) {
963 x=x+sym_st[v][k].wl;
964 sym_st[v][k].x=x;
965 x=x+sym_st[v][k].wr;
966 }
967
968 *wid0=x+voice[v].insert_space;
969 return n;
970
971 }
972
973
974 /* ----- print_poslist ----- */
975 void print_poslist ()
976 {
977 int i,n,typ,vv;
978
979 printf ("\n----------- xpos list -----------\n");
980 printf (" num ptr type time dur width tfac"
981 " shrk spac stre eol vptr\n");
982
983 n=0;
984 i=xp[XP_START].next;
985 for (;;) {
986 typ=xp[i].type;
987 printf ("%3d %3d %d ", n,i,typ);
988 if (typ==NOTE) printf ("NOTE");
989 else if (typ==REST) printf ("REST");
990 else if (typ==KEYSIG) printf ("KEY ");
991 else if (typ==TIMESIG) printf ("TSIG");
992 else if (typ==BAR) printf ("BAR ");
993 else if (typ==CLEF) printf ("CLEF");
994 else if (typ==INVISIBLE) printf ("INVS");
995 else printf ("????");
996 printf (" %7.2f %6.2f %4.1f %4.1f %5.2f %5.1f %5.1f %5.1f",
997 xp[i].time,xp[i].dur,xp[i].wl,xp[i].wr,xp[i].tfac,
998 xp[i].shrink,xp[i].space,xp[i].stretch);
999 if (xp[i].eoln)
1000 printf(" %d ",xp[i].eoln);
1001 else
1002 printf(" - ");
1003 for (vv=0;vv<nvoice;vv++) {
1004 if (xp[i].p[vv]>=0)
1005 printf(" %2d",xp[i].p[vv]);
1006 else
1007 printf(" -");
1008 }
1009 printf ("\n");
1010 i=xp[i].next;
1011 n++;
1012 if (i==XP_END) break;
1013 }
1014
1015 }
1016
1017
1018
1019
1020 /* ----- insert_poslist: insert new element after element nins ----- */
1021 int insert_poslist (nins)
1022 int nins;
1023 {
1024 int new,nxt,vv;
1025
1026 new=ixpfree;
1027 ixpfree++;
1028 if (new>=XP_END)
1029 rxi("Too many symbols; use -maxs to increase limit, now ",maxSyms);
1030
1031 nxt=xp[nins].next;
1032 xp[new].prec=nins;
1033 xp[new].next=nxt;
1034 xp[nins].next=new;
1035 xp[nxt].prec=new;
1036 for (vv=0;vv<nvoice;vv++) xp[new].p[vv]=-1;
1037
1038 return new;
1039
1040 }
1041
1042 /* ----- set_poslist: make list of horizontal posits to align voices ---…
1043 void set_poslist ()
1044 {
1045 int i,n,v,vv,typ,nok,nins;
1046 float tol=0.01;
1047 float d,tim;
1048
1049 /* initialize xp with data from top nonempty voice, ivc0 */
1050 v=ivc0;
1051 n=0;
1052 xp[0].next=1;
1053 for (i=0;i<voice[v].nsym;i++) {
1054 n++;
1055 xp[n].prec=n-1;
1056 xp[n].next=n+1;
1057 symv[v][i].p=n;
1058 for (vv=0;vv<nvoice;vv++) xp[n].p[vv]=-1;
1059 xp[n].p[v]=i;
1060 typ=symv[v][i].type;
1061 if (typ==REST) typ=NOTE;
1062 xp[n].type = typ;
1063 xp[n].time = symv[v][i].time;
1064 xp[n].dur = xp[n].tfac = 0;
1065 xp[n].shrink = xp[n].space = xp[n].stretch =0;
1066 xp[n].wl = xp[n].wr = 0;
1067 xp[n].eoln=symv[v][i].eoln;
1068 }
1069 xp[n].next=XP_END;
1070 xp[XP_END].prec=n;
1071 ixpfree=n+1;
1072
1073 /* find or insert syms for other voices */
1074 for (v=0;v<nvoice;v++) {
1075 if (voice[v].draw && v!=ivc0) {
1076 n=XP_START;
1077 for (i=0;i<voice[v].nsym;i++) {
1078 tim=symv[v][i].time;
1079 typ=symv[v][i].type;
1080 if (typ==REST) typ=NOTE;
1081 nok=-1;
1082 nins=n;
1083 for (;;) {
1084 n=xp[n].next;
1085 if (n==XP_END) break;
1086 d=xp[n].time-tim;
1087 if (xp[n].time<tim-tol) nins=n;
1088 if (d*d<tol*tol && xp[n].type==typ) {
1089 nok=n;
1090 break;
1091 }
1092 if (xp[n].time>tim+tol) break;
1093 }
1094 if (nok>0)
1095 n=nok;
1096 else {
1097 n=insert_poslist (nins);
1098 xp[n].type=typ;
1099 xp[n].time=tim;
1100 xp[n].dur = xp[n].tfac = 0;
1101 xp[n].shrink = xp[n].space = xp[n].stretch =0;
1102 xp[n].wl = xp[n].wr = 0;
1103 xp[n].eoln=0;
1104 }
1105 symv[v][i].p=n;
1106 xp[n].p[v]=i;
1107 }
1108 }
1109 }
1110
1111 /*| print_poslist (); |*/
1112
1113 }
1114
1115
1116 /* ----- set_xpwid: set symbol widths and tfac in xp list ----- */
1117 void set_xpwid()
1118 {
1119 int i,j,k,i1,i2,k1,k2,v,nsm;
1120 float fac,dy,ff,wv,wx;
1121
1122 /* set all tfacs to 1.0 */
1123 i=i1=xp[XP_START].next;
1124 for (;;) {
1125 xp[i].tfac=1.0;
1126 xp[i].wl=xp[i].wr=WIDTH_MIN;
1127 i2=i;
1128 i=xp[i].next;
1129 if (i==XP_END) break;
1130 }
1131
1132 /* loop over voices. first voice last, assumed most important */
1133 for (v=nvoice-1;v>=0;v--) {
1134 nsm=voice[v].nsym;
1135
1136 /* first symbol and last symbol */
1137 k1=symv[v][0].p;
1138 k2=symv[v][nsm-1].p;
1139 if (k1==i1 && symv[v][0].wl>xp[k1].wl) xp[k1].wl=symv[v][0].wl;
1140 if (k2==i2 && symv[v][nsm-1].wr>xp[k2].wr) xp[k2].wr=symv[v][nsm-1].…
1141
1142 /* loop over symbol nn pairs */
1143 for (i=1;i<nsm;i++) {
1144 j=i-1;
1145 k1=symv[v][j].p;
1146 k2=symv[v][i].p;
1147 if (xp[k1].next==k2) {
1148 if (symv[v][j].wr>xp[k1].wr) xp[k1].wr=symv[v][j].wr;
1149 if (symv[v][i].wl>xp[k2].wl) xp[k2].wl=symv[v][i].wl;
1150
1151 if (symv[v][j].type==NOTE && symv[v][i].type==NOTE) {
1152 fac=1.0;
1153 /* reduce distance under a beam */
1154 if (symv[v][i].word_st==0) fac=fac*fnnp;
1155 /* reduce distance for large jumps in pitch */
1156 dy=symv[v][i].y-symv[v][j].y;
1157 if (dy<0) dy=-dy;
1158 ff=1-0.010*dy;
1159 if (ff<0.9) ff=0.9;
1160 fac=fac*ff;
1161 xp[k2].tfac=fac;
1162 }
1163 }
1164 }
1165 }
1166
1167 /* check for all nn pairs in voice, in case some syms very wide */
1168 for (v=nvoice-1;v>=0;v--) {
1169 nsm=voice[v].nsym;
1170 for (i=1;i<nsm;i++) {
1171 j=i-1;
1172 k1=symv[v][j].p;
1173 k2=symv[v][i].p;
1174 if (xp[k1].next!=k2) {
1175 wv=symv[v][j].wr+symv[v][i].wl;
1176 wx=xp[k1].wr+xp[k2].wl;
1177 k=k1;
1178 for (;;) {
1179 k=xp[k].next;
1180 if (k==k2) break;
1181 wx=wx+xp[k].wl+xp[k].wr;
1182 }
1183 if(wx<wv) {
1184 fac=wv/wx;
1185 xp[k1].wr=fac*xp[k1].wr;
1186 xp[k2].wl=fac*xp[k2].wl;
1187 k=k1;
1188 for (;;) {
1189 k=xp[k].next;
1190 if (k==k2) break;
1191 xp[k].wl=fac*xp[k].wl;
1192 xp[k].wr=fac*xp[k].wr;
1193 }
1194
1195 }
1196 }
1197 }
1198 }
1199
1200 }
1201
1202
1203 /* ----- set_spaces: set the shrink,space,stretch distances ----- */
1204 void set_spaces ()
1205 {
1206 int i,j,n,nxt,typ,typl,meter1,meter2;
1207 float w0,w1,w2;
1208 float vbnp,vbnx,vnbp,vnbx;
1209
1210 /* note lengths for spaces at bars. Use dcefault meter for now */
1211 meter1=default_meter.meter1;
1212 meter2=default_meter.meter2;
1213 vbnp=(rbnp*meter1*BASE)/meter2;
1214 vbnx=(rbnx*meter1*BASE)/meter2;
1215 vnbp=(rnbp*meter1*BASE)/meter2;
1216 vnbx=(rnbx*meter1*BASE)/meter2;
1217
1218 /* redefine durations as differences in start times */
1219 n=0;
1220 i=xp[XP_START].next;
1221 for (;;) {
1222 nxt=xp[i].next;
1223 if (nxt!=XP_END) xp[i].dur=xp[nxt].time-xp[i].time;
1224 i=nxt;
1225 n++;
1226 if (i==XP_END) break;
1227 }
1228
1229 i=xp[XP_START].next;
1230 j=-1;
1231 typl=0;
1232 for (;;) {
1233 nxt=xp[i].next;
1234 typ=xp[i].type;
1235
1236 /* shrink distance is sum of left and right widths */
1237 if (j>=0)
1238 xp[i].shrink=xp[j].wr+xp[i].wl;
1239 else
1240 xp[i].shrink=xp[i].wl;
1241 xp[i].space=xp[i].stretch=xp[i].shrink;
1242
1243 if (xp[i].type==NOTE) {
1244
1245 if (typl==NOTE) { /* note after another note */
1246 w1 = lnnp*nwid(xp[j].dur);
1247 w2 = lnnp*nwid(xp[i].dur);
1248 xp[i].space = bnnp*w1 + (1-bnnp)*0.5*(w1+w2);
1249 w1 = lnnx*xwid(xp[j].dur);
1250 w2 = lnnx*xwid(xp[i].dur);
1251 xp[i].stretch = bnnx*w1 + (1-bnnx)*0.5*(w1+w2);
1252 }
1253
1254 else { /* note at start of bar */
1255 w1 = lbnp*nwid(xp[i].dur);
1256 w0 = lbnp*nwid(vbnp);
1257 if (w0>w1) w0=w1;
1258 xp[i].space = bbnp*w1 + (1-bbnp)*w0 + (j>=0 ? xp[j].wr : 0);
1259 if (xp[i].space<14.0) xp[i].space=14.0;
1260 w1 = lbnx*xwid(xp[i].dur);
1261 w0 = lbnx*xwid(vbnp);
1262 if (w0>w1) w0=w1;
1263 xp[i].stretch = bbnx*w1 + (1-bbnx)*w0 + (j>=0 ? xp[j].wr : 0);
1264 if (xp[i].stretch<18.0) xp[i].stretch=18.0;
1265 if (xp[i].shrink<12.0) xp[i].shrink=12.0;
1266 }
1267 }
1268
1269 else { /* some other symbol after note */
1270 if (typl==NOTE) {
1271 w1 = lnbp*nwid(xp[j].dur);
1272 w0 = lnbp*nwid(vnbp);
1273 xp[i].space = bnbp*w1 + (1-bnbp)*w0 + xp[i].wl;
1274 if (xp[i].space<13.0) xp[i].space=13.0;
1275 w1 = lnbx*xwid(xp[j].dur);
1276 w0 = lnbx*xwid(vnbx);
1277 xp[i].stretch = bnbx*w1 + (1-bnbx)*w0 + xp[i].wl;
1278 if (xp[i].stretch<17.0) xp[i].stretch=17.0;
1279 }
1280 }
1281
1282 /* multiply space and stretch by factors tfac */
1283 xp[i].space = xp[i].space*xp[i].tfac;
1284 xp[i].stretch = xp[i].stretch*xp[i].tfac;
1285
1286 /* make sure that shrink < space < stretch */
1287 if (xp[i].space<xp[i].shrink) xp[i].space=xp[i].shrink;
1288 if (xp[i].stretch<xp[i].space) xp[i].stretch=xp[i].space;
1289
1290 j=i;
1291 typl=typ;
1292 i=nxt;
1293
1294 if (i==XP_END) break;
1295 }
1296
1297 if (verbose>=11) print_poslist ();
1298
1299 }
1300
1301 /* ----- check_overflow: returns upper limit which fits on staff ------ …
1302 int check_overflow (ip1,ip2,width)
1303 int ip1,ip2;
1304 float width;
1305 {
1306
1307 int i,jp2,lastcut,nbar,need_note;
1308 float space,shrink,stretch,alfa,alfa0;
1309
1310 /* max shrink is alfa0 */
1311 alfa0=ALFA_X;
1312 if (cfmt.continueall) alfa0=cfmt.maxshrink;
1313 if (gmode==G_SHRINK) alfa0=1.0;
1314 if (gmode==G_SPACE) alfa0=0.0;
1315 if (gmode==G_STRETCH) alfa0=1.0;
1316
1317 jp2=ip2;
1318 space=shrink=stretch=0;
1319 lastcut=-1;
1320 nbar=0;
1321 need_note=1;
1322 i=ip1;
1323 for (;;) {
1324 space=space+xp[i].space;
1325 shrink=shrink+xp[i].shrink;
1326 stretch=stretch+xp[i].stretch;
1327 alfa=0;
1328 if (space>shrink) {
1329 alfa=(space-width)/(space-shrink);
1330 if (xp[i].type!=BAR)
1331 alfa=((space+8)-width)/(space-shrink);
1332 }
1333
1334 if (alfa>alfa0) {
1335 if (!cfmt.continueall) {
1336 if (verbose<=3) printf ("\n");
1337 printf ("+++ Overfull after %d bar%s in staff %d\n",
1338 nbar, nbar==1 ? "" : "s", mline);
1339 }
1340 jp2=i;
1341 if (i==ip1) jp2=xp[i].next;
1342 if (lastcut>=0) jp2=xp[lastcut].next;
1343 break;
1344 }
1345 /* The need_note business is to cut at the first of consecutive bars…
1346 if (xp[i].type==NOTE) need_note=0;
1347 if (xp[i].type==BAR && need_note==0) {lastcut=i; need_note=1; nbar++…
1348 if (xp[i].type==KEYSIG) lastcut=i;
1349 i=xp[i].next;
1350 if (i==ip2) break;
1351 }
1352
1353 return jp2;
1354
1355 }
1356
1357
1358 /* ----- set_glue --------- */
1359 float set_glue (ip1,ip2,width)
1360 int ip1,ip2;
1361 float width;
1362 {
1363
1364 int i,j;
1365 float space,shrink,stretch,alfa,beta,glue,w,x,d1,d2,w1;
1366 float alfa0,beta0;
1367
1368 alfa0=ALFA_X; /* max shrink and stretch */
1369 if (cfmt.continueall) alfa0=cfmt.maxshrink;
1370 if (gmode==G_SHRINK) alfa0=1.0;
1371 if (gmode==G_SPACE) alfa0=0.0;
1372 if (gmode==G_STRETCH) alfa0=1.0;
1373 beta0=BETA_X;
1374 if (cfmt.continueall) beta0=BETA_C;
1375
1376
1377 space=shrink=stretch=0;
1378 i=ip1;
1379 for (;;) {
1380 space=space+xp[i].space;
1381 shrink=shrink+xp[i].shrink;
1382 stretch=stretch+xp[i].stretch;
1383 j=i;
1384 i=xp[i].next;
1385 if (i==ip2) break;
1386 }
1387
1388 /* add extra space if last symbol is not a bar */
1389 if (xp[j].type!=BAR) {
1390 d1=d2=xp[j].wr+3;
1391 if (xp[j].type==NOTE) d2 = lnbp*nwid(xp[j].dur)+xp[j].wr;
1392 if (d2<d1) d2=d1;
1393 shrink = shrink + d1;
1394 space = space + d2;
1395 stretch = stretch + d2;
1396 }
1397
1398 /* select alfa and beta */
1399 alfa=beta=0;
1400 if (space>width) {
1401 alfa=99;
1402 if (space>shrink) alfa=(space-width)/(space-shrink);
1403 }
1404 else {
1405 beta=99;
1406 if (stretch>space) beta=(width-space)/(stretch-space);
1407 if (!cfmt.stretchstaff) beta=0;
1408 }
1409
1410 if (gmode==G_SHRINK) { alfa=1; beta=0;} /* force minimal spacing …
1411 if (gmode==G_STRETCH) { alfa=0; beta=1;} /* force stretched spacin…
1412 if (gmode==G_SPACE) { alfa=beta=0; } /* force natural spacing …
1413
1414 /*| if (alfa>alfa0) { alfa=alfa0; beta=0; } |*/
1415
1416 if (beta>beta0) {
1417 if (!cfmt.continueall) {
1418 if (verbose<=3) printf ("\n");
1419 printf ("+++ Underfull (%.0fpt of %.0fpt) in staff %d\n",
1420 (beta0*stretch+(1-beta0)*space)*cfmt.scale,
1421 cfmt.staffwidth,mline);
1422 }
1423 alfa=0;
1424 if (!cfmt.stretchstaff) beta=0;
1425 if ((!cfmt.stretchlast) && (ip2==XP_END)) {
1426 w1=alfa_last*shrink+beta_last*stretch+(1-alfa_last-beta_last)*spac…
1427 if (w1<width) {
1428 alfa=alfa_last; /* shrink undefull last line same as previous…
1429 beta=beta_last;
1430 }
1431 }
1432 }
1433
1434 w=alfa*shrink+beta*stretch+(1-alfa-beta)*space;
1435 if (verbose>=5) {
1436 if (alfa>0) printf ("Shrink staff %.0f%%", 100*alfa);
1437 else if (beta>0) printf ("Stretch staff %.0f%%", 100*beta);
1438 else printf ("No shrink or stretch");
1439 printf (" to width %.0f (%.0f,%.0f,%.0f)\n",w,shrink,space,stretch);
1440 }
1441
1442 /* now calculate the x positions */
1443 x=0;
1444 i=ip1;
1445 for (;;) {
1446 glue=alfa*xp[i].shrink+beta*xp[i].stretch+(1-alfa-beta)*xp[i].space;
1447 x=x+glue;
1448 xp[i].x=x;
1449 if (verbose>22) printf ("pos[%d]: type=%d pos=%.2f\n", i,xp[i].type…
1450 i=xp[i].next;
1451 if (i==ip2) break;
1452 }
1453
1454 alfa_last=alfa;
1455 beta_last=beta;
1456 return w;
1457
1458 }
1459
1460
1461 /* ----- adjust_group: even out spacings for one group of notes --- */
1462 /* Here we repeat the whole glue thing, in rudimentary form */
1463 void adjust_group(i1,i2)
1464 int i1,i2;
1465 {
1466 int j;
1467 float dx,x,spa,shr,str,hp,hx,alfa,beta,dur1;
1468
1469 dx=sym[i2].x-sym[i1].x;
1470 shr=sym[i1].wr+sym[i2].wl;
1471 for (j=i1+1;j<i2;j++) shr=shr+sym[j].wl+sym[j].wr;
1472 dur1=sym[i1].len;
1473 hp=lnnp*nwid(dur1);
1474 hx=lnnx*xwid(dur1);
1475 spa = (i2-i1)*hp;
1476 str = (i2-i1)*hx;
1477
1478 alfa=beta=0;
1479 if (dx>spa)
1480 beta=(dx-spa)/(str-spa);
1481 else
1482 alfa=(dx-spa)/(shr-spa);
1483
1484 x=sym[i1].x;
1485 for (j=i1+1;j<=i2;j++) {
1486 x=x+alfa*(sym[j-1].wr+sym[j].wl)+beta*hx+(1-alfa-beta)*hp;
1487 sym[j].x=x;
1488 }
1489
1490 }
1491
1492
1493 /* ----- adjust_spacings: even out triplet spacings etc --- */
1494 void adjust_spacings (n)
1495 int n;
1496 {
1497 int i,i1,count,beam,num;
1498
1499 /* adjust the n-plets */
1500 count=0;
1501 for (i=1;i<n;i++) {
1502 if ((sym[i].type==NOTE)||(sym[i].type==REST)) {
1503 if (sym[i].p_plet) {
1504 i1=i;
1505 count=sym[i].r_plet;
1506 }
1507 if (count>0 && sym[i].len!=sym[i1].len) count=0;
1508 if (count==1) adjust_group (i1,i);
1509 if (count>0) count--;
1510 }
1511 else
1512 count=0;
1513 }
1514
1515 /* adjust beamed notes of equal duration */
1516 beam=0;
1517 for (i=1;i<n;i++) {
1518 if ((sym[i].type==NOTE)||(sym[i].type==REST)) {
1519 if (sym[i].word_st && (!sym[i].word_end)) {
1520 i1=i;
1521 beam=1;
1522 if (sym[i].p_plet) beam=0; /* don't do nplets here */
1523 }
1524 if (beam && sym[i].len!=sym[i1].len) beam=0;
1525 if (beam && sym[i].word_end) {
1526 num=i-i1+1;
1527 if (num>2 && num<4) adjust_group (i1,i);
1528 }
1529 if (sym[i].word_end) beam=0;
1530 }
1531 else
1532 beam=0;
1533 }
1534
1535 }
1536
1537
1538 /* ----- adjust_rests: position single rests in bar center */
1539 void adjust_rests (n,v)
1540 int n,v;
1541 {
1542 int i,ok;
1543
1544 for (i=2;i<n-1;i++) {
1545 if ((sym[i].type==REST) && sym[i].fullmes) {
1546
1547 ok=1;
1548 if ((sym[i-1].type==REST) || (sym[i-1].type==NOTE)) ok=0;
1549 if ((sym[i+1].type==REST) || (sym[i+1].type==NOTE)) ok=0;
1550
1551 if (ok) {
1552 sym[i].head = H_OVAL;
1553 sym[i].dots = 0;
1554 sym[i].x = 0.5*(sym[i-1].x+sym[i+1].x);
1555 }
1556
1557 }
1558 }
1559
1560 }
1561
1562
1563
1564 /* ----- copy_vsyms: copy selected syms for voice to v sym --- */
1565 int copy_vsyms (v,ip1,ip2,wid0)
1566 int v,ip1,ip2;
1567 float wid0;
1568 {
1569 int i,n,m,k;
1570 float d1,d2,r,x;
1571
1572 /* copy staff initialization symbols */
1573 n=0;
1574 for (i=0;i<nsym_st[v];i++) {
1575 sym[n]=sym_st[v][i];
1576 n++;
1577 }
1578
1579 /* copy real symbols, shifted by wid0 */
1580 i=ip1;
1581 m=0;
1582 for (;;) {
1583 k=xp[i].p[v];
1584 if (k >= 0) {
1585 sym[n]=symv[v][k];
1586 sym[n].x=xp[i].x+wid0;
1587 n++;
1588 m++;
1589 }
1590 i=xp[i].next;
1591 if (i==ip2) break;
1592 }
1593
1594 /* adjust things for more pretty output.. */
1595 adjust_rests (n,v);
1596 if (mvoice>1) adjust_spacings (n);
1597
1598 /* small random shifts make the output more human... */
1599 for (i=1;i<n-1;i++) {
1600 if ((sym[i].type==NOTE) || (sym[i].type==REST)) {
1601 d1=sym[i].x-sym[i-1].x;
1602 d2=sym[i+1].x-sym[i].x;
1603 r=RANFAC*d1;
1604 if (d2<d1) r=RANFAC*d2;
1605 if (r>RANCUT) r=RANCUT;
1606 x=ranf(-r,r);
1607 sym[i].x=sym[i].x+x;
1608 }
1609 }
1610
1611 return n;
1612
1613 }
1614
1615
1616 /* ----- draw_timesig ------- */
1617 void draw_timesig (x,s)
1618 struct SYMBOL s;
1619 float x;
1620 {
1621 if (s.w==1)
1622 PUT1("%.1f csig\n", x)
1623 else if (s.w==2)
1624 PUT1("%.1f ctsig\n", x)
1625 else
1626 /* PUT3("%.1f (%d) (%d) tsig\n", x, s.u, s.v) */
1627 PUT3("%.1f (%s) (%d) tsig\n", x, s.text, s.v)
1628 }
1629
1630 /* ----- draw_keysig: return sf for this key ----- */
1631 int draw_keysig (x,s)
1632 struct SYMBOL s;
1633 float x;
1634 {
1635 float p;
1636 int i,n1,n2,n3,t,yad,sf;
1637 int sh_pos[8]={0, 24,15,27,18,9,21,15};
1638 int ft_pos[8]={0, 12,21,9,18,6,15,3};
1639
1640 n1=s.u; /* which symbol to start with */
1641 n2=s.v; /* up to which symbol to go */
1642 n3=s.w; /* draw neutrals instead starting from this one …
1643 t =s.t; /* type of symbol: sharp or flat */
1644
1645 yad = 0;
1646 if (voice[ivc].key.ktype==BASS) yad = -6;
1647 if (voice[ivc].key.ktype==ALTO) yad = -3;
1648
1649 if (n2>7) {
1650 printf ("+++ Keysig seems to have %d symbols ???\n", n2);
1651 return 0;
1652 }
1653
1654 sf=0;
1655 if (t==A_SH) {
1656 p=x;
1657 for (i=n1;i<=n2;i++) {
1658 if (i>=n3)
1659 PUT2("%.1f %d nt0 ",p,sh_pos[i]+yad)
1660 else {
1661 sf++;
1662 PUT2("%.1f %d sh0 ",p,sh_pos[i]+yad)
1663 }
1664 p=p+5;
1665 }
1666 PUT0("\n")
1667 }
1668 else if (t==A_FT) {
1669 p=x;
1670 for (i=n1;i<=n2;i++) {
1671 if (i>=n3)
1672 PUT2("%.1f %d nt0 ", p, ft_pos[i]+yad)
1673 else {
1674 sf--;
1675 PUT2("%.1f %d ft0 ", p, ft_pos[i]+yad)
1676 }
1677 p=p+5;
1678 }
1679 PUT0("\n")
1680 }
1681 else
1682 bug ("wrong type in draw_keysig", 0);
1683
1684 return sf;
1685 }
1686
1687
1688 /* ----- draw_bar ------- */
1689 void draw_bar (x,s)
1690 struct SYMBOL s;
1691 float x;
1692 {
1693
1694 if (s.u==B_SNGL) /* draw the bar */
1695 PUT1("%.1f bar\n", x)
1696 else if (s.u==B_DBL)
1697 PUT1("%.1f dbar\n", x)
1698 else if (s.u==B_LREP)
1699 PUT2("%.1f fbar1 %.1f rdots\n", x, x+10)
1700 else if (s.u==B_RREP) {
1701 PUT2("%.1f fbar2 %.1f rdots\n", x, x-10)
1702 }
1703 else if (s.u==B_DREP) {
1704 PUT2("%.1f fbar1 %.1f rdots\n", x-1, x+9)
1705 PUT2("%.1f fbar2 %.1f rdots\n", x+1, x-9)
1706 }
1707 else if (s.u==B_FAT1)
1708 PUT1("%.1f fbar1\n", x)
1709 else if (s.u==B_FAT2)
1710 PUT1("%.1f fbar2\n", x)
1711 else if (s.u==B_INVIS)
1712 ;
1713 else
1714 printf (">>> dont know how to draw bar type %d\n", s.u);
1715
1716 PUT0("\n")
1717
1718 }
1719
1720
1721 /* ----- draw_barnums ------- */
1722 void draw_barnums (fp)
1723 FILE *fp;
1724 {
1725 int i,last,ok,got_note;
1726
1727 last=0;
1728 got_note=0;
1729 for (i=0;i<nsym;i++) {
1730 if ((sym[i].type==NOTE)||(sym[i].type==REST)) got_note=1;
1731
1732 if ((sym[i].type==BAR) && (strlen(sym[i].text)>0)) {
1733 if (last != 2) set_font (fp, cfmt.barlabelfont, 0);
1734 PUT3 (" %.1f %.1f M (%s) cshow ", sym[i].x, BNUMHT, sym[i].text)
1735 last=2;
1736 }
1737
1738 if ((sym[i].type==BAR) && sym[i].t) {
1739 ok=0;
1740 if ((cfmt.barnums>0) && (sym[i].t%cfmt.barnums==0)) ok=1;
1741 if ((cfmt.barnums==0) && (!got_note)) ok=1;
1742 if ((cfmt.barnums!=0) && ((strlen(sym[i].text)>0))) ok=0;
1743
1744 if (ok) {
1745 if (last != 1) set_font (fp, cfmt.barnumfont, 0);
1746 /*| if ((mvoice>1) && (cfmt.barnums==0)) |*/
1747 if (cfmt.barnums==0)
1748 PUT1 (" 0 38 M (%d) rshow ", sym[i].t)
1749 else
1750 PUT3 (" %.1f %.1f M (%d) cshow ", sym[i].x, BNUMHT, sym[i].t)
1751 last=1;
1752 }
1753 }
1754 }
1755 PUT0("\n");
1756
1757 }
1758
1759
1760 /* ----- update_endings: remember where to draw endings ------- */
1761 void update_endings (x,s)
1762 struct SYMBOL s;
1763 float x;
1764 {
1765 int i;
1766
1767 if (num_ending>0) {
1768 i=num_ending-1;
1769 if (ending[i].num==1)
1770 mes1++;
1771 else {
1772 mes2++;
1773 if (mes2==mes1) ending[i].b=x;
1774 }
1775 }
1776
1777 if (s.v) {
1778 if (num_ending>0)
1779 if (ending[num_ending-1].num==1) ending[num_ending-1].b=x-3;
1780 ending[num_ending].a=x;
1781 ending[num_ending].b=-1;
1782 ending[num_ending].num=s.v;
1783 if (s.v==1) mes1=0;
1784 else mes2=0;
1785 num_ending++;
1786 }
1787
1788 }
1789
1790
1791
1792 /* ----- set_ending: determine limits of ending box ------- */
1793 void set_ending (i)
1794 int i;
1795 {
1796 int num,j,j0,j1,mes,mesmax;
1797 float top;
1798
1799 num=sym[i].v;
1800 mesmax=0;
1801 if (num==2) mesmax=mes1;
1802
1803 mes=0;
1804 j0=j1=-1;
1805 for (j=i+1;j<nsym;j++) {
1806 if (sym[j].type==BAR) {
1807 if (sym[j].u!=B_INVIS) mes++;
1808 if (mes==1) j1=j;
1809 if (sym[j].u==B_RREP || sym[j].u==B_DREP || sym[j].u==B_FAT2 ||
1810 sym[j].u==B_LREP || sym[j].u==B_FAT1 || sym[j].v>0) {
1811 j0=j;
1812 break;
1813 }
1814 if (mes==mesmax) {
1815 j0=j;
1816 break;
1817 }
1818 }
1819 }
1820 top=-1;
1821 if (j0==-1) j0=j1;
1822 if (j0>=0) top=sym[j0].x;
1823
1824 ending[num_ending].num=num;
1825 ending[num_ending].a=sym[i].x;
1826 ending[num_ending].b=top;
1827 if (num==1) ending[num_ending].b=top-3;
1828 ending[num_ending].type=E_CLOSED;
1829 if (sym[j0].type==BAR && sym[j0].u==B_SNGL) ending[num_ending].type=E_…
1830 num_ending++;
1831
1832 if (num==1) mes1=mes;
1833 if (num==2) mes1=0;
1834
1835 }
1836
1837
1838 /* ----- draw_endings ------- */
1839 void draw_endings ()
1840 {
1841 int i;
1842
1843 for (i=0;i<num_ending;i++) {
1844 if (ending[i].b<0)
1845 PUT3("%.1f %.1f (%d) end2\n",
1846 ending[i].a, ending[i].a+50, ending[i].num)
1847 else {
1848 if (ending[i].type==E_CLOSED) {
1849 PUT3("%.1f %.1f (%d) end1\n",
1850 ending[i].a, ending[i].b, ending[i].num)
1851 }
1852 else {
1853 PUT3("%.1f %.1f (%d) end2\n",
1854 ending[i].a, ending[i].b, ending[i].num)
1855 }
1856 }
1857 }
1858 num_ending=0;
1859
1860 }
1861
1862 /* ----- draw_rest ----- */
1863 void draw_rest (x,yy,s,gchy)
1864 struct SYMBOL s;
1865 float x,yy;
1866 float *gchy;
1867 {
1868
1869 int y,i,k,deco;
1870 float dotx,doty;
1871
1872 *gchy=38;
1873 if (s.invis) return;
1874
1875 y=(int) s.y;
1876 PUT2("%.2f %.0f", x, yy)
1877
1878 if (s.head==H_OVAL) PUT0(" r1")
1879 else if (s.head==H_EMPTY) PUT0(" r2")
1880 else {
1881 if (s.flags==0) PUT0(" r4")
1882 else if (s.flags==1) PUT0(" r8")
1883 else if (s.flags==2) PUT0(" r16")
1884 else if (s.flags==3) PUT0(" r32")
1885 else PUT0(" r64")
1886 }
1887
1888 if (y%6) { dotx=6.5; doty=0; } /* dots */
1889 else { dotx=6.5; doty=3; }
1890 if (s.head==H_OVAL) { dotx=8; doty=-3; }
1891 if (s.head==H_EMPTY) { dotx=8; doty=3; }
1892 for (i=0;i<s.dots;i++) {
1893 PUT2(" %.1f %.1f dt", dotx, doty)
1894 dotx=dotx+3.5;
1895 }
1896
1897
1898 for (k=s.dc.n-1;k>=0;k--) {
1899 deco=s.dc.t[k];
1900 if (deco==D_HOLD) PUT1(" %.1f hld", 27.0)
1901 }
1902
1903 PUT0("\n")
1904 }
1905
1906 /* ----- draw_gracenotes ----- */
1907 void draw_gracenotes (x,w,d,s)
1908 struct SYMBOL *s;
1909 float x,w,d;
1910 {
1911 int i,n,y,acc,ii,m;
1912 float xg[20],yg[20],lg,px[20],py[20],xx,yy;
1913 float s1,sx,sy,sxx,sxy,a,b,delta,lmin;
1914 float x0,y0,x1,y1,x2,y2,x3,y3,bet1,bet2,dy1,dy2,dx,dd,fac,facx;
1915
1916 n=s->gr.n;
1917 if (n==0) return;
1918
1919 facx=0.3;
1920 fac=d/w-1;
1921 if (fac<0) fac=0;
1922 fac=1+(fac*facx)/(fac+facx);
1923
1924 dx=0;
1925 for (m=0;m<s->npitch;m++) { /* room for accidentals */
1926 dd=-s->shhd[m];
1927 if (s->accs[m]) dd=-s->shhd[m]+s->shac[m];
1928 if ((s->accs[m]==A_FT)||(s->accs[m]==A_NT)) dd=dd-2;
1929 if (dx<dd) dx=dd;
1930 }
1931
1932 xx=x-fac*(dx+GSPACE0);
1933 for (i=n-1;i>=0;i--) { /* set note positions */
1934 yg[i]=3*(s->gr.p[i]-18)+s->yadd;
1935 if (i==n-1) { /* some subtle shifts.. */
1936 if(yg[i]>=s->ymx) xx=xx+1; /* gnote above a bit clos…
1937 if((yg[i]<s->ymn-7)&&(n==1)) xx=xx-2; /* below with flag further…
1938 }
1939
1940 if (i<n-1) {
1941 if (yg[i]>yg[i+1]+8) xx=xx+fac*1.8;
1942 }
1943
1944 xg[i]=xx;
1945 xx=xx-fac*GSPACE;
1946 if (s->gr.a[i]) xx=xx-3.5;
1947 }
1948
1949 if (n>1) {
1950 s1=sx=sy=sxx=sxy=0; /* linear fit through stems */
1951 for (i=0;i<n;i++) {
1952 px[i]=xg[i]+GSTEM_XOFF;
1953 py[i]=yg[i]+GSTEM;
1954 s1 += 1; sx += px[i]; sy += py[i];
1955 sxx += px[i]*px[i]; sxy += px[i]*py[i];
1956 }
1957 delta=s1*sxx-sx*sx; /* beam fct: y=ax+b */
1958 a=(s1*sxy-sx*sy)/delta;
1959 if (a>BEAM_SLOPE) a=BEAM_SLOPE;
1960 if (a<-BEAM_SLOPE) a=-BEAM_SLOPE;
1961 b=(sy-a*sx)/s1;
1962
1963 if (bagpipe) { a=0; b=35; }
1964
1965 lmin=100; /* shift to get min stems */
1966 for (i=0;i<n;i++) {
1967 px[i]=xg[i]+GSTEM_XOFF;
1968 py[i]=a*px[i]+b;
1969 lg=py[i]-yg[i];
1970 if (lg<lmin) lmin=lg;
1971 }
1972 if (lmin<10) b=b+10-lmin;
1973 }
1974
1975 for (i=0;i<n;i++) { /* draw grace notes */
1976 if (n>1) {
1977 px[i]=xg[i]+GSTEM_XOFF;
1978 py[i]=a*px[i]+b;
1979 lg=py[i]-yg[i];
1980 PUT3("%.1f %.1f %.1f gnt ", xg[i],yg[i],lg)
1981 }
1982 else {
1983 lg=GSTEM;
1984 PUT3("%.1f %.1f %.1f gn1 ", xg[i],yg[i],lg)
1985 }
1986
1987 acc=s->gr.a[i];
1988 if (acc==A_SH) PUT2("%.1f %.1f gsh0 ",xg[i]-4.5,yg[i])
1989 if (acc==A_FT) PUT2("%.1f %.1f gft0 ",xg[i]-4.5,yg[i])
1990 if (acc==A_NT) PUT2("%.1f %.1f gnt0 ",xg[i]-4.5,yg[i])
1991 if (acc==A_DS) PUT2("%.1f %.1f gds0 ",xg[i]-4.5,yg[i])
1992 if (acc==A_DF) PUT2("%.1f %.1f gdf0 ",xg[i]-4.5,yg[i])
1993
1994 y = (int)yg[i]; /* helper lines */
1995 if (y<=-6) {
1996 if (y%6) PUT2("%.1f %d ghl ",xg[i], y+3)
1997 else PUT2("%.1f %d ghl ",xg[i], y)
1998 }
1999 if (y>=30) {
2000 if (y%6) PUT2("%.1f %d ghl ",xg[i], y-3)
2001 else PUT2("%.1f %d ghl ",xg[i], y)
2002 }
2003 }
2004
2005 if (n>1) /* beam */
2006 if (bagpipe)
2007 PUT4("%.1f %.1f %.1f %.1f gbm3 ", px[0],py[0],px[n-1],py[n-1])
2008 else
2009 PUT4("%.1f %.1f %.1f %.1f gbm2 ", px[0],py[0],px[n-1],py[n-1])
2010
2011
2012 bet1=0.2; /* slur */
2013 bet2=0.8;
2014 yy=1000;
2015 for (i=n-1;i>=0;i--) if (yg[i]<=yy) {yy=yg[i]; ii=i;}
2016 x0=xg[ii];
2017 y0=yg[ii]-5;
2018 if (ii>0) { x0=x0-4; y0=y0+1; }
2019 x3=x-1;
2020 y3=s->ymn-5;
2021 dy1=(x3-x0)*0.4;
2022 if (dy1>3) dy1=3;
2023 dy2=dy1;
2024
2025 if (yg[ii]>s->ymn+7){
2026 x0=xg[ii]-1;
2027 y0=yg[ii]-4.5;
2028 y3=s->ymn+1.5;
2029 x3=x-dx-5.5;
2030 dy2=(y0-y3)*0.2;
2031 dy1=(y0-y3)*0.8;
2032 bet1=0.0;
2033 }
2034
2035 if (y3>y0+4) {
2036 y3=y0+4;
2037 x0=xg[ii]+2;
2038 y0=yg[ii]-4;
2039 }
2040
2041 x1=bet1*x3+(1-bet1)*x0;
2042 y1=bet1*y3+(1-bet1)*y0-dy1;
2043 x2=bet2*x3+(1-bet2)*x0;
2044 y2=bet2*y3+(1-bet2)*y0-dy2;
2045
2046 PUT4(" %.1f %.1f %.1f %.1f", x1,y1,x2,y2);
2047 PUT4(" %.1f %.1f %.1f %.1f gsl\n", x3,y3,x0,y0);
2048
2049 }
2050
2051 /* ----- draw_basic_note: draw m-th head with accidentals and dots -- */
2052 void draw_basic_note (x,w,d,s,m)
2053 struct SYMBOL *s;
2054 float x,w,d;
2055 int m;
2056 {
2057 int y,i,yy;
2058 float dotx,doty,xx,dx,avail,add,fac;
2059
2060 y=3*(s->pits[m]-18)+s->yadd; /* height on staff */
2061
2062 xx=x+s->shhd[m]; /* draw head */
2063 PUT2("%.1f %d", xx, y)
2064 if (s->head==H_OVAL) PUT0(" HD")
2065 if (s->head==H_EMPTY) PUT0(" Hd")
2066 if (s->head==H_FULL) PUT0(" hd")
2067 if (s->shhd[m]) {
2068 yy=0;
2069 if (y>=30) { yy=y; if (yy%6) yy=yy-3; }
2070 if (y<=-6) { yy=y; if (yy%6) yy=yy+3; }
2071 if (yy) PUT1(" %d hl", yy)
2072 }
2073
2074 if (s->dots) { /* add dots */
2075 if (y%6) { dotx=8; doty=0; }
2076 else { dotx=8; doty=3; }
2077 if (s->stem==-1)
2078 dotx=dotx+s->xmx-s->shhd[m];
2079 else
2080 dotx=dotx+s->xmx-s->shhd[m];
2081 if (s->dots && s->flags && (s->stem==1) && !(y%6))
2082 if ((s->word_st==1) && (s->word_end==1) && (s->npitch==1))
2083 dotx=dotx+DOTSHIFT;
2084 if (s->head==H_EMPTY) dotx=dotx+1;
2085 if (s->head==H_OVAL) dotx=dotx+2;
2086 for (i=0;i<s->dots;i++) {
2087 PUT2(" %.1f %.1f dt", dotx, doty)
2088 dotx=dotx+3.5;
2089 }
2090 }
2091
2092 if (s->accs[m]) { /* add accidentals */
2093 fac=1.0;
2094 avail=d-w-3;
2095 add=0.3*avail;
2096 fac=1+add/s->wl;
2097 if (fac<1) fac=1;
2098 if (fac>1.2) fac=1.2;
2099 dx=fac*s->shac[m];
2100 if (s->accs[m]==A_SH) PUT1(" %.1f sh", dx)
2101 if (s->accs[m]==A_NT) PUT1(" %.1f nt", dx)
2102 if (s->accs[m]==A_FT) PUT1(" %.1f ft", dx)
2103 if (s->accs[m]==A_DS) PUT1(" %.1f dsh", dx)
2104 if (s->accs[m]==A_DF) PUT1(" %.1f dft", dx)
2105 }
2106 }
2107
2108
2109 /* ----- draw_decorations ----- */
2110 float draw_decorations (x,s,tp)
2111 struct SYMBOL *s;
2112 float x;
2113 float *tp;
2114 {
2115 int y,sig,k,deco,m;
2116 float yc,xc,y1,top,top1,dx,dy;
2117
2118
2119 top=-1000;
2120 for (k=s->dc.n-1;k>=0;k--) { /* decos close to head */
2121 deco=s->dc.t[k];
2122
2123 /* if ((deco==D_STACC)||(deco==D_EMBAR)) { */ /* dot or bar mark */
2124 if (deco==D_STACC) { /* dot */
2125 sig=1; if (s->stem==1) sig=-1;
2126 y=s->y+6*sig;
2127 if (y<top+3) y=top+3;
2128 if (!(y%6) && (y>=0) && (y<=24)) y+=3*sig;
2129 if (top<y) top=y;
2130 if (deco==D_STACC) PUT1(" %d stc",y)
2131 else PUT1(" %d emb",y)
2132 }
2133
2134 if (deco==D_SLIDE) { /* slide */
2135 yc=s->ymn;
2136 xc=5;
2137 for (m=0;m<s->npitch;m++) {
2138 dx=5-s->shhd[m];
2139 if (s->head==H_OVAL) dx=dx+2.5;
2140 if (s->accs[m]) dx=4-s->shhd[m]+s->shac[m];
2141 dy=3*(s->pits[m]-18)+s->yadd-yc;
2142 if ((dy<10) && (dx>xc)) xc=dx;
2143 }
2144 yc=s->ymn;
2145 PUT2(" %.1f %.1f sld", yc, xc)
2146 }
2147 }
2148
2149 top1=top;
2150 for (k=s->dc.n-1;k>=0;k--) { /* decos further away */
2151 deco=s->dc.t[k];
2152
2153 if (deco==D_EMBAR) { /* bar */
2154 yc=s->ymx+6;
2155 if (s->stem==1) yc=s->ys+4;
2156 if (yc<28) yc=28;
2157 if (yc<top+3) yc=top+3;
2158 if (top<yc+2) top=yc+2;
2159 PUT1(" %.2f emb", yc)
2160 }
2161
2162 if ((deco==D_GRACE)||(deco==D_HAT)||(deco==D_ATT)) { /* gracing,hat,…
2163 yc=s->ymx+9;
2164 if (s->stem==1) yc=s->ys+5;
2165 if (yc<30) yc=30;
2166 if (yc<top+4) yc=top+4;
2167 if (top<yc+2) top=yc+2;
2168 if (deco==D_GRACE) PUT1(" %.2f grm", yc)
2169 else if (deco==D_HAT) PUT1(" %.2f hat", yc)
2170 else PUT1(" %.2f att", yc)
2171 }
2172
2173 if (deco==D_ROLL) { /* roll sign */
2174 y=s->y;
2175 if (s->stem==1) {
2176 yc=s->y-5;
2177 if (yc>-2) yc=-2;
2178 PUT1(" %.2f cpd", yc)
2179 }
2180 else {
2181 yc=s->y+5;
2182 if (s->dots && (!(y%6))) yc=s->y+6;
2183 if (yc<26) yc=26;
2184 if (yc<top+1) yc=top+1;
2185 if (top<yc+8) top=yc+8;
2186 PUT1(" %.2f cpu", yc)
2187 }
2188 }
2189
2190 if (deco==D_HOLD) { /* hold sign */
2191 yc=27;
2192 if (s->stem==1)
2193 y1=s->ys+4;
2194 else
2195 y1=s->ymx+6;
2196 if (yc<y1) yc=y1;
2197 if (yc<top+4) yc=top+4;
2198 if (top<yc+12) top=yc+12;
2199 PUT1(" %.1f hld", yc)
2200 }
2201
2202 if (deco==D_TRILL) { /* trill sign */
2203 yc=30;
2204 if (s->stem==1)
2205 y1=s->ys+5;
2206 else
2207 y1=s->ymx+7;
2208 if (yc<y1) yc=y1;
2209 if (yc<top+1) yc=top+1;
2210 if (top<yc+8) top=yc+8;
2211 PUT1(" %.1f trl", yc)
2212 }
2213
2214 if ((deco==D_UPBOW)||(deco==D_DOWNBOW)) { /* bowing signs */
2215 yc=21;
2216 if (s->stem==1)
2217 y1=s->ys+4;
2218 else
2219 y1=s->ymx+8;
2220 if (yc<y1) yc=y1;
2221 if (yc<top+4) yc=top+4;
2222 if (top<yc+10) top=yc+10;
2223 if (deco==D_UPBOW) PUT1(" %.1f upb", yc)
2224 if (deco==D_DOWNBOW) PUT1(" %.1f dnb", yc)
2225 }
2226 }
2227 *tp=top;
2228 return top1;
2229 }
2230
2231
2232 /* ----- draw_note ----- */
2233 float draw_note (x,w,d,s,fl,gchy)
2234 struct SYMBOL *s;
2235 float x,w,d;
2236 float *gchy;
2237 int fl;
2238 {
2239 char c,cc;
2240 int y,i,m,k;
2241 float yc,slen,slen0,top,top2,xx;
2242 slen0=STEM;
2243
2244 draw_gracenotes (x, w, d, s); /* draw grace notes */
2245
2246 c = 'd'; cc='u';
2247 if (s->stem==1) { c='u'; cc='d'; }
2248 slen=s->stem*(s->ys-s->y);
2249
2250 for (m=0;m<s->npitch;m++) {
2251 if (m>0) PUT0(" ")
2252 draw_basic_note (x,w,d,s,m); /* draw note heads */
2253 xx=3*(s->pits[m]-18)+s->yadd-s->y;
2254 xx=xx*xx;
2255 if (xx<0.01) { /* add stem */
2256 if (s->stem) PUT2(" %.1f s%c",slen,c)
2257 if (fl && (s->flags>0)) /* add flags */
2258 PUT3(" %.1f f%d%c",slen,s->flags,c)
2259 }
2260 if ((m>0) && (s->pits[m]==s->pits[m-1])) { /* unions */
2261 if (s->stem) PUT2(" %.2f s%c",slen0,cc)
2262 if (s->flags>0)
2263 PUT3(" %.1f f%d%c",slen0,s->flags,cc)
2264 }
2265 }
2266
2267 top=draw_decorations (x,s,&top2); /* add decorations */
2268
2269 y = s->ymn; /* lower helper lines…
2270 if (y<=-6) {
2271 for (i=-6;i>=y;i=i-6) PUT1(" %d hl", i)
2272 if (s->head==H_OVAL) PUT0("1")
2273 }
2274 y = s->ymx; /* upper helper lines…
2275 if (y>=30) {
2276 for (i=30;i<=y;i=i+6) PUT1(" %d hl", i)
2277 if (s->head==H_OVAL) PUT0("1")
2278 }
2279
2280 *gchy=38;
2281 if (strlen(s->text)>0) { /* position guitar ch…
2282 yc=*gchy;
2283 if (yc<y+8) yc=y+8;
2284 if (yc<s->ys+4) yc=s->ys+4;
2285 for (k=0;k<s->dc.n;k++) {
2286 if ((s->dc.t[k]==D_GRACE) && (yc<y+12)) yc=y+12;
2287 }
2288 if (yc<top2) yc=top2;
2289 *gchy=yc;
2290 }
2291
2292 PUT0("\n")
2293
2294 return top;
2295
2296 }
2297
2298
2299 /* ----- vsh: up/down shift needed to get k*6 ----- */
2300 float vsh (x,dir)
2301 int dir;
2302 float x;
2303 {
2304 int ix,iy,ir;
2305 float x1,xx;
2306 x1=x*dir;
2307 ix=x1+600.999;
2308 ir=ix%6;
2309 iy=ix-600;
2310 if (ir>0) iy=iy+6-ir;
2311 xx=iy*dir;
2312 return xx-x;
2313 }
2314
2315
2316 /* ----- rnd3: up/down shift needed to get k*3 ----- */
2317 float rnd3(x)
2318 float x;
2319 {
2320 int ix,iy,ir;
2321 float xx;
2322
2323 ix=x+600.999-1.5;
2324 ir=ix%3;
2325 iy=ix-600;
2326 if (ir>0) iy=iy+3-ir;
2327 xx=iy;
2328 return xx-x;
2329 }
2330
2331
2332 /* ----- rnd6: up/down shift needed to get k*6 ----- */
2333 float rnd6(x)
2334 float x;
2335 {
2336 int ix,iy,ir;
2337 float xx;
2338
2339 ix=x+600.999-3.0;
2340 ir=ix%6;
2341 iy=ix-600;
2342 if (ir>0) iy=iy+6-ir;
2343 xx=iy;
2344 return xx-x;
2345 }
2346
2347
2348 /* ----- b_pos ----- */
2349 float b_pos (stem,flags,b)
2350 int stem,flags;
2351 float b;
2352 {
2353 float bb,d1,d2,add;
2354 float top,bot;
2355
2356 if (stem==1) {
2357 top=b;
2358 bot=b-(flags-1)*BEAM_SHIFT-BEAM_DEPTH;
2359 if (bot>26) return b;
2360 }
2361 else {
2362 bot=b;
2363 top=b+(flags-1)*BEAM_SHIFT+BEAM_DEPTH;
2364 if (top<-2) return b;
2365 }
2366
2367 d1=rnd6(top-BEAM_OFFSET);
2368 d2=rnd6(bot+BEAM_OFFSET);
2369 add=d1;
2370 if (d1*d1>d2*d2) add=d2;
2371 bb=b+add;
2372
2373 /* printf ("stem %d top %.1f, bot%.1f, choices %.1f %.1f => %.1f\n",
2374 stem, top,bot, d1,d2, add); */
2375 /* printf ("b_pos(%d) b=%.1f to %.1f\n", stem,b,bb); */
2376
2377 return bb;
2378 }
2379
2380
2381 /* ----- calculate_beam ----- */
2382 int calculate_beam (i0,bm)
2383 int i0;
2384 struct BEAM *bm;
2385 {
2386 int j,j1,j2,i,stem,notes,flags;
2387 float x,y,ys,a,b,max_stem_err,stem_err,min_stem,slen,yyg,yg,try;
2388 float s,sx,sy,sxx,sxy,syy,delta,hh,dev,dev2,a0;
2389
2390 j1=i0; /* find first and last note in beam */
2391 j2=-1;
2392 stem=sym[j1].stem;
2393 for (j=i0;j<nsym;j++)
2394 if (sym[j].word_end) {
2395 j2=j;
2396 break;
2397 }
2398 if (j2==-1) {
2399 return 0;
2400 }
2401
2402 notes=flags=0; /* set x positions, count notes and flag…
2403 for (j=j1;j<=j2;j++) {
2404 if(sym[j].type==NOTE) {
2405 sym[j].xs=sym[j].x+stem*STEM_XOFF;
2406 sym[j].stem=stem;
2407 if (sym[j].flags>flags) flags=sym[j].flags;
2408 notes++;
2409 }
2410 }
2411
2412 s=sx=sy=sxx=sxy=syy=0; /* linear fit through stem ends */
2413 for (j=j1;j<=j2;j++) if (sym[j].type==NOTE) {
2414 x=sym[j].xs;
2415 y=sym[j].ymx+STEM*stem;
2416 s += 1; sx += x; sy += y;
2417 sxx += x*x; sxy += x*y; syy += y*y;
2418 }
2419
2420 delta=s*sxx-sx*sx; /* beam fct: y=ax+b */
2421 a=(s*sxy-sx*sy)/delta;
2422 b=(sy-a*sx)/s;
2423
2424 /* the next few lines modify the slope of the beam */
2425 if (notes>=3) {
2426 hh=syy-a*sxy-b*sy; /* flatten if notes not in line */
2427 dev=0;
2428 if (hh>0) {
2429 dev2=hh/(notes-2);
2430 if (dev2>0.5) a=BEAM_FLATFAC*a;
2431 }
2432 }
2433
2434
2435 if (a>=0) a=BEAM_SLOPE*a/(BEAM_SLOPE+a); /* max steepness for beam */
2436 else a=BEAM_SLOPE*a/(BEAM_SLOPE-a);
2437
2438
2439 /* to decide if to draw flat etc. use normalized slope a0 */
2440 a0=a*(sym[j2].xs-sym[j1].xs)/(20*(notes-1));
2441
2442 if ((a0<BEAM_THRESH) && (a0>-BEAM_THRESH)) a=0; /* flat below threshh…
2443
2444 b=(sy-a*sx)/s; /* recalculate b for new slope */
2445
2446 /* if (flags>1) b=b+2*stem;*/ /* leave a bit more room if several …
2447
2448 if (bagpipe) { b=-11; a=0; }
2449
2450 max_stem_err=0; /* check stem lengths */
2451 for (j=j1;j<=j2;j++) if (sym[j].type==NOTE) {
2452 if (sym[j].npitch==1) {
2453 min_stem=STEM_MIN;
2454 if (sym[j].flags==2) min_stem=STEM_MIN2;
2455 if (sym[j].flags==3) min_stem=STEM_MIN3;
2456 if (sym[j].flags==4) min_stem=STEM_MIN4;
2457 }
2458 else {
2459 min_stem=STEM_CH_MIN;
2460 if (sym[j].flags==2) min_stem=STEM_CH_MIN2;
2461 if (sym[j].flags==3) min_stem=STEM_CH_MIN3;
2462 if (sym[j].flags==4) min_stem=STEM_CH_MIN4;
2463 }
2464 min_stem=min_stem+BEAM_DEPTH+BEAM_SHIFT*(sym[j].flags-1);
2465 ys=a*sym[j].xs+b;
2466 if (stem==1) slen=ys-sym[j].ymx;
2467 else slen=sym[j].ymn-ys;
2468 stem_err=min_stem-slen;
2469 if (stem_err>max_stem_err) max_stem_err=stem_err;
2470 }
2471
2472 if (max_stem_err>0) /* shift beam if stems too short…
2473 b=b+stem*max_stem_err;
2474
2475 for (j=j1+1;j<=j2;j++) if (sym[j].type==NOTE) { /* room for gracenote…
2476 for (i=0;i<sym[j].gr.n;i++) {
2477 yyg=a*(sym[j].x-GSPACE0)+b;
2478 yg=3*(sym[j].gr.p[i]-18)+sym[j].yadd;
2479 if (stem==1) {
2480 try=(yg+GSTEM)-(yyg-BEAM_DEPTH-2);
2481 if (try>0) b=b+try;
2482 }
2483 else {
2484 try=(yg)-(yyg+BEAM_DEPTH+7);
2485 if (try<0) b=b+try;
2486 }
2487 }
2488 }
2489
2490 if ((a<0.01) && (a>-0.01)) /* shift flat beams onto staff lines …
2491 b=b_pos (stem,flags,b);
2492
2493 for (j=j1;j<=j2;j++) if (sym[j].type==NOTE) { /* final stems */
2494 sym[j].ys=a*sym[j].xs+b;
2495 }
2496
2497 bm->i1=j1; /* save beam parameters in struct */
2498 bm->i2=j2;
2499 bm->a=a;
2500 bm->b=b;
2501 bm->stem=stem;
2502 bm->t=stem*BEAM_DEPTH;
2503 return 1;
2504 }
2505
2506
2507 /* ----- rest_under_beam ----- */
2508 float rest_under_beam (x,head,bm)
2509 float x;
2510 int head;
2511 struct BEAM *bm;
2512 {
2513 float y,tspace,bspace;
2514 int j1,j2,j,nf,iy;
2515
2516 tspace=9;
2517 bspace=11;
2518 if ((head==H_OVAL)||(head==H_EMPTY)) tspace=bspace=4;
2519
2520 j1=bm->i1;
2521 j2=bm->i2;
2522 nf=0;
2523 for (j=j1;j<=j2;j++)
2524 if ((sym[j].type==NOTE)||(sym[j].flags>nf)) nf=sym[j].flags;
2525
2526 if (bm->stem==1) {
2527 y=bm->a*x+bm->b;
2528 y=y-BEAM_DEPTH-(nf-1)*BEAM_SHIFT;
2529 y=y-tspace;
2530 if (y>12) y=12;
2531 }
2532 else {
2533 y=bm->a*x+bm->b;
2534 y=y+BEAM_DEPTH+(nf-1)*BEAM_SHIFT;
2535 y=y+bspace;
2536 if (y<12) y=12;
2537 }
2538
2539 if ((head==H_OVAL)||(head==H_EMPTY)) {
2540 iy=(y+3.0)/6.0;
2541 y=6*iy;
2542 }
2543
2544 return y;
2545 }
2546
2547 /* ----- draw_beam_num: draw number on a beam ----- */
2548 void draw_beam_num (bm,num,xn)
2549 struct BEAM *bm;
2550 int num;
2551 float xn;
2552 {
2553 float yn;
2554
2555 if (bm->stem==-1)
2556 yn=bm->a*xn+bm->b-12;
2557 else
2558 yn=bm->a*xn+bm->b+4;
2559
2560 PUT3("%.1f %.1f (%d) bnum\n", xn, yn, num)
2561
2562 }
2563
2564
2565 /* ----- draw_beam: draw a single beam ----- */
2566 void draw_beam (x1,x2,dy,bm)
2567 float x1,x2,dy;
2568 struct BEAM *bm;
2569 {
2570 float y1,y2;
2571
2572 y1=bm->a*x1+bm->b-bm->stem*dy;
2573 y2=bm->a*x2+bm->b-bm->stem*dy;
2574 PUT5("%.1f %.1f %.1f %.1f %.1f bm\n", x1,y1,x2,y2,bm->t)
2575 }
2576
2577 /* ----- draw_beams: draw the beams for one word ----- */
2578 void draw_beams (bm)
2579 struct BEAM *bm;
2580 {
2581 int j,j1,j2,j3,inbeam,k1,k2,num,p,r;
2582 float x1,x2,xn;
2583
2584 j1=bm->i1;
2585 j2=bm->i2;
2586
2587 /* make first beam over whole word */
2588 x1=sym[j1].xs;
2589 x2=sym[j2].xs;
2590 num=sym[j1].u;
2591
2592 for (j=j1;j<=j2;j++) { /* numbers for nplets on same beam */
2593 if (sym[j].p_plet>0) {
2594 p=sym[j].p_plet;
2595 r=sym[j].r_plet;
2596 j3=j+r-1;
2597 if (j3<=j2) {
2598 xn=0.5*(sym[j].xs+sym[j3].xs);
2599 draw_beam_num (bm,p,xn);
2600 sym[j].p_plet=0;
2601 }
2602 }
2603 }
2604
2605 draw_beam (x1,x2,0.0,bm);
2606
2607 /* second beams where two or more flags */
2608 k1=0;
2609 inbeam=0;
2610 for (j=j1;j<=j2;j++) {
2611 if (sym[j].type!=NOTE) continue;
2612 if ((!inbeam) && (sym[j].flags>=2)) {
2613 k1=j;
2614 inbeam=1;
2615 }
2616 if (inbeam && ((sym[j].flags<2) || (j==j2))) {
2617 if ((sym[j].flags>=2) && (j==j2)) k2=j;
2618 x1=sym[k1].xs;
2619 x2=sym[k2].xs;
2620 inbeam=0;
2621 if (k1==k2) {
2622 if (k1==j1) draw_beam (x1+BEAM_STUB,x1,BEAM_SHIFT,bm);
2623 else draw_beam (x1-BEAM_STUB,x1,BEAM_SHIFT,bm);
2624 }
2625 else
2626 draw_beam (x1,x2,BEAM_SHIFT,bm);
2627 inbeam=0;
2628 }
2629 k2=j;
2630 }
2631
2632 /* third beams where three or more flags */
2633 k1=0;
2634 inbeam=0;
2635 for (j=j1;j<=j2;j++) {
2636 if (sym[j].type!=NOTE) continue;
2637 if ((!inbeam) && (sym[j].flags>=3)) {
2638 k1=j;
2639 inbeam=1;
2640 }
2641 if (inbeam && ((sym[j].flags<3) || (j==j2))) {
2642 if ((sym[j].flags>=3) && (j==j2)) k2=j;
2643 x1=sym[k1].xs;
2644 x2=sym[k2].xs;
2645 inbeam=0;
2646 if (k1==k2) {
2647 if (k1==j1) draw_beam (x1+BEAM_STUB,x1,2*BEAM_SHIFT,bm);
2648 else draw_beam (x1-BEAM_STUB,x1,2*BEAM_SHIFT,bm);
2649 }
2650 else
2651 draw_beam (x1,x2,2*BEAM_SHIFT,bm);
2652 inbeam=0;
2653 }
2654 k2=j;
2655 }
2656
2657 /* fourth beams where four or more flags */
2658 k1=0;
2659 inbeam=0;
2660 for (j=j1;j<=j2;j++) {
2661 if (sym[j].type!=NOTE) continue;
2662 if ((!inbeam) && (sym[j].flags>=4)) {
2663 k1=j;
2664 inbeam=1;
2665 }
2666 if (inbeam && ((sym[j].flags<4) || (j==j2))) {
2667 if ((sym[j].flags>=4) && (j==j2)) k2=j;
2668 x1=sym[k1].xs;
2669 x2=sym[k2].xs;
2670 inbeam=0;
2671 if (k1==k2) {
2672 if (k1==j1) draw_beam (x1+BEAM_STUB,x1,3*BEAM_SHIFT,bm);
2673 else draw_beam (x1-BEAM_STUB,x1,3*BEAM_SHIFT,bm);
2674 }
2675 else
2676 draw_beam (x1,x2,3*BEAM_SHIFT,bm);
2677 inbeam=0;
2678 }
2679 k2=j;
2680 }
2681
2682 }
2683
2684 /* ----- extreme: return min or max, depending on s ----- */
2685 float extreme (s, a, b)
2686 float s,a,b;
2687 {
2688
2689 if (s>0) {
2690 if (a>b) return a;
2691 return b;
2692 }
2693 else {
2694 if (a<b) return a;
2695 return b;
2696 }
2697 }
2698
2699 /* ----- draw_bracket ----- */
2700 void draw_bracket (p,j1,j2)
2701 int p,j1,j2;
2702 {
2703 float x1,x2,y1,y2,xm,ym,s,s0,xx,yy,yx,dy;
2704 int j;
2705
2706 x1=sym[j1].x-4;
2707 x2=sym[j2].x+4;
2708 y1=sym[j1].ymx+10;
2709 y2=sym[j2].ymx+10;
2710
2711 if (sym[j1].stem==1) { y1=sym[j1].ys+4; x1=x1+3; }
2712 if (sym[j2].stem==1) { y2=sym[j2].ys+4; x2=x2+3; }
2713
2714 if (y1<30) y1=30;
2715 if (y2<30) y2=30;
2716
2717 xm=0.5*(x1+x2);
2718 ym=0.5*(y1+y2);
2719
2720 s=(y2-y1)/(x2-x1);
2721 s0=(sym[j2].ymx-sym[j1].ymx)/(x2-x1);
2722 if (s0>0) {
2723 if (s<0) s=0; if (s>s0) s=s0;
2724 }
2725 else {
2726 if (s>0) s=0; if (s<s0) s=s0;
2727 }
2728 if (s*s < 0.2*0.2) s=0; /* flat if below limit */
2729
2730
2731 dy=0; /* shift up bracket if needed */
2732 for (j=j1;j<=j2;j++) {
2733 if ((sym[j].type==NOTE) || (sym[j].type==REST)) {
2734 xx=sym[j].x;
2735 yy=ym+(xx-xm)*s;
2736 yx=sym[j].ymx+10;
2737 if (sym[j].stem==1) yx=sym[j].ys+5;
2738 if (yx-yy>dy) dy=yx-yy;
2739 }
2740 }
2741 ym=ym+dy;
2742 y1=ym+s*(x1-xm);
2743 y2=ym+s*(x2-xm);
2744
2745 /* shift up guitar chords, if needed */
2746 for (j=j1;j<=j2;j++) {
2747 if ((sym[j].type==NOTE) || (sym[j].type==REST)) {
2748 xx=sym[j].x;
2749 yy=ym+(xx-xm)*s;
2750 if (sym[j].gchy<yy+4) sym[j].gchy=yy+4;
2751 }
2752 }
2753
2754 xx=xm-6;
2755 yy=ym+s*(xx-xm);
2756 PUT4("%.1f %.1f %.1f %.1f hbr ", x1,y1,xx,yy)
2757
2758 xx=xm+6;
2759 yy=ym+s*(xx-xm);
2760 PUT4("%.1f %.1f %.1f %.1f hbr ", x2,y2,xx,yy)
2761
2762 yy=0.5*(y1+y2);
2763 PUT3("%.1f %.1f (%d) bnum\n", xm, yy-4, p)
2764
2765 }
2766
2767 /* ----- draw_nplet_brackets ----- */
2768 void draw_nplet_brackets ()
2769 {
2770 int i,j,k,p,r,c;
2771
2772 for (i=0;i<nsym;i++) {
2773 if ((sym[i].type==NOTE) || (sym[i].type==REST)) {
2774 if (sym[i].p_plet>0) {
2775 p=sym[i].p_plet;
2776 r=sym[i].r_plet;
2777 c=r;
2778 k=i;
2779 for (j=i;j<nsym;j++) {
2780 if ((sym[j].type==NOTE) || (sym[j].type==REST)) {
2781 c--;
2782 k=j;
2783 if (c==0) break;
2784 }
2785 }
2786 draw_bracket (p,i,k);
2787 }
2788 }
2789 }
2790 }
2791
2792
2793 /* ----- slur_direction: decide whether slur goes up or down --- */
2794 float slur_direction (k1,k2)
2795 int k1,k2;
2796 {
2797 float s;
2798 int i,are_stems,are_downstems,are_bars,y_max,notes;
2799
2800 are_stems=are_downstems=are_bars=0;
2801 notes=0;
2802 y_max=300;
2803 for (i=k1;i<=k2;i++) {
2804 if (sym[i].type==BAR) are_bars=1;
2805 if (sym[i].type==NOTE) {
2806 notes++;
2807 if (sym[i].stem != 0 ) are_stems=1;
2808 if (sym[i].stem == -1 ) are_downstems=1;
2809 if (sym[i].ymn<y_max) y_max=sym[i].ymn;
2810 }
2811 }
2812 s=-1;
2813 if (are_downstems) s=1;
2814 if (!are_stems) {
2815 s=1;
2816 if (y_max<12) s=-1;
2817 }
2818
2819 /* next line tries to put long phrasings on top */
2820 if (are_bars && (notes>5)) s=1;
2821
2822 return s;
2823 }
2824
2825 /* ----- output_slur: output slur -- --- */
2826 void output_slur (x1,y1,x2,y2,s,height,shift)
2827 float x1,y1,x2,y2,s,height,shift;
2828 {
2829 float alfa,beta,mx,my,xx1,yy1,xx2,yy2,dx,dy,dz,a,add;
2830
2831 alfa=0.3;
2832 beta=0.45;
2833
2834 /* for wide flat slurs, make shape more square */
2835 dy=y2-y1;
2836 if (dy<0) dy=-dy;
2837 dx=x2-x1;
2838 if (dx<0) dx=-dx;
2839 a=dy/dx;
2840 if ((a<0.7) && dx>40) {
2841 add=0.2*(dx-40)/100;
2842 alfa=0.3+add;
2843 if (alfa>0.7) alfa=0.7;
2844 }
2845
2846
2847 /* alfa, beta, and height determine Bezier control points pp1,pp2
2848 *
2849 * X====alfa===|===alfa=====X
2850 * / | \
2851 * pp1 | pp2
2852 * / height \
2853 * beta | beta
2854 * / | \
2855 * p1 m p2
2856 *
2857 */
2858
2859
2860 mx=0.5*(x1+x2);
2861 my=0.5*(y1+y2);
2862
2863 xx1=mx+alfa*(x1-mx);
2864 yy1=my+alfa*(y1-my)+height;
2865 xx1=x1+beta*(xx1-x1);
2866 yy1=y1+beta*(yy1-y1);
2867
2868 xx2=mx+alfa*(x2-mx);
2869 yy2=my+alfa*(y2-my)+height;
2870 xx2=x2+beta*(xx2-x2);
2871 yy2=y2+beta*(yy2-y2);
2872
2873 dx=0.03*(x2-x1);
2874 if (dx>10.0) dx=10.0;
2875 dy=1.0;
2876 dz=0.20;
2877 if (x2-x1>100) dz=dz+0.001*(x2-x1);
2878 if (dz>0.6) dz=0.6;
2879
2880 PUT4("%.1f %.1f %.1f %.1f ",
2881 xx2-dx, yy2+shift+s*dy, xx1+dx, yy1+shift+s*dy)
2882 PUT3("%.1f %.1f 0 %.1f ", x1,y1+shift+s*dz,s*dz)
2883 PUT4("%.1f %.1f %.1f %.1f ", xx1,yy1+shift,xx2,yy2+shift)
2884 PUT4("%.1f %.1f %.1f %.1f SL\n", x2,y2+shift, x1,y1+shift)
2885
2886
2887 /*PUT4("%.2f %.2f %.2f %.2f ", xx1,yy1+shift,xx2,yy2+shift)
2888 PUT4("%.2f %.2f %.2f %.2f sl\n", x2,y2+shift, x1,y1+shift)*/
2889
2890 return;
2891 }
2892
2893 /* ----- draw_slur (not a pretty routine, this) ----- */
2894 void draw_slur (k1,k2,nn,level)
2895 int k1,k2,level,nn;
2896 {
2897 float x01,x02,y01,y02;
2898 float x1,y1,x2,y2,yy,height,addx,addy;
2899 float s,shift,hmin,a;
2900 float x,y,z,h,dx,dy;
2901 int i;
2902
2903 s=slur_direction (k1,k2);
2904
2905 /* fix endpoints */
2906 if (sym[k1].type==NOTE) { /* here if k1 points to note */
2907 x01=sym[k1].x;
2908 yy=sym[k1].ymn; if (s>0) yy=sym[k1].ymx;
2909 y01=extreme(s,yy+s*6,sym[k1].ys+s*2);
2910 if (sym[k1].word_end) {
2911 yy=sym[k1].ymn; if (s>0) yy=sym[k1].ymx;
2912 y01=yy+s*6;
2913 if ((sym[k1].stem==1)&&(s==1)) x01=x01+4;
2914 }
2915 if ((s>0) && (y01<sym[k1].dc.top+2.5)) y01=sym[k1].dc.top+2.5;
2916 }
2917
2918 if (sym[k2].type==NOTE) { /* here if k2 points to note */
2919 x02=sym[k2].x;
2920 yy=sym[k2].ymn; if (s>0) yy=sym[k2].ymx;
2921 y02=extreme(s,yy+s*6,sym[k2].ys+s*2);
2922 if (sym[k2].word_st) {
2923 yy=sym[k2].ymn; if (s>0) yy=sym[k2].ymx;
2924 y02=yy+s*6;
2925 if ((sym[k2].stem==-1)&&(s==-1)) x02=x02-3;
2926 }
2927 if ((s>0) && (y02<sym[k2].dc.top+2.5)) y02=sym[k2].dc.top+2.5;
2928 }
2929
2930 if (sym[k1].type!=NOTE) {
2931 x01=sym[k1].x+sym[k1].wr;
2932 y01=y02+1.2*s;
2933 if (nn>1) {
2934 if(s==1) { if (y01<28) y01=28; }
2935 else { if (y01>-4) y01=-4; }
2936 }
2937 }
2938
2939 if (sym[k2].type!=NOTE) {
2940 x02=sym[k2].x;
2941 y02=y01+1.2*s;
2942 if (nn>1) {
2943 if (s==1) {if (y02<28) y02=28; }
2944 else {if (y02>-4) y02=-4; }
2945 }
2946 }
2947
2948 /* shift endpoints */
2949 addx=0.04*(x02-x01);
2950 if (addx>3.0) addx=3.0;
2951 addy=0.02*(x02-x01);
2952 if (addy>3.0) addy=3.0;
2953 x1 = x01+addx;
2954 x2 = x02-addx;
2955 y1=y01+s*addy;
2956 y2=y02+s*addy;
2957
2958 a=(y2-y1)/(x2-x1); /* slur steepness */
2959 if (a > SLUR_SLOPE) a= SLUR_SLOPE;
2960 if (a < -SLUR_SLOPE) a=-SLUR_SLOPE;
2961 if (a>0) {
2962 if (s == 1) y1=y2-a*(x2-x1);
2963 if (s == -1) y2=y1+a*(x2-x1);
2964 }
2965 else {
2966 if (s == -1) y1=y2-a*(x2-x1);
2967 if (s == 1) y2=y1+a*(x2-x1);
2968 }
2969
2970 /* for big vertical jump, shift endpoints */
2971 y=y2-y1; if (y>8) y=8; if (y<-8) y=-8;
2972 z=y; if(z<0) z=-z; dx=0.5*z; dy=0.3*z;
2973 if (y>0) {
2974 if (s==1) { x2=x2-dx; y2=y2-dy; }
2975 if (s==-1) { x1=x1+dx; y1=y1+dy; }
2976 }
2977 else {
2978 if (s==1) { x1=x1+dx; y1=y1-dy; }
2979 if (s==-1) { x2=x2-dx; y2=y2+dy; }
2980 }
2981
2982 h=0;
2983 for (i=k1+1; i<k2; i++)
2984 if (sym[i].type==NOTE) {
2985 x = sym[i].x;
2986 yy = sym[i].ymn; if (s>0) yy=sym[i].ymx;
2987 y = extreme (s, yy+6*s, sym[i].ys+2*s);
2988 z = (y2*(x-x1)+y1*(x2-x))/(x2-x1);
2989 h = extreme (s, h, y-z);
2990 }
2991
2992 y1=y1+0.4*h;
2993 y2=y2+0.4*h;
2994 h=0.6*h;
2995
2996 hmin=s*(0.03*(x2-x1)+8);
2997 if (nn>3) hmin=s*(0.12*(x2-x1)+12);
2998 height = extreme (s, hmin, 3.0*h);
2999 height = extreme (-s, height, s*50);
3000
3001 y=y2-y1; if (y<0) y=-y;
3002 if ((s==1) && (height< 0.8*y)) height=0.8*y;
3003 if ((s==-1) && (height>-0.8*y)) height=-0.8*y;
3004
3005 shift=3*s*level;
3006
3007 output_slur (x1,y1,x2,y2,s,height,shift);
3008
3009 return;
3010 }
3011
3012
3013 /* ----- prev_scut, next_scut: find place to terminate/start slur --- */
3014 int next_scut (i)
3015 int i;
3016 {
3017 int j,cut,ok;
3018
3019 cut=nsym-1;
3020 for (j=i+1;j<nsym;j++) {
3021 ok=0;
3022 if (sym[j].type==BAR) {
3023 if (sym[j].u==B_RREP) ok=1;
3024 if (sym[j].u==B_DREP) ok=1;
3025 if (sym[j].u==B_FAT1) ok=1;
3026 if (sym[j].u==B_FAT2) ok=1;
3027 if (sym[j].v==2) ok=1;
3028 }
3029 if(ok) {
3030 cut=j;
3031 break;
3032 }
3033 }
3034 return cut;
3035 }
3036
3037 int prev_scut(i)
3038 int i;
3039 {
3040 int j,cut,ok;
3041
3042 cut=-1;
3043 for (j=i;j>=0;j--) {
3044 ok=0;
3045 if (sym[j].type==BAR) {
3046 if (sym[j].u==B_LREP) ok=1;
3047 if (sym[j].u==B_DREP) ok=1;
3048 if (sym[j].u==B_FAT1) ok=1;
3049 if (sym[j].u==B_FAT2) ok=1;
3050 if (sym[j].v==2) ok=1;
3051 }
3052 if(ok) {
3053 cut=j;
3054 break;
3055 }
3056 }
3057
3058 if (cut==-1) { /* return sym before first note */
3059 cut=0;
3060 for (j=0;j<nsym;j++) {
3061 if((sym[j].type==REST) || (sym[j].type==NOTE)) {
3062 cut=j-1;
3063 break;
3064 }
3065 }
3066 }
3067
3068 return cut;
3069 }
3070
3071
3072 /* ----- draw_chord_slurs ----- */
3073 void draw_chord_slurs(k1,k2,nh1,nh2,nslur,mhead1,mhead2,job)
3074 int k1,k2,nh1,nh2,nslur,mhead1[MAXHD],mhead2[MAXHD],job;
3075 {
3076
3077 int i,pbot,ptop,m1,m2,p1,p2,y,cut;
3078 float s,x1,y1,x2,y2,height,shift,addx,addy;
3079
3080 if (nslur==0) return;
3081
3082 pbot=1000;
3083 ptop=-1000;
3084 for (i=0;i<sym[k1].npitch;i++) {
3085 p1=sym[k1].pits[i];
3086 if (p1<pbot) pbot=p1;
3087 if (p1>ptop) ptop=p1;
3088 }
3089
3090 for (i=0;i<nslur;i++) {
3091 m1=mhead1[i];
3092 m2=mhead2[i];
3093 p1=sym[k1].pits[m1];
3094 p2=sym[k2].pits[m2];
3095 s=slur_direction (k1,k2);
3096 if (p1==pbot) s=-1;
3097 if (p1==ptop) s=1;
3098
3099 x1=sym[k1].x;
3100 x2=sym[k2].x;
3101 if (job==2) {
3102 cut=next_scut(k1);
3103 x2=sym[cut].x;
3104 if (cut==k1) x2=x1+30;
3105 }
3106
3107 if (job==1) {
3108 cut=prev_scut(k1);
3109 x1=sym[cut].x;
3110 if (cut==k1) x2=x1-30;
3111 }
3112
3113 addx=0.04*(x2-x1);
3114 if (addx>3.0) addx=3.0;
3115 addy=0.02*(x2-x1);
3116 if (addy>3.0) addy=3.0;
3117
3118 x1=x1+3+addx;
3119 x2=x2-3-addx;
3120 if ((s==1) && (sym[k1].stem==1)) x1=x1+1.5;
3121 if ((s==-1) && (sym[k2].stem==-1)) x2=x2-1.5;
3122
3123 y=3*(p1-18)+sym[k1].yadd;
3124 y1=y2=y+s*(4+addy);
3125 y=3*(p2-18)+sym[k2].yadd;
3126 y2=y+s*(4+addy);
3127
3128 if ((s==1) && !(y%6) && (sym[k1].dots>0)) {
3129 y2=y1=y+s*(5.5+addy);
3130 x1=x1-2;
3131 x2=x2+2;
3132 }
3133 height=s*(0.04*(x2-x1)+5);
3134 shift=0;
3135 output_slur (x1,y1,x2,y2,s,height,shift);
3136 }
3137
3138 }
3139
3140
3141
3142 /* ----- draw_slurs: draw slurs/ties between neighboring notes/chords */
3143 void draw_slurs (k1,k2,job)
3144 int k1,k2,job;
3145 {
3146 int i,m1,m2;
3147 int mhead1[MAXHD],mhead2[MAXHD],nslur,nh1,nh2;
3148
3149 if (nbuf+100>BUFFSZ)
3150 rx ("PS output exceeds reserved space per staff",
3151 " -- increase BUFFSZ1");
3152
3153 nslur=0;
3154
3155 if (job==2) { /* half slurs from last note in line …
3156 nh1=sym[k1].npitch;
3157 for (i=1;i<=nh1;i++) {
3158 for (m1=0;m1<nh1;m1++) {
3159 if (sym[k1].sl1[m1]==i) {
3160 nslur=nslur+1;
3161 mhead1[nslur-1]=m1;
3162 }
3163 if (sym[k1].ti1[m1]) {
3164 nslur=nslur+1;
3165 mhead1[nslur-1]=m1;
3166 }
3167 }
3168 }
3169 draw_chord_slurs(k1,k1,nh1,nh1,nslur,mhead1,mhead1,job);
3170 return;
3171 }
3172
3173 if (job==1) { /* half slurs to first note in line */
3174 nh1=sym[k1].npitch;
3175 for (i=1;i<=nh1;i++) {
3176 for (m1=0;m1<nh1;m1++) {
3177 if (sym[k1].sl2[m1]==i) {
3178 nslur=nslur+1;
3179 mhead1[nslur-1]=m1;
3180 }
3181 if (sym[k1].ti2[m1]) {
3182 nslur=nslur+1;
3183 mhead1[nslur-1]=m1;
3184 }
3185 }
3186 }
3187 draw_chord_slurs(k1,k1,nh1,nh1,nslur,mhead1,mhead1,job);
3188 return;
3189 }
3190
3191 /* real 2-note case: set up list of slurs/ties to draw */
3192 if ((sym[k1].type==NOTE) && (sym[k2].type==NOTE)) {
3193 nh1=sym[k1].npitch;
3194 nh2=sym[k2].npitch;
3195
3196 for (m1=0;m1<nh1;m1++) {
3197 if (sym[k1].ti1[m1]) {
3198 for (m2=0;m2<nh2;m2++) {
3199 if (sym[k2].pits[m2]==sym[k1].pits[m1]) {
3200 nslur++;
3201 mhead1[nslur-1]=m1;
3202 mhead2[nslur-1]=m2;
3203 break;
3204 }
3205 }
3206 }
3207 }
3208
3209 for (i=1;i<=nh1;i++) {
3210 for (m1=0;m1<nh1;m1++) {
3211 if (sym[k1].sl1[m1]==i) {
3212 nslur++;
3213 mhead1[nslur-1]=m1;
3214 mhead2[nslur-1]=-1;
3215 for (m2=0;m2<nh2;m2++) {
3216 if (sym[k2].sl2[m2]==i) mhead2[nslur-1]=m2;
3217 }
3218 if (mhead2[nslur-1]==-1) nslur--;
3219 }
3220 }
3221 }
3222 }
3223
3224 draw_chord_slurs(k1,k2,nh1,nh2,nslur,mhead1,mhead2,job);
3225 }
3226
3227
3228
3229 /* ----- draw_phrasing: draw phrasing slur between two symbols --- */
3230 void draw_phrasing (k1,k2,level)
3231 int k1,k2,level;
3232 {
3233 int nn,i;
3234
3235 if (k1==k2) return;
3236 if (nbuf+100>BUFFSZ)
3237 rx ("PS output exceeds reserved space per staff",
3238 " -- increase BUFFSZ1");
3239 nn=0;
3240 for (i=k1;i<=k2;i++)
3241 if ((sym[i].type==NOTE)||(sym[i].type==REST)) nn++;
3242
3243 draw_slur (k1,k2,nn,level);
3244
3245 }
3246
3247 /* ----- draw_all_slurs: draw all slurs/ties between neighboring notes …
3248 void draw_all_slurs ()
3249 {
3250 int i,i1,i2;
3251
3252 i1=-1;
3253 for (i=0;i<nsym;i++) {
3254 if (sym[i].type==NOTE) {
3255 i1=i;
3256 break;
3257 }
3258 }
3259 if (i1<0) return;
3260 draw_slurs(i1,i1,1);
3261
3262 for (;;) {
3263 i2=-1;
3264 for (i=i1+1;i<nsym;i++) {
3265 if (sym[i].type==NOTE) {
3266 i2=i;
3267 break;
3268 }
3269 }
3270 if (i2<0) break;
3271 draw_slurs(i1,i2,0);
3272 i1=i2;
3273 }
3274
3275 draw_slurs(i1,i1,2);
3276
3277 }
3278
3279 /* ----- draw_all_phrasings: draw all phrasing slurs for one staff -----…
3280 void draw_all_phrasings ()
3281 {
3282 int i,j,k,cut,pass,num;
3283
3284 for (pass=0;;pass++) {
3285 num=0;
3286 for (i=0;i<nsym;i++) {
3287
3288 if (sym[i].slur_st) {
3289 k=-1; /* find matching slur end */
3290 for (j=i+1;j<nsym;j++) {
3291 if (sym[j].slur_st && (!sym[j].slur_end)) break;
3292 if (sym[j].slur_end) {
3293 k=j;
3294 break;
3295 }
3296 }
3297 if (k>=0) {
3298 cut=next_scut(i);
3299 if (cut<k) {
3300 draw_phrasing (i,cut,pass);
3301 cut=prev_scut(k);
3302 draw_phrasing (cut,k,pass);
3303 }
3304 else {
3305 draw_phrasing (i,k,pass);
3306 }
3307 num++;
3308 sym[i].slur_st--;
3309 sym[k].slur_end--;
3310 }
3311 }
3312 }
3313 if (num==0) break;
3314 }
3315
3316 /* do unbalanced slurs still left over */
3317
3318 for (i=0;i<nsym;i++) {
3319 if (sym[i].slur_end) {
3320 cut=prev_scut(i);
3321 draw_phrasing (cut,i,0);
3322 }
3323 if (sym[i].slur_st) {
3324 cut=next_scut(i);
3325 draw_phrasing (i,cut,0);
3326 }
3327 }
3328
3329 }
3330
3331 /* ----- check_bars1 ---------- */
3332 void check_bars1 (ip1,ip2)
3333 int ip1,ip2;
3334 {
3335 int v,i,j,k1,k2;
3336 float dx;
3337
3338 /* check for inelegant bar combinations within one line */
3339 i=j=ip1;
3340 for (;;) {
3341 if (xp[i].type==BAR && xp[j].type==BAR && i!=j) {
3342 dx=0;
3343 for (v=0;v<nvoice;v++) {
3344 k1=xp[j].p[v];
3345 k2=xp[i].p[v];
3346 if (k1>=0 && k2>=0) {
3347 if (symv[v][k1].u==B_RREP && symv[v][k2].u==B_LREP) {
3348 symv[v][k2].u=B_DREP;
3349 symv[v][k1].u=B_INVIS;
3350 dx=-4.0;
3351 }
3352 }
3353 }
3354 xp[i].x=xp[i].x+dx;
3355 }
3356 j=i;
3357 i=xp[i].next;
3358 if (i==ip2) break;
3359 }
3360
3361 }
3362
3363
3364 /* ----- check_bars2 ---------- */
3365 void check_bars2 (ip1,ip2)
3366 int ip1,ip2;
3367 {
3368 int i,ip,v;
3369
3370 /* check whether to split up last bar over two lines */
3371 ip=xp[ip2].prec;
3372 for (v=0;v<nvoice;v++) {
3373 strcpy(voice[v].insert_text,"");
3374 voice[v].insert_bnum = 0;
3375 voice[v].insert_space = 0;
3376 voice[v].insert_num = 0;
3377 voice[v].insert_btype = 0;
3378
3379 i=xp[ip].p[v];
3380 if (i>=0) {
3381 if (symv[v][i].type==BAR) {
3382 if (symv[v][i].u==B_LREP) {
3383 symv[v][i].u=B_SNGL;
3384 voice[v].insert_btype=B_LREP;
3385 voice[v].insert_num=0;
3386 }
3387 else if (symv[v][i].u==B_DREP) {
3388 symv[v][i].u=B_RREP;
3389 voice[v].insert_btype=B_LREP;
3390 voice[v].insert_num=0;
3391 }
3392 else if ((symv[v][i].u==B_RREP) && (symv[v][i].v!=0)) {
3393 voice[v].insert_btype=B_INVIS;
3394 voice[v].insert_num=symv[v][i].v;
3395 symv[v][i].v=0;
3396 }
3397 else if ((symv[v][i].u==B_SNGL) && (symv[v][i].v!=0)) {
3398 voice[v].insert_btype=B_INVIS;
3399 voice[v].insert_num=symv[v][i].v;
3400 symv[v][i].v=0;
3401 }
3402
3403 /* if number or label on last bar, move to next line */
3404 if (symv[v][i].t || (strlen(symv[v][i].text)>0)) {
3405 if (symv[v][i+1].type==BAR) {
3406 if (symv[v][i+1].t==0) symv[v][i+1].t=symv[v][i].t;
3407 if (strlen(symv[v][i+1].text)==0)
3408 strcpy(symv[v][i+1].text,symv[v][i].text);
3409 }
3410 else {
3411 if (!voice[v].insert_btype) voice[v].insert_btype=B_INVIS;
3412 voice[v].insert_space=symv[v][i].wr;
3413 voice[v].insert_bnum=symv[v][i].t;
3414 strcpy(voice[v].insert_text,symv[v][i].text);
3415 strcpy(symv[v][i].text,"");
3416 symv[v][i].t=0;
3417 }
3418 }
3419
3420
3421 }
3422 }
3423 }
3424
3425
3426 }
3427
3428
3429
3430 /* ----- draw_vocals ----- */
3431 void draw_vocals (fp,nwl,botnote,bspace,botpos)
3432 FILE *fp;
3433 float botnote,bspace;
3434 float *botpos;
3435 int nwl;
3436 {
3437 int i,hyflag,l,j;
3438 float x,x0,yword,lastx,spc,vfsize,w,swfac,lskip;
3439 char word[81],t[81];
3440
3441 if (nwl<=0) return;
3442 vfsize=cfmt.vocalfont.size;
3443 lskip=1.1*vfsize;
3444 set_font (fp, cfmt.vocalfont, 0);
3445 yword=-cfmt.vocalspace;
3446 swfac=1.05;
3447 if (strstr(cfmt.vocalfont.name,"Helvetica")) swfac=1.10;
3448 if (botnote-cfmt.vocalfont.size<yword)
3449 yword=botnote-cfmt.vocalfont.size;
3450
3451 for (j=0;j<nwl;j++) {
3452 hyflag=0;
3453 lastx=-10;
3454 for (i=0;i<nsym;i++) {
3455 if (sym[i].wordp[j]) {
3456 strcpy(word,sym[i].wordp[j]);
3457 x0=sym[i].x;
3458 l=strlen(word);
3459
3460 if (hyflag) {
3461 tex_str (word,t,&w);
3462 spc=x0-VOCPRE*vfsize*swfac*w-lastx;
3463 x = lastx+0.5*spc-0.5*swfac*vfsize*cwid('-');
3464 PUT2("%.1f %.1f whf ",x,yword)
3465 hyflag=0;
3466 }
3467
3468 if ((l>1) && (word[l-1]=='^')) {
3469 word[l-1]='\0';
3470 hyflag=1;
3471 }
3472
3473 if ((l==1) && (word[0]=='_')) {
3474 if (lastx<0) lastx=sym[i-1].x+sym[i-1].wr;
3475 PUT3("%.1f %.1f %.1f wln ", lastx+3, sym[i].x+1, yword)
3476 }
3477 else if ((l==1) && (word[0]=='^')) {
3478 PUT2("%.1f %.1f whf ", x0, yword)
3479 lastx=x0+vfsize*swfac*w;
3480 }
3481 else {
3482 tex_str (word,t,&w);
3483 if (isdig(word[0]))
3484 x0=x0-3*vfsize*swfac*cwid('1');
3485 else
3486 x0=x0-VOCPRE*vfsize*swfac*w;
3487 if (strcmp(t," ")) PUT3("(%s) %.1f %.1f wd ", t, x0, yword)
3488 lastx=x0+vfsize*swfac*w;
3489 }
3490 }
3491 }
3492 if (hyflag) PUT2("%.1f %.1f whf ",lastx+5,yword)
3493 yword=yword-lskip;
3494 }
3495 *botpos=yword + lskip - bspace;
3496 }
3497
3498 /* ----- draw_symbols: draw symbols at proper positions on staff ----- */
3499 void draw_symbols (fp,bspace,bpos,is_top)
3500 FILE *fp;
3501 float bspace,*bpos;
3502 int is_top;
3503 {
3504 int i,inbeam,j,nwl;
3505 float x,y,top,xl,d,w,gchy,botnote,botpos,spc,swfac;
3506 struct BEAM bm;
3507 char t[81];
3508
3509 inbeam=do_words=0;
3510 botnote=0;
3511 nwl=0;
3512 for (i=0;i<nsym;i++) { /* draw the symbols */
3513
3514 for (j=0;j<NWLINE;j++)
3515 if (sym[i].wordp[j]) {
3516 if (j+1>nwl) nwl=j+1;
3517 }
3518 if (nbuf+100>BUFFSZ)
3519 rx ("PS output exceeds reserved space per staff",
3520 " -- increase BUFFSZ1");
3521 x=sym[i].x;
3522
3523 switch (sym[i].type) {
3524
3525 case NOTE:
3526 xl=0; w=sym[i].wl;
3527 if (i>0) { xl=sym[i-1].x; w=w+sym[i-1].wr; }
3528 d=x-xl;
3529
3530 if (sym[i].word_st && !sym[i].word_end) {
3531 if (calculate_beam (i,&bm)) inbeam=1;
3532 }
3533 if (inbeam) {
3534 top=draw_note(x,w,d,&sym[i],0,&gchy);
3535 if (i==bm.i2) {
3536 inbeam=0;
3537 draw_beams (&bm);
3538 }
3539 }
3540 else {
3541 top=draw_note(x,w,d,&sym[i],1,&gchy);
3542 }
3543 sym[i].gchy=gchy;
3544 sym[i].dc.top=top;
3545 if (sym[i].ymn-5<botnote) botnote=sym[i].ymn-5;
3546 break;
3547
3548 case REST:
3549 y=sym[i].y;
3550 if (inbeam) y=rest_under_beam (sym[i].x,sym[i].head,&bm);
3551 draw_rest(x,y,sym[i],&gchy);
3552 sym[i].gchy=gchy;
3553 break;
3554
3555 case BAR:
3556 if (sym[i].v) set_ending(i);
3557 draw_bar (x,sym[i]);
3558 break;
3559
3560 case CLEF:
3561 if (sym[i].u==TREBLE) {
3562 if (sym[i].v) PUT1("%.1f stclef\n", x)
3563 else PUT1("%.1f tclef\n", x)
3564 }
3565 else if (sym[i].u==BASS) {
3566 if (sym[i].v) PUT1("%.1f sbclef\n", x)
3567 else PUT1("%.1f bclef\n", x)
3568 }
3569 else if (sym[i].u==ALTO) {
3570 if (sym[i].v) PUT1("%.1f scclef\n", x)
3571 else PUT1("%.1f cclef\n", x)
3572 }
3573 else
3574 bug("unknown clef type", 0);
3575 voice[ivc].key.ktype=sym[i].u;
3576 break;
3577
3578 case TIMESIG:
3579 draw_timesig (x,sym[i]);
3580 break;
3581
3582 case KEYSIG:
3583 voice[ivc].key.sf=draw_keysig (x,sym[i]);
3584 break;
3585
3586 case INVISIBLE:
3587 break;
3588
3589 default:
3590 printf (">>> cannot draw symbol type %d\n", sym[i].type);
3591 }
3592 }
3593
3594 draw_nplet_brackets ();
3595
3596 /*| if (voice[ivc].do_gch) draw_barnums (fp); |*/
3597
3598
3599 if (ivc==ivc0) draw_barnums (fp);
3600
3601
3602 /* draw guitar chords */
3603 if (voice[ivc].do_gch) {
3604 set_font(fp,cfmt.gchordfont,0);
3605 swfac=1.0;
3606 if (strstr(cfmt.gchordfont.name,"Times-Roman")) swfac=1.00;
3607 if (strstr(cfmt.gchordfont.name,"Times-Bold")) swfac=1.05;
3608 if (strstr(cfmt.gchordfont.name,"Helvetica")) swfac=1.10;
3609 if (strstr(cfmt.gchordfont.name,"Helvetica-Bold")) swfac=1.15;
3610
3611 for (i=0;i<nsym;i++) {
3612 if ((sym[i].type==NOTE)||(sym[i].type==REST)) {
3613 if (strlen(sym[i].text)>0) {
3614 tex_str (sym[i].text,t,&w);
3615 w=cfmt.gchordfont.size*w;
3616 spc=w*GCHPRE;
3617 if (spc>8.0) spc=8.0;
3618 PUT3("%.1f %.1f (%s) gc ", sym[i].x-spc, sym[i].gchy, t)
3619 }
3620 }
3621 }
3622 }
3623
3624
3625 draw_all_slurs ();
3626 draw_all_phrasings ();
3627
3628 /*| if (is_top) draw_endings (); |*/
3629 if (ivc==ivc0) draw_endings ();
3630 num_ending=0;
3631
3632 botpos=-bspace;
3633 if (botnote<botpos) botpos=botnote;
3634
3635 if (nwl>0) draw_vocals (fp,nwl,botnote,bspace,&botpos);
3636
3637 *bpos=botpos;
3638
3639 }
3640
3641
3642 /* ----- draw_sysbars: draw bars extending over staves----- */
3643 void draw_sysbars (fp,ip1,ip2,wid0,h1,dh)
3644 FILE *fp;
3645 int ip1,ip2;
3646 float wid0,h1,dh;
3647 {
3648 int i,v,ok,u,uu,p;
3649 float x;
3650
3651 PUT2 ("gsave 0 %.2f T 1.0 %.4f scale ",h1,dh/24.0)
3652 i=ip1;
3653 for (;;) {
3654 if (xp[i].type==BAR) {
3655 p=xp[i].p[ivc0];
3656 u=symv[ivc0][p].u;
3657 if (u==B_LREP) u=B_FAT1;
3658 if (u==B_RREP) u=B_FAT2;
3659 ok=1;
3660 for (v=0;v<nvoice;v++) {
3661 if (v!=ivc0 && voice[v].draw) {
3662 p=xp[i].p[v];
3663 if (p<0) ok=0;
3664 else {
3665 uu=symv[v][p].u;
3666 if (uu==B_LREP) uu=B_FAT1;
3667 if (uu==B_RREP) uu=B_FAT2;
3668 if (uu!=u) ok=0;
3669 }
3670 }
3671 }
3672
3673 if (ok) {
3674 x=xp[i].x+wid0;
3675 if (u==B_SNGL)
3676 PUT1("%.1f bar ", x)
3677 else if (u==B_DBL)
3678 PUT1("%.1f dbar ", x)
3679 else if (u==B_FAT1)
3680 PUT1("%.1f fbar1 ", x)
3681 else if (u==B_FAT2)
3682 PUT1("%.1f fbar2 ", x)
3683 else if (u==B_DREP) {
3684 PUT1("%.1f fbar1 ", x-1)
3685 PUT1("%.1f fbar2 ", x+1)
3686 }
3687 }
3688 }
3689
3690 i=xp[i].next;
3691 if (i==ip2) break;
3692 }
3693
3694 PUT0 (" 0.0 bar grestore\n")
3695
3696 }
3697
3698
3699 /* ----- count_symbols: count number of "real" symbols ---- */
3700 int count_symbols ()
3701 {
3702 int i,c;
3703
3704 c=0;
3705 for (i=0;i<nsym;i++) {
3706 switch (sym[i].type) {
3707 case NOTE:
3708 case REST:
3709 case BAR:
3710 c++;
3711 }
3712 }
3713 return c;
3714
3715 }
3716
3717 /* ----- select_piece: choose limits for piece to put on one staff ---- …
3718 int select_piece (ip1)
3719 int ip1;
3720 {
3721 int i,num,ltype,count_this;
3722
3723 /* find next symbol marked as eol */
3724 i=ip1;
3725 for (;;) {
3726 if (xp[i].eoln) break;
3727 if (xp[i].next==XP_END) break;
3728 i=xp[i].next;
3729 }
3730 i=xp[i].next;
3731 if (cfmt.barsperstaff==0) return i;
3732
3733 /* find first note or rest */
3734 i=ip1;
3735 for (;;) {
3736 if (xp[i].type==NOTE || xp[i].type==REST)
3737 if (xp[i].type==NOTE || xp[i].type==REST) break;
3738 i=xp[i].next;
3739 if (i==XP_END) return i;
3740 }
3741 i=xp[i].next;
3742 if (i==XP_END) return i;
3743
3744 /* count bars until number is reached */
3745 num=0;
3746 ltype=0;
3747 for (;;) {
3748 count_this=0;
3749 if (xp[i].type==BAR) {
3750 count_this=1;
3751 if (ltype==BAR) count_this=0;
3752 }
3753 num=num+count_this;
3754 ltype=xp[i].type;
3755 i=xp[i].next;
3756 if (i==XP_END) return i;
3757 if (num==cfmt.barsperstaff) return i;
3758 }
3759 i=xp[i].next;
3760
3761 return i;
3762
3763 }
3764
3765 /* ----- is_topvc: check for top voice of set staved together --- */
3766 int is_topvc (jv)
3767 int jv;
3768 {
3769 int iv,kv,ok;
3770
3771 ok=0;
3772 for (iv=0;iv<jv;iv++) {
3773 if (voice[iv].staves >= jv-iv+1) {
3774 for (kv=iv;kv<jv;kv++)
3775 if (voice[kv].draw) ok=1;
3776 }
3777 }
3778
3779 return 1-ok;
3780 }
3781
3782
3783 /* ----- vc_select: set flags for voice selection from -V option --- */
3784 int vc_select ()
3785 {
3786 char *s;
3787 int i,a,b,n;
3788
3789 if (strlen(vcselstr)==0) return nvoice;
3790
3791 for (i=0;i<nvoice;i++) voice[i].select=0;
3792 s=vcselstr;
3793 for (;;) {
3794 if (*s==0) break;
3795 if (!sscanf(s,"%d%n",&a,&n)) break;
3796 s+=n;
3797 b=a;
3798 if (*s=='-') {
3799 s++;
3800 if (*s==0) break;
3801 if (!sscanf(s,"%d%n",&b,&n)) break;
3802 s+=n;
3803 }
3804 for (i=a-1;i<b;i++)
3805 if (i>=0 && i<nvoice) voice[i].select=1;
3806
3807
3808 if (*s==0) {
3809 n=0;
3810 for (i=0;i<nvoice;i++) if (voice[i].select) n++;
3811 if (verbose>=4) {
3812 printf ("Selection <%s> selected voices:",vcselstr);
3813 for (i=0;i<nvoice;i++) if (voice[i].select) printf(" %d",i+1);
3814 printf ("\n");
3815 }
3816 return n;
3817 }
3818 if (*s==',') s++;
3819 else break;
3820 }
3821
3822 rx ("Bad voice selection: -V ", vcselstr);
3823 return 0;
3824 }
3825
3826 /* ----- voice_label: label voice, or just return length if job==0 -- */
3827 float voice_label (fp, label, h, xc, dx0, job)
3828 FILE *fp;
3829 char *label;
3830 float xc,dx0,h;
3831 int job;
3832 {
3833 float w,wid,dy,xcc;
3834 char lab[81],t[81];
3835 int n,i;
3836 char *p,*q,*l[10];
3837
3838 if (strlen(label)==0) return 0.0;
3839
3840 strcpy(lab,label);
3841 n=0;
3842 p=lab;
3843 l[0]=p;
3844 while (q=strstr(p,"\\\\")) { *q='\0'; p=q+2; n++; l[n]=p; }
3845 n++;
3846
3847 wid=0;
3848 for (i=0;i<n;i++) {
3849 tex_str(l[i],t,&w);
3850 w=cfmt.voicefont.size*w;
3851 if (w>wid) wid=w;
3852 if (job!=0) {
3853 xcc=xc;
3854 if (xcc+0.5*w>dx0) xcc=dx0-0.5*w;
3855 dy = 8.0 + 0.5*cfmt.voicefont.size*(n-1-2*i) + h;
3856 PUT3 (" %.2f %.2f M (%s) cshow\n",xcc,dy,t)
3857 }
3858 }
3859 return wid;
3860 }
3861
3862
3863
3864 /* ----- mstave_deco: draw decorations over multiple staves ----- */
3865 void mstave_deco (fp,ip1,ip2,wid0,hsys,htab)
3866 FILE *fp;
3867 int ip1,ip2;
3868 float hsys,wid0,htab[];
3869 {
3870 int iv,jv,nv;
3871 float hbot,htop,ht,x0,y0,wid,wc,wcb,w,wmin;
3872 float wmin1=15.0, wmin2=10.0; /* space to staff */
3873
3874 wmin=wmin2;
3875 if (do_indent) wmin=wmin1;
3876
3877 /* draw bar lines */
3878 if (mvoice>1) {
3879 for (iv=0;iv<nvoice;iv++) {
3880 hbot=10000; htop=-hbot; nv=1;
3881 for (jv=iv;jv<iv+voice[iv].staves;jv++) {
3882 if (voice[jv].draw) nv++;
3883 if (voice[jv].draw && (htab[jv]<hbot)) hbot=htab[jv];
3884 if (voice[jv].draw && (htab[jv]>htop)) htop=htab[jv];
3885 }
3886 if ((hbot<htop-0.001) && (nv>1))
3887 draw_sysbars (fp,ip1,ip2,wid0,hsys-htop,htop-hbot+24.0);
3888 }
3889 PUT1 ("gsave 1.0 %.4f scale 0.0 bar grestore\n", (hsys+24.0)/24.0)
3890 }
3891
3892 /* next part draws voice names (except on braces) */
3893 set_font (fp, cfmt.voicefont, 0);
3894 nv=0;
3895 for (iv=0;iv<nvoice;iv++) if (voice[iv].draw) nv++;
3896
3897 /* get max label width, then center labels above each other */
3898 wid=w=0;
3899 for (iv=0;iv<nvoice;iv++) {
3900 if (voice[iv].draw) {
3901 if (do_indent)
3902 w=voice_label (fp, voice[iv].name, 0.0,0.0,0.0, 0);
3903 else if (nv>1)
3904 w=voice_label (fp, voice[iv].sname, 0.0,0.0,0.0, 0);
3905 if (w>wid) wid=w;
3906 }
3907 }
3908 wc=wcb=0.5*wid+wmin;
3909 if (wcb<18.0) wcb=18.0; /* label on brace needs a bit more room */
3910
3911 for (iv=0;iv<nvoice;iv++) {
3912 if (voice[iv].draw && (voice[iv].brace==0) ) {
3913 y0=hsys-htab[iv];
3914 if (do_indent)
3915 voice_label (fp, voice[iv].name,y0,-wc,-wmin,1);
3916 else if (nv>1)
3917 voice_label (fp,voice[iv].sname,y0,-wc,-wmin,1);
3918 }
3919 }
3920
3921 /* braces and brackets */
3922 for (iv=0;iv<nvoice;iv++) {
3923 hbot=10000; htop=-hbot; nv=0;
3924 for (jv=iv;jv<iv+voice[iv].brace;jv++) {
3925 if (voice[jv].draw) nv++;
3926 if (voice[jv].draw && (htab[jv]<hbot)) hbot=htab[jv];
3927 if (voice[jv].draw && (htab[jv]>htop)) htop=htab[jv];
3928 }
3929 if (hbot<htop+0.001) {
3930 ht=htop-hbot+24.0;
3931 y0=hsys-htop+0.5*ht;
3932 x0=-8;
3933 ht=ht-2.0;
3934 if (voice[iv].brace==1) ht=ht+15.0;
3935 if (voice[iv].brace>2) ht=ht-8.0;
3936 if ((nv>1)||(voice[iv].brace==1))
3937 PUT3 (" %.4f %.1f %.1f brace\n", ht/120.0, x0, y0)
3938 if (do_indent)
3939 voice_label (fp, voice[iv].name, y0-12.0,-wcb,-wmin,1);
3940 else if (nv>1)
3941 voice_label (fp, voice[iv].sname,y0-12.0,-wcb,-wmin,1);
3942 }
3943
3944 hbot=10000; htop=-hbot; nv=0;
3945 for (jv=iv;jv<iv+voice[iv].bracket;jv++) {
3946 if (voice[jv].draw) nv++;
3947 if (voice[jv].draw && (htab[jv]<hbot)) hbot=htab[jv];
3948 if (voice[jv].draw && (htab[jv]>htop)) htop=htab[jv];
3949 }
3950 if ((hbot<htop+0.001) && ((nv>1)||(voice[iv].bracket==1)))
3951 PUT2 ("\n %.1f -3 %.1f bracket\n", htop-hbot+24.0+6.0, hsys-htop-3…
3952
3953 }
3954
3955 }
3956
3957
3958
3959 /* ----- output_music: output for parsed symbol list ----- */
3960 void output_music (fp)
3961 FILE *fp;
3962 {
3963 int ip1,ip2,mv,is_top,nsel,b,bnum;
3964 float realwidth,staffwidth,wid0,widv,lscale,lwidth,bpos;
3965 float spa1,spa2,hsys,htab[40],extra,indent,spax;
3966
3967 /* save current meter and key, to continue after P: or T: field */
3968 for (ivc=0;ivc<nvoice;ivc++) {
3969 voice[ivc].meter1 = voice[ivc].meter;
3970 voice[ivc].key1 = voice[ivc].key;
3971 }
3972
3973 if (!file_initialized && !epsf) {
3974 init_ps (fout,infostr,0,0.0,0.0,0.0,0.0);
3975 init_page (fout);
3976 }
3977
3978 if (nvoice==0) { init_parse_params(); return; }
3979 if (verbose>=10) print_vsyms ();
3980
3981 alfa_last=0.1; beta_last=0.0;
3982 lwidth=cfmt.staffwidth;
3983 lscale=cfmt.scale;
3984 check_margin (cfmt.leftmargin);
3985
3986 /* dump buffer if not enough space for a staff line */
3987 check_buffer (fp, BUFFSZ1);
3988
3989 /* initialize meter and key for voices */
3990 for (ivc=0;ivc<nvoice;ivc++) {
3991 voice[ivc].meter = voice[ivc].meter0;
3992 voice[ivc].key = voice[ivc].key0;
3993 if (!do_meter) voice[ivc].meter.insert=0;
3994 }
3995
3996 /* setup for horizontal positioning, decide which voices to draw */
3997 nsel=vc_select ();
3998 for (ivc=0;ivc<nvoice;ivc++)
3999 if (!voice[ivc].select) voice[ivc].nsym=0;
4000
4001 mvoice=0;
4002 ivc0=-1;
4003 for (ivc=0;ivc<nvoice;ivc++) {
4004 voice[ivc].draw=0;
4005 if (voice[ivc].nsym>0) {
4006 mvoice++;
4007 if (ivc0<0) ivc0=ivc;
4008 voice[ivc].draw=1;
4009 }
4010 }
4011 if (mvoice==0) { init_parse_params(); return; }
4012
4013 for (ivc=0;ivc<nvoice;ivc++) {
4014 if (voice[ivc].draw) {
4015 set_sym_chars (0,voice[ivc].nsym,symv[ivc]);
4016 set_beams (0,voice[ivc].nsym,symv[ivc]);
4017 set_stems (0,voice[ivc].nsym,symv[ivc]);
4018 b=set_sym_times(0,voice[ivc].nsym,symv[ivc],voice[ivc].meter0);
4019 set_sym_widths (0,voice[ivc].nsym,symv[ivc],ivc);
4020 if (ivc==ivc0) bnum=b;
4021 }
4022 }
4023 barinit=bnum;
4024
4025 if (mvoice==1)
4026 set_style_pars (cfmt.strict1);
4027 else
4028 set_style_pars (cfmt.strict2);
4029
4030 set_poslist ();
4031 set_xpwid ();
4032 set_spaces ();
4033
4034 /* loop over pieces to output */
4035 ip1=xp[XP_START].next;
4036 for (;;) {
4037 mline++;
4038 ip1=contract_keysigs (ip1);
4039 wid0=0;
4040 for (ivc=0;ivc<nvoice;ivc++) {
4041 nsym_st[ivc]=set_initsyms (ivc, &widv);
4042 if (widv>wid0) wid0=widv;
4043 }
4044 indent = (do_indent==1) ? cfmt.indent : 0.0;
4045
4046 ip2=select_piece (ip1);
4047 ip2=check_overflow (ip1,ip2,lwidth/lscale-wid0-indent);
4048 if (verbose>5) printf ("output posits %d to %d\n",ip1,ip2-1);
4049 realwidth=set_glue (ip1,ip2,lwidth/lscale-wid0-indent);
4050 check_bars1 (ip1,ip2);
4051 check_bars2 (ip1,ip2);
4052
4053 spa1=spa2=cfmt.staffsep;
4054 if (mvoice>1) {
4055 spa1=cfmt.systemsep;
4056 spa2=cfmt.sysstaffsep;
4057 }
4058
4059 hsys=0;
4060 mv=0;
4061 for (ivc=0;ivc<nvoice;ivc++) {
4062 if (voice[ivc].draw) {
4063 mv++;
4064 nsym=copy_vsyms (ivc,ip1,ip2,wid0);
4065 PUT2("\n%% --- ln %d vc %d \n", mline,ivc+1)
4066 if (mv==1) bskip(lscale*(0.5*spa1+24.0));
4067 else bskip(lscale*(0.5*spa2+24.0));
4068 PUT3("gsave %.3f %.3f scale %.2f setlinewidth\n",
4069 lscale, lscale, BASEWIDTH)
4070 if (do_indent) PUT1(" %.2f 0 T ",indent)
4071 staffwidth=realwidth+wid0;
4072 PUT1("%.2f staff\n", staffwidth)
4073 htab[ivc]=hsys;
4074 spax=spa2+voice[ivc].sep;
4075 if (voice[ivc].sep>1000.0) spax=voice[ivc].sep-2000.0;
4076
4077 is_top=is_topvc(ivc);
4078 draw_symbols (fp,0.5*spa2+spax-spa2,&bpos,is_top);
4079
4080 if (mv==mvoice) mstave_deco (fp,ip1,ip2,wid0,hsys,htab);
4081
4082 PUT0("grestore\n")
4083 bskip(-lscale*bpos);
4084 hsys=hsys+0.5*spa2+24.0-bpos;
4085 }
4086 }
4087
4088 extra=-bpos-0.5*spa2;
4089 if (mvoice>1) bskip(lscale*(spa1+bpos-0.5*spa1+extra));
4090 buffer_eob (fp);
4091
4092 do_meter=do_indent=0;
4093 ip1=ip2;
4094 if (ip1==XP_END) break;
4095 }
4096
4097
4098 /* set things to continue parsing */
4099 for (ivc=0;ivc<nvoice;ivc++) {
4100 voice[ivc].nsym=0;
4101 voice[ivc].meter0 = voice[ivc].meter = voice[ivc].meter1;
4102 voice[ivc].key0 = voice[ivc].key = voice[ivc].key1;
4103 }
4104 init_parse_params ();
4105
4106 }
4107
4108 /* ----- process_textblock ----- */
4109 void process_textblock(fpin,fp,job)
4110 FILE *fp,*fpin;
4111 int job;
4112 {
4113 char w1[81],ln[BSIZE],ln1[BSIZE];
4114 float lwidth,baseskip,parskip;
4115 int i,ll,add_final_nl;
4116
4117 baseskip = cfmt.textfont.size * cfmt.lineskipfac;
4118 parskip = cfmt.textfont.size * cfmt.parskipfac;
4119 add_final_nl=0;
4120 if (job==OBEYLINES) add_final_nl=1;
4121 lwidth=cfmt.staffwidth;
4122 output_music (fp);
4123 buffer_eob (fp);
4124 set_font (fp, cfmt.textfont, 0);
4125 ntxt=0;
4126 for (i=0;i<100;i++) {
4127 if (feof(fpin)) rx("EOF reached scanning text block","");
4128 strcpy (ln, "");
4129 abc2ps_getline(ln, BSIZE, fpin);
4130 ll=strlen(ln);
4131 linenum++;
4132 if ((verbose>=5) || (vb>=10) ) printf ("%3d %s \n", linenum, ln);
4133 if ((ln[0]=='%') && (ln[1]=='%')) {
4134 strcpy(ln1,ln+2);
4135 strcpy(ln,ln1);
4136 }
4137
4138 strcpy(w1,"");
4139 sscanf(ln,"%s",w1);
4140 if (!strcmp(w1,"endtext")) break;
4141
4142 if (job!=SKIP) {
4143 if (str_isblank(ln)) {
4144 write_text_block (fp,job);
4145 ntxt=0;
4146 }
4147 else {
4148 add_to_text_block (ln,add_final_nl);
4149 }
4150 }
4151 }
4152 if (job!=SKIP) write_text_block (fp,job);
4153 }
4154
4155
4156 /* ----- process_pscomment ----- */
4157 void process_pscomment (fpin,fp,line)
4158 FILE *fp,*fpin;
4159 char line[];
4160 {
4161 char w[81],fstr[81],unum1[41],unum2[41],unum3[41];
4162 float h1,h2,len,lwidth;
4163 int i,nch,job;
4164
4165 lwidth=cfmt.staffwidth;
4166 line[0]=' ';
4167 line[1]=' ';
4168 for (i=0;i<strlen(line);i++) if (line[i]=='%') line[i]='\0';
4169 strcpy(w," ");
4170 sscanf(line,"%s%n", w, &nch);
4171
4172 if (!strcmp(w,"begintext")) {
4173 if (epsf && !within_block) return;
4174 strcpy(fstr,"");
4175 sscanf(line, "%*s %s", fstr);
4176 if (str_isblank(fstr)) strcpy(fstr,"obeylines");
4177 if (!strcmp(fstr,"obeylines")) job=OBEYLINES;
4178 else if (!strcmp(fstr,"align")) job=ALIGN;
4179 else if (!strcmp(fstr,"skip")) job=SKIP;
4180 else if (!strcmp(fstr,"ragged")) job=RAGGED;
4181 else rx("bad argument for begintext: ",fstr);
4182 if (within_block && !do_this_tune) job=SKIP;
4183 process_textblock (fpin,fp,job);
4184 return;
4185 }
4186
4187 if (!strcmp(w,"text") || !strcmp(w,"center")) {
4188 if (epsf && !within_block) return;
4189 if (within_block && !do_this_tune) return;
4190 output_music (fp);
4191 set_font (fp, cfmt.textfont, 0);
4192 ntxt=0;
4193 add_to_text_block (line+nch+1,1);
4194 if (!strcmp(w,"text"))
4195 write_text_block (fp,OBEYLINES);
4196 else
4197 write_text_block (fp,OBEYCENTER);
4198 buffer_eob (fp);
4199 }
4200
4201 else if (!strcmp(w,"sep")) {
4202 if (within_block && !do_this_tune) return;
4203 output_music (fp);
4204 strcpy(unum1,"");
4205 strcpy(unum2,"");
4206 strcpy(unum3,"");
4207 sscanf(line,"%*s %s %s %s", unum1,unum2,unum3);
4208 g_unum(unum1,unum1,&h1);
4209 g_unum(unum2,unum2,&h2);
4210 g_unum(unum3,unum3,&len);
4211 if (h1*h1<0.00001) h1=0.5*CM;
4212 if (h2*h2<0.00001) h2=h1;
4213 if (len*len<0.0001) len=3.0*CM;
4214 bskip (h1);
4215 PUT2("%.1f %.1f sep0\n", lwidth/2-len/2, lwidth/2+len/2);
4216 bskip (h2);
4217 buffer_eob (fp);
4218 }
4219
4220 else if (!strcmp(w,"vskip")) {
4221 if (within_block && !do_this_tune) return;
4222 output_music (fp);
4223 strcpy(unum1,"");
4224 sscanf(line,"%*s %s", unum1);
4225 g_unum(unum1,unum1,&h1);
4226 if (h1*h1<0.00001) h1=0.5*CM;
4227 bskip (h1);
4228 buffer_eob (fp);
4229 }
4230
4231 else if (!strcmp(w,"newpage")) {
4232 if (within_block && !do_this_tune) return;
4233 output_music (fp);
4234 write_buffer (fp);
4235 use_buffer=0;
4236 write_pagebreak (fp);
4237 }
4238
4239 else {
4240 if (within_block) {
4241 interpret_format_line (line,&cfmt);
4242 ops_into_fmt (&cfmt);
4243
4244 }
4245 else {
4246 interpret_format_line (line,&dfmt);
4247 ops_into_fmt (&dfmt);
4248 cfmt=dfmt;
4249 }
4250 }
4251
4252
4253 }
4254
4255 /* ----- check_selected ----- */
4256 void check_selected(fp,xref_str,npat,pat,sel_all,search_field)
4257 FILE *fp;
4258 int npat,sel_all,search_field;
4259 char xref_str[],pat[][STRL1];
4260 {
4261
4262 if (!do_this_tune) {
4263 if (is_selected(xref_str,npat,pat,sel_all,search_field)) {
4264 do_this_tune=1;
4265 verbose=vb;
4266 clear_buffer ();
4267 /* set to 0 to permit staff breaks in a tune */
4268 use_buffer=1;
4269 write_tunetop(fp);
4270 }
4271 }
4272 }
4273
4274
4275 /* ----- process_header: call at end of header ----- */
4276 void process_header (fp,xref_str,npat,pat,sel_all,search_field)
4277 FILE *fp;
4278 int npat,sel_all,search_field;
4279 char xref_str[],pat[][STRL1];
4280 {
4281
4282 if ((vb>15) || ((verbose>10)&&within_block))
4283 printf ("End of header.. process header data\n");
4284
4285 check_selected(fp,xref_str,npat,pat,sel_all,search_field);
4286 if (do_this_tune) {
4287 tunenum++;
4288 if (verbose>=3)
4289 printf ("---- start %d (%s) ----\n", xrefnum, info.title);
4290 fflush (stdout);
4291 set_keysig (info.key, &default_key, 1);
4292 halftones=get_halftones (default_key, transpose);
4293 set_transtab (halftones,&default_key);
4294 set_meter (info.meter,&default_meter);
4295 set_dlen (info.len, &default_meter);
4296 check_margin (cfmt.leftmargin);
4297 write_heading (fp);
4298 nvoice=0;
4299 init_parse_params ();
4300 default_meter.insert=1;
4301 mline=0;
4302 do_indent=do_meter=1;
4303 barinit=1;
4304 writenum=0;
4305 }
4306 within_tune=1;
4307 }
4308
4309 /* ----- close_tune ----- */
4310 void close_tune (fp)
4311 FILE *fp;
4312 {
4313 char fnm[81],finf[MAXINF];
4314 FILE *feps;
4315
4316 if (do_this_tune) {
4317 output_music (fp);
4318 put_words (fp);
4319 if (cfmt.writehistory) put_history (fp);
4320 if (epsf) {
4321 close_output_file ();
4322 if (choose_outname) {
4323 epsf_title (info.title, fnm);
4324 strcat (fnm,".eps");
4325 }
4326 else {
4327 nepsf++;
4328 sprintf (fnm, "%s%03d.eps", outf, nepsf);
4329 }
4330 sprintf (finf, "%s (%d)", in_file[0], xrefnum);
4331 if ((feps = fopen (fnm,"w")) == NULL)
4332 rx ("Cannot open output file ", fnm);
4333 init_ps (feps, finf, 1,
4334 cfmt.leftmargin-5, posy+bposy-5,
4335 cfmt.leftmargin+cfmt.staffwidth+5,
4336 cfmt.pageheight-cfmt.topmargin);
4337 init_epsf (feps);
4338 write_buffer (feps);
4339 printf ("\n[%s] %s", fnm, info.title);
4340 close_epsf (feps);
4341 fclose (feps);
4342 in_page=0;
4343 init_pdims ();
4344 }
4345 else {
4346 buffer_eob (fp);
4347 write_buffer (fp);
4348 if ((verbose==0) && (tunenum%10==0)) printf (".");
4349 if (verbose==2) printf ("%s - ", info.title);
4350 }
4351 verbose=0;
4352 }
4353 info=default_info;
4354 within_tune=within_block=do_this_tune=0;
4355
4356 }
4357
4358
4359 /* ----- process_line ----- */
4360 void process_line (fp,type,xref_str,npat,pat,sel_all,search_field)
4361 FILE *fp;
4362 int type,npat,sel_all,search_field;
4363 char xref_str[],pat[][STRL1];
4364 {
4365
4366 if ((vb>15) || ((verbose>10)&&within_block)) {
4367 printf ("process_line, type %d ", type);
4368 print_linetype(type);
4369 }
4370
4371 switch (type) {
4372
4373 case XREF: /* start of new block */
4374 if (!epsf) write_buffer (fp); /* flush stuff left from %% lines */
4375 if (within_block) printf ("\n+++ Last tune not closed properly\n");
4376 get_default_info ();
4377 within_block = 1;
4378 within_tune = 0;
4379 do_this_tune = 0;
4380 numtitle=0;
4381 ntext=0;
4382 init_pdims();
4383 cfmt=dfmt;
4384 break;
4385
4386 case TITLE:
4387 if (!within_block) break;
4388 if (within_tune) { /* title within tune */
4389 if (do_this_tune ) {
4390 output_music (fp);
4391 write_inside_title (fp);
4392 do_meter=do_indent=1;
4393 barinit=1;
4394 }
4395 }
4396 else
4397 check_selected(fp,xref_str,npat,pat,sel_all,search_field);
4398 break;
4399
4400 case TEMPO:
4401 if (!within_block) break;
4402 if (within_tune) { /* tempo within tune */
4403 if (do_this_tune ) {
4404 output_music (fp);
4405 write_inside_tempo(fp);
4406 }
4407 }
4408 else
4409 check_selected(fp,xref_str,npat,pat,sel_all,search_field);
4410 break;
4411
4412 case KEY:
4413 if (!within_block) break;
4414 if (within_tune) {
4415 if (do_this_tune) handle_inside_field(type);
4416 }
4417 else { /* end of header.. start now */
4418 /*| process_header (fp,xref_str,npat,pat,sel_all,search_field); |*/
4419 }
4420 break;
4421
4422 case METER:
4423 if (!within_block) break;
4424 if (do_this_tune && within_tune) handle_inside_field(type);
4425 break;
4426
4427 case DLEN:
4428 if (!within_block) break;
4429 if (do_this_tune && within_tune) handle_inside_field(type);
4430 break;
4431
4432 case PARTS:
4433 if (!within_block) break;
4434 if (do_this_tune && within_tune) {
4435 output_music (fp);
4436 write_parts(fp);
4437 }
4438 break;
4439
4440 case VOICE:
4441 if (do_this_tune && within_block) {
4442 if (!within_tune)
4443 printf ("+++ Voice field not allowed in header: V:%s\n", lvoicei…
4444 else
4445 ivc=switch_voice (lvoiceid);
4446 }
4447 break;
4448
4449 }
4450 }
4451
4452 /* ----- process_file ----- */
4453 void process_file (fpin,fpout,xref_str,npat,pat,sel_all,search_field)
4454 FILE *fpin,*fpout;
4455 int npat,sel_all,search_field;
4456 char xref_str[],pat[][STRL1];
4457 {
4458 char line[BSIZE];
4459 int type,nsym0;
4460
4461 within_tune=within_block=do_this_tune=0;
4462 linenum=0;
4463 numtitle=0;
4464 reset_info (&default_info);
4465 info=default_info;
4466 verbose=0;
4467 if (vb>=20) db=3;
4468 if (vb>=25) db=5;
4469
4470 type=read_line (fpin,line);
4471
4472 for (;;) {
4473
4474 /* header is completed at first MUSIC or VOICE line */
4475 if ((type==MUSIC) || (type==VOICE)) {
4476 if (within_block && !within_tune)
4477 process_header (fpout,xref_str,npat,pat,sel_all,search_field);
4478 }
4479
4480 /* tune terminates at BLANK or EOF */
4481 if ((type==BLANK) || (type==E_O_F)) close_tune (fpout);
4482 if (type==E_O_F) break;
4483
4484 if (type==PSCOMMENT) process_pscomment(fpin,fpout,line);
4485 if ((type==MUSIC) && do_this_tune) parse_music_line (line);
4486 process_line (fpout,type,xref_str,npat,pat,sel_all,search_field);
4487 type=read_line (fpin,line);
4488 }
4489 if (!epsf) {
4490 buffer_eob (fpout);
4491 write_buffer (fpout);
4492 }
4493
4494 }
4495
4496
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.