subs.h - abc2ps - A powerful sheet setting tool using the simple abc notation | |
git clone git://vernunftzentrum.de/abc2ps.git | |
Log | |
Files | |
Refs | |
--- | |
subs.h (37054B) | |
--- | |
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 /* miscellaneous subroutines */ | |
8 | |
9 /* ----- write_help ----- */ | |
10 void write_help () | |
11 { | |
12 | |
13 printf ("abc2ps v%s.%s (%s, %s) compiled %s\n", | |
14 VERSION, REVISION, VDATE, STYLE, __DATE__); | |
15 | |
16 printf ("Usage: abc2ps files.. [-e nums-or-pats] [other flags]\n" | |
17 " - show index of abc files or typeset tunes in Postscript.\n" | |
18 "where: files input files in abc format\n" | |
19 " nums tune xref numbers, i.e. 1 3 6-7,20-\n" | |
20 " pats patterns for title search\n" | |
21 "Tunes are selected if they match a number or a pattern.\n" | |
22 "Flags: -o write output for selected tunes\n" | |
23 " -E produce EPSF output, one tune per file\n" | |
24 " -O aa set outfile name to aaa\n" | |
25 " -O = make outfile name from infile/title\n" | |
26 " -i run in interactive mode\n" | |
27 " -v nn set verbosity level to nn\n" | |
28 " -h show this command summary\n" | |
29 " Selection:\n" | |
30 " -e following arguments are selectors\n" | |
31 " -f following arguments are file names\n" | |
32 " -T search Title field (default)\n" | |
33 " -C search Composer field instead of title\n" | |
34 " -R search Rhythm field instead of title\n" | |
35 " -S search Source field instead of title\n" | |
36 " -V str select voices, eg. -V 1,4-5\n" | |
37 " Formatting:\n" | |
38 " -H show the format parameters\n" | |
39 " -p pretty output (looks better, needs more space)… | |
40 " -P select second predefined pretty output style\n" | |
41 " -s xx set scale factor for symbol size to xx\n" | |
42 " -w xx set staff width (cm/in/pt)\n" | |
43 " -m xx set left margin (cm/in/pt)\n" | |
44 " -d xx set staff separation (cm/in/pt)\n" | |
45 " -x include xref numbers in output\n" | |
46 " -k nn number every nn bars; 0 for first in staff\n" | |
47 " -n include notes and history in output\n" | |
48 " -N write page numbers\n" | |
49 " -I write index to Ind.ps\n" | |
50 " -1 write one tune per page\n" | |
51 " -l landscape mode\n" | |
52 " -g xx set glue mode to shrink|space|stretch|fill\n" | |
53 " -F foo read format from \"foo.fmt\"\n" | |
54 " -D bar look for format files in directory \"bar\"\n" | |
55 " -X x set strictness for note spacing, 0<x<1 \n" | |
56 " Transposing:\n" | |
57 " -t n transpose by n halftones (_n for negative numb… | |
58 " -t XX transpose root up/down to note XX (eg. C A# ^B… | |
59 " Line breaks:\n" | |
60 " -a xx set max shrinkage to xx (between 0 and 1)\n" | |
61 " -b break at all line ends (ignore continuations)\… | |
62 " -c continue all line ends (append '\\')\n" | |
63 " -B bb put line break every bb bars\n" | |
64 " Alloc options:\n" | |
65 " -maxs n set maximal number of symbols (default %d)\n" | |
66 " -maxv n set maximal number of voices (default %d)\n" | |
67 , maxSyms, maxVc); | |
68 } | |
69 | |
70 | |
71 /* ----- write_version ----- */ | |
72 void write_version () | |
73 { | |
74 | |
75 /* printf ("abc2ps v%s (%s, %s) compiled %s\n", | |
76 VERSION, VDATE, STYLE, __DATE__); */ | |
77 | |
78 printf ("abc2ps v%s.%s (%s, %s) compiled %s\n", | |
79 VERSION, REVISION, VDATE, STYLE, __DATE__); | |
80 | |
81 if (strlen(DEFAULT_FDIR)>0) | |
82 printf ("Default format directory %s\n", DEFAULT_FDIR); | |
83 | |
84 } | |
85 | |
86 /* ----- is_xrefstr: check if string ok for xref selection ---- */ | |
87 int is_xrefstr (str) | |
88 char str[]; | |
89 { | |
90 | |
91 char *c; | |
92 c=str; | |
93 while (*c != '\0') { | |
94 if ((!isdig(*c)) && (*c!='-') && (*c!=',') && (*c!=' ')) return 0; | |
95 c++; | |
96 } | |
97 return 1; | |
98 } | |
99 | |
100 | |
101 /* ----- make_arglist: splits one string into list or arguments ---- */ | |
102 int make_arglist (str, av) | |
103 char str[]; | |
104 char *av[]; | |
105 { | |
106 char *q; | |
107 int n; | |
108 | |
109 q=str; | |
110 n=1; /* first real arg is 1, as in argv */ | |
111 for (;;) { | |
112 while (*q==' ') q++; | |
113 if (*q=='\0') break; | |
114 av[n]=q; | |
115 n++; | |
116 while ((*q!=' ') && (*q!='\0')) q++; | |
117 if (*q=='\0') break; | |
118 *q='\0'; | |
119 q++; | |
120 } | |
121 return n; | |
122 } | |
123 | |
124 | |
125 /* ----- init_ops ----- */ | |
126 void init_ops (job) | |
127 int job; | |
128 { | |
129 | |
130 one_per_page = -1; | |
131 landscape = -1; | |
132 scalefac = -1.0; | |
133 lmargin = -1.0; | |
134 swidth = -1.0; | |
135 write_history = -1; | |
136 staffsep = -1; | |
137 dstaffsep = 0; | |
138 break_continues = -1; | |
139 continue_lines = -1; | |
140 include_xrefs = -1; | |
141 alfa_c = -1.0; | |
142 strict1 = -1.0; | |
143 strict2 = -1.0; | |
144 barnums = -1; | |
145 make_index = 0; | |
146 | |
147 select_all = 0; | |
148 do_mode = DO_INDEX; | |
149 pagenumbers = 0; | |
150 strcpy (styf, ""); | |
151 strcpy (transpose, ""); | |
152 strcpy (vcselstr, ""); | |
153 | |
154 if (job) { | |
155 strcpy (styd, DEFAULT_FDIR); | |
156 strcpy (outf, OUTPUTFILE); | |
157 interactive = 0; | |
158 pretty = 0; | |
159 epsf = 0; | |
160 choose_outname = 0; | |
161 gmode = G_FILL; | |
162 vb = VERBOSE0; | |
163 search_field0 = S_TITLE; | |
164 } | |
165 } | |
166 | |
167 | |
168 /* ----- ops_into_fmt ----- */ | |
169 void ops_into_fmt (fmt) | |
170 struct FORMAT *fmt; | |
171 { | |
172 if (landscape >= 0) fmt->landscape=landscape; | |
173 if (scalefac >= 0) fmt->scale=scalefac; | |
174 if (lmargin >= 0) fmt->leftmargin=lmargin; | |
175 if (swidth >= 0) fmt->staffwidth=swidth; | |
176 if (continue_lines >= 0) fmt->continueall=continue_lines; | |
177 if (break_continues >= 0) fmt->breakall=break_continues; | |
178 if (write_history >= 0) fmt->writehistory=write_history; | |
179 if (bars_per_line > 0) fmt->barsperstaff=bars_per_line; | |
180 if (include_xrefs >= 0) fmt->withxrefs=include_xrefs; | |
181 if (one_per_page >= 0) fmt->oneperpage=one_per_page; | |
182 if (alfa_c >= 0) fmt->maxshrink=alfa_c; | |
183 if (staffsep >= 0) fmt->staffsep=staffsep; | |
184 if (strict1 >= 0) fmt->strict1=strict1; | |
185 if (strict2 >= 0) fmt->strict2=strict2; | |
186 if (barnums >= 0) fmt->barnums=barnums; | |
187 fmt->staffsep = fmt->staffsep + dstaffsep; | |
188 fmt->sysstaffsep = fmt->sysstaffsep + dstaffsep; | |
189 | |
190 } | |
191 | |
192 | |
193 /* ----- parse_args: parse list of arguments, interpret flags ----- */ | |
194 int parse_args (ac, av) | |
195 int ac; | |
196 char *av[]; | |
197 { | |
198 int i,m,k,nsel,sel_arg,j,ok,f_pos,got_value; | |
199 char c,aaa[201],ext[41]; | |
200 | |
201 help_me=0; | |
202 ninf=0; | |
203 nsel=0; | |
204 sel_arg=0; | |
205 f_pos=-1; | |
206 strcpy (sel_str[0], ""); | |
207 s_field[0]=search_field0; | |
208 | |
209 i=1; | |
210 while (i<ac) { | |
211 | |
212 if (av[i][0]=='+') { /* switch off flags with '+' */ | |
213 m=1; | |
214 k=strlen(av[i]); | |
215 while (m<k) { | |
216 c=av[i][m]; | |
217 if (c=='b') break_continues=0; | |
218 else if (c=='c') continue_lines=0; | |
219 else if (c=='x') include_xrefs=0; | |
220 else if (c=='1') one_per_page=0; | |
221 else if (c=='B') bars_per_line=0; | |
222 else if (c=='i') interactive=0; | |
223 else if (c=='n') write_history=0; | |
224 else if (c=='l') landscape=0; | |
225 else if (c=='p') pretty=0; | |
226 else if (c=='E') epsf=0; | |
227 else if (c=='F') strcpy (styf, ""); | |
228 else if (c=='N') pagenumbers=0; | |
229 else if (c=='O') { choose_outname=0; strcpy (outf, OUTPUTFILE);… | |
230 else { | |
231 printf ("+++ Cannot switch off flag: +%c\n", c); | |
232 return 1; | |
233 } | |
234 m++; | |
235 } | |
236 } | |
237 | |
238 else if (av[i][0]=='-') { /* interpret a flag with '-'*/ | |
239 | |
240 /* identify fullword options first… | |
241 if (!strcmp(av[i],"-maxv")) { | |
242 if ((i==ac-1)||(av[i+1][0]=='-')) rx("missing parameter for ",av… | |
243 sscanf(av[++i],"%d",&maxVc); | |
244 } | |
245 else if (!strcmp(av[i],"-maxs")) { | |
246 if ((i==ac-1)||(av[i+1][0]=='-')) rx("missing parameter for ",av… | |
247 sscanf(av[++i],"%d",&maxSyms); | |
248 } | |
249 | |
250 else { | |
251 m=1; | |
252 k=strlen(av[i]); | |
253 while (m<k) { | |
254 c=av[i][m]; | |
255 if (c=='h') help_me=1; /* simple flags */ | |
256 else if (c=='H') help_me=2; | |
257 else if (c=='e') sel_arg=1; | |
258 else if (c=='f') { | |
259 nsel++; | |
260 strcpy (sel_str[nsel], ""); | |
261 if (ninf==0) { /* selector before first file … | |
262 strcpy(sel_str[nsel],sel_str[nsel-1]); | |
263 s_field[nsel]=s_field[nsel-1]; | |
264 } | |
265 s_field[nsel]=search_field0; | |
266 sel_arg=0; | |
267 f_pos=i; | |
268 } | |
269 else if (c=='b') {break_continues=1; continue_lines=0;} | |
270 else if (c=='c') {continue_lines=1; break_continues=0;} | |
271 else if (c=='x') include_xrefs=1; | |
272 else if (c=='1') one_per_page=1; | |
273 else if (c=='i') interactive=1; | |
274 else if (c=='n') write_history=1; | |
275 else if (c=='l') landscape=1; | |
276 else if (c=='p') pretty=1; | |
277 else if (c=='P') pretty=2; | |
278 else if (c=='E') epsf=1; | |
279 else if (c=='o') do_mode=DO_OUTPUT; | |
280 else if (c=='N') pagenumbers=1; | |
281 else if (c=='I') make_index=1; | |
282 else if (strchr("TCRS",c)) { | |
283 if (c=='T') s_field[nsel]=S_TITLE; | |
284 if (c=='C') s_field[nsel]=S_COMPOSER; | |
285 if (c=='R') s_field[nsel]=S_RHYTHM; | |
286 if (c=='S') s_field[nsel]=S_SOURCE; | |
287 sel_arg=1; | |
288 } | |
289 | |
290 else if (strchr("vsdwmgtkDFYBVXaO",c)) { /* flags with parame… | |
291 strcpy (aaa, &av[i][m+1]); | |
292 if ((strlen(aaa)>0) && strchr("glO",c)) { /* no sticky a… | |
293 printf ("+++ Incorrect usage of flag -%c\n", c); | |
294 return 1; | |
295 } | |
296 | |
297 got_value=1; /* check for value… | |
298 if (strlen(aaa)==0) { | |
299 got_value=0; | |
300 i++; | |
301 if ((i>=ac) || (av[i][0]=='-')) | |
302 i--; | |
303 else { | |
304 strcpy (aaa,av[i]); | |
305 got_value=1; | |
306 } | |
307 } | |
308 | |
309 if (got_value && strchr("vskYB",c)) { /* check num args… | |
310 ok=1; | |
311 for (j=0;j<strlen(aaa);j++) | |
312 if (!strchr("0123456789.",aaa[j])) ok=0; | |
313 if (!ok) { | |
314 printf ("+++ Invalid parameter <%s> for flag -%c\n",aaa,… | |
315 return 1; | |
316 } | |
317 } | |
318 | |
319 /* --- next ops require a value --- */ | |
320 | |
321 if (!got_value) { /* check value was given… | |
322 printf ("+++ Missing parameter after flag -%c\n", c); | |
323 return 1; | |
324 } | |
325 | |
326 if (c=='k') { | |
327 sscanf(aaa,"%d",&barnums); | |
328 break; | |
329 } | |
330 | |
331 if (c=='V') { /* -V flag */ | |
332 ok=1; | |
333 strcpy (vcselstr, aaa); | |
334 } | |
335 | |
336 if (c=='X') { /* -X flag */ | |
337 ok=1; | |
338 if (aaa[0]==',') { | |
339 sscanf(aaa,",%f",&strict2); | |
340 if (strict2<-0.001 || strict2>1.001) ok=0; | |
341 } | |
342 else if (strchr(aaa,',')) { | |
343 sscanf (aaa,"%f,%f",&strict1,&strict2); | |
344 if (strict1<-0.001 || strict1>1.001) ok=0; | |
345 if (strict2<-0.001 || strict2>1.001) ok=0; | |
346 } | |
347 else { | |
348 sscanf(aaa,"%f",&strict1); | |
349 if (strict1<-0.001 || strict1>1.001) ok=0; | |
350 strict2=strict1; | |
351 } | |
352 if (!ok) { | |
353 printf ("+++ Invalid parameter <%s> for flag -%c\n",aaa,… | |
354 return 1; | |
355 } | |
356 } | |
357 | |
358 if (c=='O') { /* -O flag */ | |
359 if (!strcmp(aaa,"=")) { | |
360 choose_outname=1; | |
361 } | |
362 else { | |
363 getext (aaa,ext); | |
364 if (strcmp(ext,"ps") && strcmp(ext,"eps") && strcmp(ext,… | |
365 printf ("Wrong extension for output file: %s\n", aaa); | |
366 return 1; | |
367 } | |
368 strext (outf, aaa, "ps", 1); | |
369 choose_outname=0; | |
370 } | |
371 } | |
372 | |
373 if (c=='a') { | |
374 sscanf (aaa, "%f", &alfa_c); | |
375 if ((alfa_c>1.05)||(alfa_c<-0.01)) { | |
376 printf ("+++ Bad parameter for flag -a: %s\n",aaa); | |
377 return 1; | |
378 } | |
379 } | |
380 | |
381 if (c=='B') { | |
382 sscanf(aaa,"%d",&bars_per_line); | |
383 continue_lines=0; | |
384 } | |
385 if (c=='t') strcpy(transpose,aaa); | |
386 if (c=='v') sscanf(aaa,"%d",&vb); | |
387 if (c=='s') sscanf(aaa,"%f",&scalefac); | |
388 if (c=='d') { | |
389 if (aaa[0]=='+' || aaa[0]=='-') dstaffsep = scan_u(aaa); | |
390 else staffsep = scan_u(aaa); | |
391 } | |
392 if (c=='w') swidth = scan_u(aaa); | |
393 if (c=='m') lmargin = scan_u(aaa); | |
394 if (c=='F') strcpy(styf,aaa); | |
395 if (c=='D') strcpy (styd,aaa); | |
396 if (c=='g') { | |
397 if (abbrev(aaa,"shrink", 2)) gmode=G_SHRINK; | |
398 else if (abbrev(aaa,"stretch",2)) gmode=G_STRETCH; | |
399 else if (abbrev(aaa,"space", 2)) gmode=G_SPACE; | |
400 else if (abbrev(aaa,"fill", 2)) gmode=G_FILL; | |
401 else { | |
402 printf ("+++ Bad parameter for flag -g: %s\n",aaa); | |
403 return 1; | |
404 } | |
405 } | |
406 break; | |
407 } | |
408 else { | |
409 printf ("+++ Unknown flag: -%c\n", c); | |
410 return 1; | |
411 } | |
412 m++; | |
413 } | |
414 } | |
415 } | |
416 | |
417 else { | |
418 if (strstr(av[i],".fmt")) { /* implict -F */ | |
419 strcpy(styf, av[i]); | |
420 } | |
421 else { | |
422 if (strstr(av[i],".abc") && sel_arg) { /* file if .abc */ | |
423 nsel++; | |
424 strcpy (sel_str[nsel], ""); | |
425 s_field[nsel]=S_TITLE; | |
426 if (ninf==0) { /* selector before first file */ | |
427 strcpy(sel_str[nsel],sel_str[nsel-1]); | |
428 s_field[nsel]=s_field[nsel-1]; | |
429 } | |
430 sel_arg=0; | |
431 } | |
432 if (is_xrefstr(av[i]) && (!sel_arg)) { /* sel if xref numbers… | |
433 if (i-1 != f_pos) sel_arg=1; | |
434 } | |
435 | |
436 if (!sel_arg) { /* this arg is a file name */ | |
437 if (ninf>=MAXINF) { | |
438 printf ("+++ Too many input files, max is %d\n", MAXINF); | |
439 return 1; | |
440 } | |
441 strcpy (in_file[ninf], av[i]); | |
442 psel[ninf]=nsel; | |
443 ninf++; | |
444 } | |
445 else { /* this arg is a selector */ | |
446 strcat(sel_str[nsel], av[i]); | |
447 strcat(sel_str[nsel], " "); | |
448 } | |
449 } | |
450 } | |
451 i++; | |
452 } | |
453 | |
454 return 0; | |
455 } | |
456 | |
457 /* ----- alloc_structs ----- */ | |
458 /* Thanks to Henrik Norbeck for this */ | |
459 void alloc_structs () | |
460 { | |
461 int j; | |
462 | |
463 sym = (struct SYMBOL *)calloc(maxSyms, sizeof(struct SYMBOL)); | |
464 if (sym==NULL) rx("Out of memory",""); | |
465 | |
466 symv = (struct SYMBOL **)calloc(maxVc, sizeof(struct SYMBOL *)); | |
467 if (symv==NULL) rx("Out of memory",""); | |
468 | |
469 for (j=0;j<maxVc;j++) { | |
470 symv[j] = (struct SYMBOL *)calloc(maxSyms, sizeof(struct SYMBOL)); | |
471 if (symv[j]==NULL) rx("Out of memory",""); | |
472 } | |
473 | |
474 xp = (struct XPOS *)calloc(maxSyms+1, sizeof(struct XPOS)); | |
475 if (xp==NULL) rx("Out of memory",""); | |
476 | |
477 for (j=0;j<maxSyms+1;j++) { | |
478 xp[j].p = (int *)calloc(maxVc, sizeof(int)); | |
479 if (xp[j].p==NULL) rx("Out of memory",""); | |
480 } | |
481 | |
482 voice=(struct VCESPEC *)calloc(maxVc, sizeof(struct VCESPEC)); | |
483 if (voice==NULL) rx("Out of memory",""); | |
484 | |
485 sym_st = (struct SYMBOL **)calloc(maxVc, sizeof(struct SYMBOL *)); | |
486 if (sym_st==NULL) rx("Out of memory",""); | |
487 | |
488 for (j=0;j<maxVc;j++) { | |
489 sym_st[j] = (struct SYMBOL *)calloc(MAXSYMST, sizeof(struct SYMBOL)); | |
490 if (sym_st[j]==NULL) rx("Out of memory",""); | |
491 } | |
492 | |
493 nsym_st = (int *)calloc(maxVc, sizeof(int)); | |
494 if (nsym_st==NULL) rx("Out of memory",""); | |
495 | |
496 } | |
497 | |
498 | |
499 /* ----- set_page_format ----- */ | |
500 int set_page_format () | |
501 { | |
502 int i,j; | |
503 | |
504 if (pretty==1) | |
505 set_pretty_format (&cfmt); | |
506 else if (pretty==2) | |
507 set_pretty2_format (&cfmt); | |
508 else | |
509 set_standard_format (&cfmt); | |
510 | |
511 i=read_fmt_file ("fonts.fmt", styd, &cfmt); | |
512 j=0; | |
513 if (strlen(styf)>0) { | |
514 strext(styf,styf,"fmt",1); | |
515 j=read_fmt_file (styf, styd, &cfmt); | |
516 if (j==0) { | |
517 printf ("\n+++ Cannot open file: %s\n", styf); | |
518 return 0; | |
519 } | |
520 strcpy(cfmt.name, styf); | |
521 } | |
522 if (i || j) printf("\n"); | |
523 ops_into_fmt (&cfmt); | |
524 | |
525 make_font_list (&cfmt); | |
526 sfmt=cfmt; | |
527 dfmt=cfmt; | |
528 return 1; | |
529 } | |
530 | |
531 | |
532 /* ----- tex_str: change string to take care of some tex-style codes ---… | |
533 /* Puts \ in front of ( and ) in case brackets are not balanced, | |
534 interprets some TeX-type strings using ISOLatin1 encodings. | |
535 Returns the length of the string as finally given out on paper. | |
536 Also returns an estimate of the string width... */ | |
537 int tex_str (str,s,wid) | |
538 char *str; | |
539 char s[]; | |
540 float *wid; | |
541 { | |
542 char *c; | |
543 int base,add,n; | |
544 char t[21]; | |
545 float w; | |
546 | |
547 c=str; | |
548 strcpy(s,""); | |
549 n=0; | |
550 w=0; | |
551 while (*c != '\0') { | |
552 | |
553 if ((*c=='(') || (*c==')')) /* ( ) becomes \( \) */ | |
554 {sprintf(t, "\\%c", *c); strcat(s,t); w+=cwid('('); n++; } | |
555 | |
556 else if (*c=='\\') { /* backslash sequences */ | |
557 c++; | |
558 if (*c=='\0') break; | |
559 add=0; /* accented vowels */ | |
560 if (*c=='`') add=1; | |
561 if (*c=='\'') add=2; | |
562 if (*c=='^') add=3; | |
563 if (*c=='"') add=4; | |
564 if (add) { | |
565 c++; | |
566 base=0; | |
567 if (*c=='a') { base=340; if (add==4) add=5; } | |
568 if (*c=='e') base=350; | |
569 if (*c=='i') base=354; | |
570 if (*c=='o') { base=362; if (add==4) add=5; } | |
571 if (*c=='u') base=371; | |
572 if (*c=='A') { base=300; if (add==4) add=5; } | |
573 if (*c=='E') base=310; | |
574 if (*c=='I') base=314; | |
575 if (*c=='O') { base=322; if (add==4) add=5; } | |
576 if (*c=='U') base=331; | |
577 w+=cwid(*c); | |
578 if (base) | |
579 {sprintf(t,"\\%d",base+add-1); strcat(s,t); n+=1; } | |
580 else | |
581 {sprintf(t,"%c",*c); strcat(s,t); n+=1; } | |
582 } | |
583 | |
584 else if (*c==' ') /* \-space */ | |
585 { strcat(s," "); w+=cwid(' '); n++; } | |
586 | |
587 else if (*c=='O') /* O-slash */ | |
588 { strcat(s,"\\330"); w+=cwid('O'); n++; } | |
589 | |
590 else if (*c=='o') /* o-slash */ | |
591 { strcat(s,"\\370"); w+=cwid('O'); n++; } | |
592 | |
593 else if((*c=='s')&&(*(c+1)=='s')) /* sz */ | |
594 { c++; strcat(s,"\\337"); w+=cwid('s'); n++; } | |
595 else if((*c=='a')&&(*(c+1)=='a')) /* a-ring */ | |
596 { c++; strcat(s,"\\345"); w+=cwid('a'); n++; } | |
597 else if((*c=='A')&&(*(c+1)=='A')) /* A-ring */ | |
598 { c++; strcat(s,"\\305"); w+=cwid('A'); n++; } | |
599 else if((*c=='a')&&(*(c+1)=='e')) /* ae */ | |
600 { c++; strcat(s,"\\346"); w+=1.5*cwid('a'); n++; } | |
601 else if((*c=='A')&&(*(c+1)=='E')) /* AE */ | |
602 { c++; strcat(s,"\\306"); w+=1.5*cwid('A'); n++; } | |
603 | |
604 | |
605 else if (*c=='c') { /* c-cedilla */ | |
606 c++; | |
607 w+=cwid(*c); | |
608 if (*c=='C') { strcat(s,"\\307"); n++; } | |
609 else if (*c=='c') { strcat(s,"\\347"); n++; } | |
610 else {sprintf(t,"%c",*c); strcat(s,t); n++; } | |
611 } | |
612 | |
613 else if (*c=='~') { /* n-twiddle */ | |
614 c++; | |
615 w+=cwid(*c); | |
616 if (*c=='N') { strcat(s,"\\321"); n++; } | |
617 else if (*c=='n') { strcat(s,"\\361"); n++; } | |
618 else { sprintf(t,"%c",*c); strcat(s,t); n++; } | |
619 } | |
620 | |
621 else /* \-something-else; pass through */ | |
622 {sprintf(t,"\\%c",*c); strcat(s,t); w+=cwid('A'); n++; } | |
623 } | |
624 | |
625 else if (*c=='{') | |
626 ; | |
627 else if (*c=='}') | |
628 ; | |
629 | |
630 else /* other characters: pass though */ | |
631 { | |
632 sprintf(t,"%c",*c); | |
633 strcat(s,t); n++; | |
634 w+=cwid(*c); | |
635 } | |
636 | |
637 c++; | |
638 } | |
639 *wid = w; | |
640 | |
641 return n; | |
642 } | |
643 | |
644 | |
645 /* ----- put_str: output a string in postscript ----- */ | |
646 void put_str (str) | |
647 char *str; | |
648 { | |
649 char s[801]; | |
650 float w; | |
651 | |
652 tex_str (str,s,&w); | |
653 PUT1 ("%s", s); | |
654 } | |
655 | |
656 /* ----- set_font ----- */ | |
657 void set_font (fp,font,add_bracket) | |
658 FILE *fp; | |
659 struct FONTSPEC font; | |
660 int add_bracket; | |
661 { | |
662 int i,fnum; | |
663 | |
664 fnum=-1; | |
665 for (i=0;i<nfontnames;i++) { | |
666 if (!strcmp(font.name,fontnames[i])) fnum=i; | |
667 } | |
668 if (fnum<0) { | |
669 printf ("\n+++ Font \"%s\" not predefined; using first in list\n", | |
670 font.name); | |
671 fnum=0; | |
672 } | |
673 PUT3("%.1f %d F%d ", font.size, font.box, fnum) | |
674 if (add_bracket) PUT0("(") | |
675 } | |
676 | |
677 /* ----- set_font_str ----- */ | |
678 void set_font_str (str,font) | |
679 char str[]; | |
680 struct FONTSPEC font; | |
681 { | |
682 int i,fnum; | |
683 | |
684 fnum=-1; | |
685 for (i=0;i<nfontnames;i++) { | |
686 if (!strcmp(font.name,fontnames[i])) fnum=i; | |
687 } | |
688 sprintf (str,"%.1f %d F%d ", font.size, font.box, fnum); | |
689 } | |
690 | |
691 | |
692 /* ----- check_margin: do horizontal shift if needed ---- */ | |
693 void check_margin (new_posx) | |
694 float new_posx; | |
695 { | |
696 float dif; | |
697 | |
698 dif=new_posx-posx; | |
699 if (dif*dif<0.001) return; | |
700 | |
701 PUT1("%.2f 0 T\n", dif) | |
702 posx=new_posx; | |
703 } | |
704 | |
705 | |
706 /* ----- epsf_title ------ */ | |
707 void epsf_title (title,fnm) | |
708 char title[],fnm[]; | |
709 { | |
710 char *p,*q; | |
711 | |
712 p=title; q=fnm; | |
713 while (*p != '\0') { | |
714 if (*p == ' ') | |
715 *q = '_'; | |
716 else | |
717 *q = *p; | |
718 p++; q++; | |
719 } | |
720 *q = '\0'; | |
721 } | |
722 | |
723 /* ----- close_output_file ------ */ | |
724 void close_output_file () | |
725 { | |
726 int m; | |
727 | |
728 if (!file_open) return; | |
729 | |
730 if (interactive) printf ("(close %s)\n", outfnam); | |
731 | |
732 close_page(fout); | |
733 close_ps (fout); | |
734 fclose (fout); | |
735 if (tunenum==0) | |
736 printf ("+++ Warning: no tunes written to output file\n"); | |
737 m=get_file_size (outfnam); | |
738 printf ("Output written on %s (%d page%s, %d title%s, %d byte%s)\n", | |
739 outfnam, | |
740 pagenum, pagenum==1 ? "" : "s", | |
741 tunenum, tunenum==1 ? "" : "s", | |
742 m, m==1 ? "" : "s"); | |
743 file_open=0; | |
744 file_initialized=0; | |
745 | |
746 } | |
747 | |
748 | |
749 /* ----- open_output_file ------ */ | |
750 void open_output_file (fnam,tstr) | |
751 char fnam[],tstr[]; | |
752 { | |
753 | |
754 if (!strcmp(fnam,outfnam)) return; | |
755 | |
756 if (file_open) close_output_file (); | |
757 | |
758 if (interactive) printf ("(open %s)\n", fnam); | |
759 strcpy (outfnam, fnam); | |
760 if ((fout = fopen (outfnam,"w")) == NULL) | |
761 rx ("Cannot open output file ", outf); | |
762 pagenum=0; | |
763 tunenum=tnum1=tnum2=0; | |
764 file_open=1; | |
765 file_initialized=0; | |
766 | |
767 } | |
768 | |
769 | |
770 | |
771 /* ----- open_index_file ------- */ | |
772 void open_index_file (fnam) | |
773 char fnam[]; | |
774 { | |
775 if (vb>=8) printf("Open index file \"%s\"\n", fnam); | |
776 if ((findex = fopen (fnam,"w")) == NULL) | |
777 rx ("Cannot open index file: ", fnam); | |
778 | |
779 index_initialized=0; | |
780 | |
781 } | |
782 | |
783 /* ----- close_index_file ------- */ | |
784 void close_index_file () | |
785 { | |
786 | |
787 if (vb>=8) printf("Close index file\n"); | |
788 | |
789 close_index_page (findex); | |
790 | |
791 fclose (findex); | |
792 | |
793 } | |
794 | |
795 /* ----- add_to_text_block ----- */ | |
796 void add_to_text_block (ln,add_final_nl) | |
797 char ln[]; | |
798 int add_final_nl; | |
799 { | |
800 char *c,*a; | |
801 char word[81]; | |
802 int nt,nl; | |
803 | |
804 nt=ntxt; | |
805 c=ln; | |
806 | |
807 for (;;) { | |
808 while (*c==' ') c++; | |
809 if (*c=='\0') break; | |
810 a=word; | |
811 while ((*c!=' ')&&(*c!='\0')&&(*c!='\n')) { | |
812 nl=0; | |
813 if ((*c=='\\')&&(*(c+1)=='\\')) { | |
814 nl=1; | |
815 c+=2; | |
816 break; | |
817 } | |
818 *a=*c; | |
819 c++; | |
820 a++; | |
821 | |
822 } | |
823 *a='\0'; | |
824 if (strlen(word)>MAXWLEN) { | |
825 word[MAXWLEN-1]='\0'; | |
826 printf ("+++ Insanely long word truncated to %d chars: %s\n", | |
827 MAXWLEN-1,word); | |
828 } | |
829 if (nt>=MAXNTEXT) { | |
830 printf ("\n+++ Line %d: %s\n", linenum,ln); | |
831 rx("Text overflow; increase MAXNTEXT and recompile.",""); | |
832 } | |
833 if (strlen(word)>0) { | |
834 strcpy(txt[nt],word); | |
835 nt++; | |
836 } | |
837 if (nl) { | |
838 strcpy(txt[nt],"$$NL$$"); | |
839 nt++; | |
840 } | |
841 } | |
842 if (add_final_nl) { | |
843 strcpy(txt[nt],"$$NL$$"); | |
844 nt++; | |
845 } | |
846 | |
847 ntxt=nt; | |
848 | |
849 } | |
850 | |
851 | |
852 /* ----- write_text_block ----- */ | |
853 void write_text_block (fp,job) | |
854 FILE *fp; | |
855 int job; | |
856 { | |
857 int i,i1,i2,ntline,nc,mc,nbreak; | |
858 float textwidth,ftline,ftline0,swfac,baseskip,parskip; | |
859 float wwidth,wtot,spw; | |
860 char str[81]; | |
861 | |
862 if (ntxt<=0) return; | |
863 | |
864 baseskip = cfmt.textfont.size * cfmt.lineskipfac; | |
865 parskip = cfmt.textfont.size * cfmt.parskipfac; | |
866 set_font_str (page_init,cfmt.textfont); | |
867 | |
868 /* estimate text widths.. ok for T-R, wild guess for other fonts */ | |
869 swfac=1.0; | |
870 if (strstr(cfmt.textfont.name,"Times-Roman")) swfac=1.00; | |
871 if (strstr(cfmt.textfont.name,"Times-Bold")) swfac=1.05; | |
872 if (strstr(cfmt.textfont.name,"Helvetica")) swfac=1.10; | |
873 if (strstr(cfmt.textfont.name,"Helvetica-Bold")) swfac=1.15; | |
874 if (strstr(cfmt.textfont.name,"Palatino")) swfac=1.10; | |
875 swfac=1.0; | |
876 spw=cwid(' '); | |
877 PUT1("/LF {0 %.1f rmoveto} bind def\n",-baseskip) | |
878 | |
879 /* output by pieces, separate at newline token */ | |
880 i1=0; | |
881 while (i1<ntxt) { | |
882 i2=-1; | |
883 for (i=i1;i<ntxt;i++) if(!strcmp(txt[i],"$$NL$$")) {i2=i; break; } | |
884 if (i2==-1) i2=ntxt; | |
885 bskip(baseskip); | |
886 | |
887 if (job==OBEYLINES) { | |
888 PUT0("0 0 M (") | |
889 for (i=i1;i<i2;i++) { | |
890 tex_str(txt[i],str,&wwidth); | |
891 PUT1("%s ",str); | |
892 } | |
893 PUT0(") rshow\n") | |
894 } | |
895 | |
896 else if (job==OBEYCENTER) { | |
897 PUT1("%.1f 0 M (",cfmt.staffwidth/2) | |
898 for (i=i1;i<i2;i++) { | |
899 tex_str(txt[i],str,&wwidth); | |
900 PUT1("%s",str) | |
901 if (i<i2-1) PUT0(" ") | |
902 } | |
903 PUT0(") cshow\n") | |
904 } | |
905 | |
906 else { | |
907 PUT0("0 0 M mark\n") | |
908 nc=0; | |
909 mc=-1; | |
910 wtot=-spw; | |
911 for (i=i2-1;i>=i1;i--) { | |
912 mc+=tex_str(txt[i],str,&wwidth)+1; | |
913 wtot+=wwidth+spw; | |
914 nc+=strlen(str)+2; | |
915 if (nc>=72) {nc=0; PUT0("\n") } | |
916 PUT1 ("(%s)",str); | |
917 } | |
918 if (job==RAGGED) | |
919 PUT1(" %.1f P1\n",cfmt.staffwidth) | |
920 else | |
921 PUT1(" %.1f P2\n",cfmt.staffwidth) | |
922 /* first estimate: (total textwidth)/(available width) */ | |
923 textwidth=wtot*swfac*cfmt.textfont.size; | |
924 if (strstr(cfmt.textfont.name,"Courier")) | |
925 textwidth=0.60*mc*cfmt.textfont.size; | |
926 ftline0=textwidth/cfmt.staffwidth; | |
927 /* revised estimate: assume some chars lost at each line end */ | |
928 nbreak=ftline0; | |
929 textwidth=textwidth+5*nbreak*cwid('a')*swfac*cfmt.textfont.size; | |
930 ftline=textwidth/cfmt.staffwidth; | |
931 ntline=ftline+1.0; | |
932 if (vb>=10) | |
933 printf("first estimate %.2f, revised %.2f\n", ftline0,ftline); | |
934 if (vb>=10) | |
935 printf("Output %d word%s, about %.2f lines (fac %.2f)\n", | |
936 i2-i1, i2-i1==1?"":"s", ftline,swfac); | |
937 bskip((ntline-1)*baseskip); | |
938 } | |
939 | |
940 buffer_eob (fp); | |
941 /* next line to allow pagebreak after each text "line" */ | |
942 /* if (!epsf && !within_tune) write_buffer(fp); */ | |
943 i1=i2+1; | |
944 } | |
945 bskip(parskip); | |
946 buffer_eob (fp); | |
947 /* next line to allow pagebreak after each paragraph */ | |
948 if (!epsf && !within_tune) write_buffer(fp); | |
949 strcpy (page_init,""); | |
950 return; | |
951 } | |
952 | |
953 | |
954 | |
955 /* ----- put_words ------- */ | |
956 void put_words (fp) | |
957 FILE *fp; | |
958 { | |
959 int i,nw,n; | |
960 char str[81]; | |
961 char *p,*q; | |
962 | |
963 set_font (fp,cfmt.wordsfont, 0); | |
964 set_font_str (page_init,cfmt.wordsfont); | |
965 | |
966 n=0; | |
967 for (i=0;i<ntext;i++) if (text_type[i]==TEXT_W) n++; | |
968 if (n==0) return; | |
969 | |
970 bskip(cfmt.wordsspace); | |
971 for (i=0;i<ntext;i++) { | |
972 if (text_type[i]==TEXT_W) { | |
973 bskip(cfmt.lineskipfac*cfmt.wordsfont.size); | |
974 p=&text[i][0]; | |
975 q=&str[0]; | |
976 if (isdig(text[i][0])) { | |
977 while (*p != '\0') { | |
978 *q=*p; | |
979 q++; | |
980 p++; | |
981 if (*p==' ') break; | |
982 if (*(p-1)==':') break; | |
983 if (*(p-1)=='.') break; | |
984 } | |
985 if (*p==' ') p++; | |
986 } | |
987 *q='\0'; | |
988 | |
989 /* permit page break at empty lines or stanza start */ | |
990 nw=nwords(text[i]); | |
991 if ((nw==0) || (strlen(str)>0)) buffer_eob(fp); | |
992 | |
993 if (nw>0) { | |
994 if (strlen(str)>0) { | |
995 PUT0("45 0 M (") | |
996 put_str (str); | |
997 PUT0(") lshow\n") | |
998 } | |
999 if (strlen(p)>0) { | |
1000 PUT0("50 0 M (") | |
1001 put_str (p); | |
1002 PUT0(") rshow\n") | |
1003 } | |
1004 } | |
1005 } | |
1006 } | |
1007 | |
1008 buffer_eob (fp); | |
1009 strcpy (page_init,""); | |
1010 | |
1011 } | |
1012 | |
1013 /* ----- put_text ------- */ | |
1014 void put_text (fp, type, str) | |
1015 FILE *fp; | |
1016 int type; | |
1017 char str[]; | |
1018 { | |
1019 int i,n; | |
1020 float baseskip,parskip; | |
1021 | |
1022 n=0; | |
1023 for (i=0;i<ntext;i++) if (text_type[i]==type) n++; | |
1024 if (n==0) return; | |
1025 | |
1026 baseskip = cfmt.textfont.size * cfmt.lineskipfac; | |
1027 parskip = cfmt.textfont.size * cfmt.parskipfac; | |
1028 PUT0("0 0 M\n") | |
1029 ntxt=0; | |
1030 add_to_text_block(str,0); | |
1031 for (i=0;i<ntext;i++) { | |
1032 if (text_type[i]==type) add_to_text_block(text[i],1); | |
1033 } | |
1034 write_text_block (fp,RAGGED); | |
1035 buffer_eob (fp); | |
1036 | |
1037 } | |
1038 | |
1039 /* ----- put_history ------- */ | |
1040 void put_history (fp) | |
1041 FILE *fp; | |
1042 { | |
1043 int i,ok; | |
1044 float baseskip,parskip; | |
1045 | |
1046 set_font (fp, cfmt.textfont,0); | |
1047 set_font_str (page_init,cfmt.textfont); | |
1048 baseskip = cfmt.textfont.size * cfmt.lineskipfac; | |
1049 parskip = cfmt.textfont.size * cfmt.parskipfac; | |
1050 | |
1051 bskip(cfmt.textspace); | |
1052 | |
1053 if (strlen(info.rhyth)>0) { | |
1054 bskip(baseskip); | |
1055 PUT0("0 0 M (Rhythm: ") | |
1056 put_str (info.rhyth); | |
1057 PUT0(") show\n") | |
1058 bskip(parskip); | |
1059 } | |
1060 | |
1061 if (strlen(info.book)>0) { | |
1062 bskip(0.5*CM); | |
1063 PUT0("0 0 M (Book: ") | |
1064 put_str (info.book); | |
1065 PUT0(") show\n") | |
1066 bskip(parskip); | |
1067 } | |
1068 | |
1069 if (strlen(info.src)>0) { | |
1070 bskip(0.5*CM); | |
1071 PUT0("0 0 M (Source: ") | |
1072 put_str (info.src); | |
1073 PUT0(") show\n") | |
1074 bskip(parskip); | |
1075 } | |
1076 | |
1077 put_text (fp, TEXT_D, "Discography: "); | |
1078 put_text (fp, TEXT_N, "Notes: "); | |
1079 put_text (fp, TEXT_Z, "Transcription: "); | |
1080 | |
1081 ok=0; | |
1082 for (i=0;i<ntext;i++) { | |
1083 if (text_type[i]==TEXT_H) { | |
1084 bskip(0.5*CM); | |
1085 PUT0("0 0 M (") | |
1086 put_str (text[i]); | |
1087 PUT0(") show\n") | |
1088 ok=1; | |
1089 } | |
1090 } | |
1091 if (ok) bskip(parskip); | |
1092 buffer_eob (fp); | |
1093 strcpy (page_init,""); | |
1094 | |
1095 } | |
1096 | |
1097 | |
1098 /* ----- write_inside_title ----- */ | |
1099 void write_inside_title (fp) | |
1100 FILE *fp; | |
1101 { | |
1102 char t[201]; | |
1103 | |
1104 if (numtitle==1) strcpy (t,info.title); | |
1105 else if (numtitle==2) strcpy (t,info.title2); | |
1106 else if (numtitle==3) strcpy (t,info.title3); | |
1107 if (vb>15) printf ("write inside title <%s>\n", t); | |
1108 if (strlen(t)==0) return; | |
1109 | |
1110 bskip (cfmt.subtitlefont.size+0.2*CM); | |
1111 set_font (fp, cfmt.subtitlefont, 0); | |
1112 | |
1113 if (cfmt.titlecaps) cap_str(t); | |
1114 PUT0(" (") | |
1115 put_str (t); | |
1116 if (cfmt.titleleft) PUT0(") 0 0 M rshow\n") | |
1117 else PUT1(") %.1f 0 M cshow\n", cfmt.staffwidth/2) | |
1118 bskip (cfmt.musicspace+0.2*CM); | |
1119 | |
1120 } | |
1121 | |
1122 | |
1123 /* ----- write_tunetop ----- */ | |
1124 void write_tunetop(fp) | |
1125 FILE *fp; | |
1126 { | |
1127 | |
1128 PUT2("\n\n%% --- tune %d %s\n", tunenum+1, info.title) | |
1129 if (!epsf) bskip (cfmt.topspace); | |
1130 } | |
1131 | |
1132 | |
1133 /* ----- write_tempo ----- */ | |
1134 void write_tempo(fp,tempo,meter) | |
1135 FILE *fp; | |
1136 char tempo[]; | |
1137 struct METERSTR meter; | |
1138 { | |
1139 char *r, *q; | |
1140 char text[STRL]; | |
1141 int top,bot,value,len,i,err,fac,dig,div,rc; | |
1142 struct SYMBOL s; | |
1143 float stem,dotx,doty,sc,dx; | |
1144 | |
1145 if (vb>15) printf ("write tempo <%s>\n", info.tempo); | |
1146 r=tempo; | |
1147 p0=tempo; | |
1148 set_font (fp,cfmt.tempofont,0); | |
1149 PUT0(" 18 0 M\n") | |
1150 | |
1151 for (;;) { | |
1152 | |
1153 while (*r==' ') r++; /* skip blanks */ | |
1154 if (*r=='\0') break; | |
1155 | |
1156 if (*r=='"') { /* write string */ | |
1157 r++; | |
1158 q=text; | |
1159 while (*r!='"' && *r!='\0') { *q=*r; r++; q++; } | |
1160 if (*r=='"') r++; | |
1161 *q='\0'; | |
1162 if (strlen(text)>0) { | |
1163 PUT0("6 0 rmoveto (") | |
1164 put_str (text); | |
1165 PUT0(") rshow 12 0 \n") | |
1166 } | |
1167 } | |
1168 | |
1169 else { /* write tempo denotation */ | |
1170 q=text; | |
1171 while (*r!=' ' && *r!='\0') { *q=*r; r++; q++; } | |
1172 *q='\0'; | |
1173 q=text; | |
1174 | |
1175 len=QUARTER; | |
1176 value=0; | |
1177 err=0; | |
1178 if (strchr(q,'=')) { | |
1179 if ((*q=='C') || (*q=='c')) { | |
1180 q++; | |
1181 | |
1182 len=meter.dlen; | |
1183 div=0; | |
1184 if (*q=='/') { div=1; q++; } | |
1185 fac=0; | |
1186 while (isdig(*q)) { dig=*q-'0'; fac=10*fac+dig; q++; } | |
1187 | |
1188 if (div) { | |
1189 if (fac==0) fac=2; | |
1190 if (len%fac) printf ("Bad length divisor in tempo: %s", text… | |
1191 len=len/fac; | |
1192 } | |
1193 else | |
1194 if (fac>0) len=len*fac; | |
1195 if (*q!='=') err=1; | |
1196 q++; | |
1197 if (!isdig(*q)) err=1; | |
1198 sscanf(q,"%d", &value); | |
1199 } | |
1200 else if (isdig(*q)) { | |
1201 sscanf(q,"%d/%d=%d", &top,&bot,&value); | |
1202 len=(BASE*top)/bot; | |
1203 } | |
1204 else err=1; | |
1205 } | |
1206 else { | |
1207 if (isdig(*q)) | |
1208 sscanf(q,"%d", &value); | |
1209 else err=1; | |
1210 } | |
1211 | |
1212 s.len=len; | |
1213 rc = idfy_note (&s); | |
1214 if (rc) err=1; | |
1215 if (err) /* draw note=value */ | |
1216 printf("\n+++ invalid tempo specifier: %s\n", text); | |
1217 else { | |
1218 sc=0.55*cfmt.tempofont.size/10.0; | |
1219 PUT2("gsave %.2f %.2f scale 15 3 rmoveto currentpoint\n", sc,sc) | |
1220 if (s.head==H_OVAL) PUT0("HD") | |
1221 if (s.head==H_EMPTY) PUT0("Hd") | |
1222 if (s.head==H_FULL) PUT0("hd") | |
1223 dx=4.0; | |
1224 if (s.dots) { | |
1225 dotx=8; doty=0; | |
1226 if (s.flags>0) dotx=dotx+4; | |
1227 if (s.head==H_EMPTY) dotx=dotx+1; | |
1228 if (s.head==H_OVAL) dotx=dotx+2; | |
1229 for (i=0;i<s.dots;i++) { | |
1230 PUT2(" %.1f %.1f dt", dotx, doty) | |
1231 dx=dotx; | |
1232 dotx=dotx+3.5; | |
1233 } | |
1234 } | |
1235 stem=16.0; | |
1236 if (s.flags>1) stem=stem+3*(s.flags-1); | |
1237 if (s.len<WHOLE) PUT1(" %.1f su",stem) | |
1238 if (s.flags>0) PUT2(" %.1f f%du",stem,s.flags) | |
1239 if ((s.flags>0) && (dx<6.0)) dx=6.0; | |
1240 dx=(dx+18)*sc; | |
1241 PUT2(" grestore %.2f 0 rmoveto ( = %d) rshow\n", dx,value) | |
1242 } | |
1243 } | |
1244 } | |
1245 } | |
1246 | |
1247 | |
1248 /* ----- write_inside_tempo ----- */ | |
1249 void write_inside_tempo (fp) | |
1250 FILE *fp; | |
1251 { | |
1252 | |
1253 bskip (cfmt.partsfont.size); | |
1254 write_tempo(fp,info.tempo,default_meter); | |
1255 bskip (0.1*CM); | |
1256 } | |
1257 | |
1258 /* ----- write_heading ----- */ | |
1259 void write_heading (fp) | |
1260 FILE *fp; | |
1261 { | |
1262 float lwidth,down1,down2; | |
1263 int i,ncl; | |
1264 char t[201]; | |
1265 | |
1266 lwidth=cfmt.staffwidth; | |
1267 | |
1268 /* write the main title */ | |
1269 bskip (cfmt.titlefont.size+cfmt.titlespace); | |
1270 set_font (fp,cfmt.titlefont,1); | |
1271 if (cfmt.withxrefs) PUT1("%d. ", xrefnum) | |
1272 strcpy (t,info.title); | |
1273 if (cfmt.titlecaps) cap_str(t); | |
1274 put_str (t); | |
1275 if (cfmt.titleleft) PUT0(") 0 0 M rshow\n") | |
1276 else PUT1(") %.1f 0 M cshow\n", lwidth/2) | |
1277 | |
1278 /* write second title */ | |
1279 if (numtitle>=2) { | |
1280 bskip (cfmt.subtitlespace+cfmt.subtitlefont.size); | |
1281 set_font (fp,cfmt.subtitlefont,1); | |
1282 strcpy (t,info.title2); | |
1283 if (cfmt.titlecaps) cap_str(t); | |
1284 put_str (t); | |
1285 if (cfmt.titleleft) PUT0(") 0 0 M rshow\n") | |
1286 else PUT1(") %.1f 0 M cshow\n", lwidth/2) | |
1287 } | |
1288 | |
1289 /* write third title */ | |
1290 if (numtitle>=3) { | |
1291 bskip (cfmt.subtitlespace+cfmt.subtitlefont.size); | |
1292 set_font (fp,cfmt.subtitlefont,1); | |
1293 strcpy (t,info.title3); | |
1294 if (cfmt.titlecaps) cap_str(t); | |
1295 put_str (t); | |
1296 if (cfmt.titleleft) PUT0(") 0 0 M rshow\n") | |
1297 else PUT1(") %.1f 0 M cshow\n", lwidth/2) | |
1298 } | |
1299 | |
1300 /* write composer, origin */ | |
1301 if ((info.ncomp>0) || (strlen(info.orig)>0)) { | |
1302 set_font (fp,cfmt.composerfont,0); | |
1303 bskip(cfmt.composerspace); | |
1304 ncl=info.ncomp; | |
1305 if ((strlen(info.orig)>0) && (ncl<1)) ncl=1; | |
1306 for (i=0;i<ncl;i++) { | |
1307 bskip(cfmt.composerfont.size); | |
1308 PUT1("%.1f 0 M (", lwidth) | |
1309 put_str (info.comp[i]); | |
1310 if ((i==ncl-1)&&(strlen(info.orig)>0)) { | |
1311 put_str (" ("); | |
1312 put_str (info.orig); | |
1313 put_str (")"); | |
1314 } | |
1315 PUT0 (") lshow\n"); | |
1316 } | |
1317 down1=cfmt.composerspace+cfmt.musicspace+ncl*cfmt.composerfont.size; | |
1318 } | |
1319 else { | |
1320 bskip(cfmt.composerfont.size+cfmt.composerspace); | |
1321 down1=cfmt.composerspace+cfmt.musicspace+cfmt.composerfont.size; | |
1322 } | |
1323 bskip (cfmt.musicspace); | |
1324 | |
1325 /* decide whether we need extra shift for parts and tempo */ | |
1326 down2=cfmt.composerspace+cfmt.musicspace; | |
1327 if (strlen(info.parts)>0) down2=down2+cfmt.partsspace+cfmt.partsfont.s… | |
1328 if (strlen(info.tempo)>0) down2=down2+cfmt.partsspace+cfmt.partsfont.s… | |
1329 if (down2>down1) bskip (down2-down1); | |
1330 | |
1331 /* write tempo and parts */ | |
1332 if (strlen(info.parts)>0 || strlen(info.tempo)>0) { | |
1333 | |
1334 if (strlen(info.tempo)>0) { | |
1335 bskip (-0.2*CM); | |
1336 PUT1 (" %.2f 0 T ", cfmt.indent*cfmt.scale) | |
1337 write_tempo(fp, info.tempo, default_meter); | |
1338 PUT1 (" %.2f 0 T ", -cfmt.indent*cfmt.scale) | |
1339 bskip (-cfmt.tempofont.size); | |
1340 } | |
1341 | |
1342 if (strlen(info.parts)>0) { | |
1343 bskip (-cfmt.partsspace); | |
1344 set_font (fp,cfmt.partsfont,0); | |
1345 PUT0("0 0 M (") | |
1346 put_str (info.parts); | |
1347 PUT0(") rshow\n") | |
1348 bskip (cfmt.partsspace); | |
1349 } | |
1350 | |
1351 if (strlen(info.tempo)>0) bskip (cfmt.tempofont.size+0.3*CM); | |
1352 | |
1353 } | |
1354 | |
1355 | |
1356 } | |
1357 | |
1358 /* ----- write_parts ----- */ | |
1359 void write_parts (fp) | |
1360 FILE *fp; | |
1361 { | |
1362 if (strlen(info.parts)>0) { | |
1363 bskip (cfmt.partsfont.size); | |
1364 set_font (fp, cfmt.partsfont,0); | |
1365 PUT0("0 0 M (") | |
1366 put_str (info.parts); | |
1367 PUT0(") rshow\n") | |
1368 bskip(cfmt.partsspace); | |
1369 } | |
1370 } | |
1371 | |
1372 |