1 /* Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2 * 2006 by Arkkra Enterprises */
3 /* All rights reserved */
7 * Description: This file defines the instances of score, staff, and voice
8 * structures that are used for viewpathing. It also contains
9 * functions for accessing them.
20 /* define the default order of stacking for marks */
21 static char Defmarkorder
[] = {
33 /* default timesig of 4/4 */
34 static char Dflt_timerep
[] = { 4, TSR_SLASH
, 4, TSR_END
};
36 static void freestaffset
P((int num
, struct STAFFSET
*ss_p
));
37 static void asgnstaffset
P((int num
, struct STAFFSET
**new_p_p
,
38 struct STAFFSET
*old_p
));
39 static void setorder
P((int place
, struct SSV
*i_p
, struct SSV
*f_p
));
44 * Abstract: Init the fixed instances of the SSV structures.
48 * Description: This function initializes all the fixed structures Score,
49 * Staff[s], and Voice[s][v]. This needs to be done before
50 * scanning through the main linked list of user input
58 int s
; /* staff number */
59 int v
; /* voice number */
60 int n
; /* another loop variable */
61 int p
; /* place (PL_*) */
62 int m
; /* mark (MK_*) */
63 int hs
; /* head shape number */
67 * Call zapssv() to release any malloc'ed memory, if any of the
68 * structures have been used before, and mark all fields unused.
72 for (s
= 0; s
< MAXSTAFFS
; s
++) {
74 for (v
= 0; v
< MAXVOICES
; v
++)
79 * Fill the Score structure with the proper default values, and
80 * mark all its fields as used.
83 Score
.scale_factor
= DEFSCALE
;
85 Score
.pageheight
= DEFPAGEHEIGHT
;
86 Score
.pagewidth
= DEFPAGEWIDTH
;
87 Score
.panelsperpage
= DEFPANELSPERPAGE
;
88 Score
.topmargin
= DEFVMARGIN
;
89 Score
.botmargin
= DEFVMARGIN
;
90 Score
.leftmargin
= DEFHMARGIN
;
91 Score
.rightmargin
= DEFHMARGIN
;
92 Score
.restcombine
= NORESTCOMBINE
;
93 Score
.firstpage
= NOFIRSTPAGE
;
94 Score
.staffs
= DEFSTAFFS
;
95 Score
.minscsep
= DEFMINSCSEP
;
96 Score
.maxscsep
= DEFMAXSCSEP
;
97 Score
.minscpad
= DEFMINSCPAD
;
98 Score
.maxscpad
= DEFMAXSCPAD
;
102 Score
.timerep
= Dflt_timerep
;
107 Score
.division
= DEFDIVISION
;
108 Score
.endingstyle
= ENDING_TOP
;
109 Score
.gridsatend
= NO
;
111 Score
.measnumfamily
= BASE_TIMES
;
112 Score
.measnumfont
= FONT_TR
;
113 Score
.measnumsize
= MNUM_SIZE
;
114 Score
.packfact
= DFLTPACKFACT
;
115 Score
.packexp
= DFLTPACKEXP
;
118 /* score and staff context */
119 Score
.staffscale
= DEFSTFSCALE
;
121 Score
.hidesilent
= NO
;
122 Score
.stafflines
= 5;
124 Score
.printclef
= SS_NORMAL
;
125 Score
.gridswhereused
= NO
;
126 Score
.gridscale
= DEFGRIDSCALE
;
127 Score
.gridfret
= DEFGRIDFRET
;
128 Score
.numbermrpt
= YES
;
129 Score
.printmultnum
= YES
;
130 Score
.restsymmult
= NO
;
132 for (v
= 0; v
< MAXVOICES
; v
++) {
133 Score
.vcombine
[v
] = 0;
135 Score
.vcombinequal
= VC_NOOVERLAP
;
136 Score
.sharps
= DEFSHARPS
;
138 Score
.cancelkey
= NO
;
139 Score
.inttype
= PERFECT
;
141 Score
.addinttype
= PERFECT
;
144 Score
.rehstyle
= RS_BOXED
;
145 Score
.fontfamily
= BASE_TIMES
;
146 Score
.font
= FONT_TR
;
147 Score
.size
= DFLT_SIZE
;
148 Score
.lyricsfamily
= BASE_TIMES
;
149 Score
.lyricsfont
= FONT_TR
;
150 Score
.lyricssize
= DFLT_SIZE
;
151 Score
.lyricsalign
= DEFLYRICSALIGN
;
152 Score
.sylposition
= DEFSYLPOSITION
;
153 Score
.minstsep
= DEFMINSTSEP
;
154 Score
.staffpad
= DEFSTPAD
;
155 for (p
= 0; p
< NUM_PLACE
; p
++) {
156 for (m
= 0; m
< NUM_MARK
; m
++) {
157 Score
.markorder
[p
][m
] = Defmarkorder
[m
];
160 Score
.pedstyle
= P_LINE
;
161 Score
.chorddist
= DEFCHORDDIST
;
162 Score
.dist
= DEFDIST
;
163 Score
.dyndist
= DEFDYNDIST
;
167 /* score, staff, and voice context */
170 Score
.beamfact
= DEFBEAMFACT
;
171 Score
.beammax
= DEFBEAMMAX
;
173 Score
.stemlen
= DEFSTEMLEN
;
174 Score
.stemshorten
= DEFSTEMSHORTEN
;
175 Score
.defoct
= DEFOCTAVE
;
176 Score
.timeunit
.n
= 1;
177 Score
.timeunit
.d
= 4;
178 Score
.timelist_p
= 0;
179 Score
.swingunit
= Zero
;
180 Score
.release
= DEFRELEASE
;
181 Score
.ontheline
= YES
;
182 Score
.tabwhitebox
= NO
;
183 hs
= get_shape_num("norm");
184 for (n
= 0; n
< 7; n
++) {
185 Score
.noteheads
[n
] = hs
;
188 for (n
= 0; n
< NUMFLDS
; n
++) {
189 Score
.used
[n
] = YES
; /* all items will be set in Score */
196 * Abstract: Init a fixed instance of the SSV structure to empty.
200 * Description: This function initializes a fixed SSV structure to say that
201 * all fields are unused.
207 struct SSV
*s_p
; /* pointer to the structure to be zapped */
210 int n
; /* loop variable */
214 * If the structure has been used before, we first have to free any
215 * memory that was malloc'ed. It's okay to check "used" the first
216 * time, because global variables are set to 0 by the compiler;
217 * thus, used[X] == NO.
219 if (s_p
->used
[BRACELIST
] == YES
) {
220 freestaffset(s_p
->nbrace
, s_p
->bracelist
);
223 if (s_p
->used
[BRACKLIST
] == YES
) {
224 freestaffset(s_p
->nbrack
, s_p
->bracklist
);
227 if (s_p
->used
[BARSTLIST
] == YES
&& s_p
->barstlist
!= 0) {
228 FREE(s_p
->barstlist
);
231 if (s_p
->used
[LABEL
] == YES
&& s_p
->label
!= 0) {
235 if (s_p
->used
[LABEL2
] == YES
&& s_p
->label2
!= 0) {
239 if (s_p
->used
[BEAMSTLIST
] == YES
&& s_p
->beamstlist
!= 0) {
240 FREE(s_p
->beamstlist
);
245 * Mark all fields unused.
247 for (n
= 0; n
< NUMFLDS
; n
++) {
253 * Name: freestaffset()
255 * Abstract: Free all malloc'ed memory associated with a staffset list.
259 * Description: This function frees staffset structures, along with their
260 * labels if they exist.
264 freestaffset(num
, ss_p
)
266 int num
; /* how many staffsets are in list? */
267 struct STAFFSET
*ss_p
; /* pointer to first staffset */
270 int n
; /* loop variable */
273 if (ss_p
== 0) /* if there is no list, just return */
276 /* for each staffset in the list, free labels if present */
277 for (n
= 0; n
< num
; n
++) {
278 if (ss_p
[n
].label
!= 0) { /* if label, free it */
282 if (ss_p
[n
].label2
!= 0) { /* if label2, free it */
283 FREE(ss_p
[n
].label2
);
288 FREE(ss_p
); /* free the staffset list itself */
292 * Name: asgnstaffset()
294 * Abstract: Set up a staffset list in another SSV structure.
298 * Description: This function sets up a new staffset list identical to
299 * another one, including the labels if they exist.
303 asgnstaffset(num
, new_p_p
, old_p
)
305 int num
; /* how many staffsets are in list? */
306 struct STAFFSET
**new_p_p
; /* ptr to ptr to first staffset of new list */
307 struct STAFFSET
*old_p
; /* pointer to first staffset of old list */
310 int n
; /* loop variable */
313 if (num
== 0) /* if there's no old list, nothing to do */
317 * Allocate the new list and point at it.
319 MALLOC(STAFFSET
, *new_p_p
, num
);
322 * Loop through the old list. Wherever there is a label, allocate
323 * one for the new list. When there isn't, set that pointer to null.
325 for (n
= 0; n
< num
; n
++) {
326 (*new_p_p
)[n
].topstaff
= old_p
[n
].topstaff
;
327 (*new_p_p
)[n
].botstaff
= old_p
[n
].botstaff
;
329 if (old_p
[n
].label
!= 0) {
330 MALLOCA(char, (*new_p_p
)[n
].label
,
331 strlen(old_p
[n
].label
) + 1);
332 (void)strcpy((*new_p_p
)[n
].label
, old_p
[n
].label
);
334 (*new_p_p
)[n
].label
= 0;
337 if (old_p
[n
].label2
!= 0) {
338 MALLOCA(char, (*new_p_p
)[n
].label2
,
339 strlen(old_p
[n
].label2
) + 1);
340 (void)strcpy((*new_p_p
)[n
].label2
, old_p
[n
].label2
);
342 (*new_p_p
)[n
].label2
= 0;
350 * Abstract: Find a field for a staff, using the viewpath.
352 * Returns: pointer to structure containing correct field value
354 * Description: This function, given a staff number and a field number, looks
355 * down the viewpath to find the first structure where the field
356 * is set. It returns a pointer to that structure. (However, see
357 * below for a special kluge for the "visible" field.)
358 * Note: 0 is allowed for the staff number, and that means use
365 int s
; /* staff number, 1 to MAXSTAFFS; or 0, meaning score */
366 int field
; /* the defined symbol for the field desired */
369 static struct SSV phony
; /* phony SSV; see below */
376 * For the "visible" field, special kluges are needed, for two reasons.
377 * One is that there is a command line option (-s) that overrides the
378 * visibility requests in the Mup input file. The other is that, even
379 * though it is a score/staff/voice parameter, it is easier to manage
380 * visibility at the staff level than at the voice level. Otherwise,
381 * to know if a staff should be drawn, we would have to check vscheme
382 * and the visibility state of each voice.
384 * The design is as follows: in mkchords.c, if a voice is to be
385 * invisible, a measure space is put in place of its original GRPSYL
386 * list. Users can use svpath() to check if a staff is visible
387 * instead of having to call vvpath() for its voice(s). The field
388 * staff_p->visible is set by calling here, so that will also be
391 * If the -s option was used on the command line, only staffs/voices
392 * listed there are ever allowed to be visible. So although SSVs are
393 * set as for other score/staff/voice parameters, the results from
394 * svpath() also consider what the -s option said. In vvpath() this
397 if (field
== VISIBLE
) {
398 int num_voices
; /* how many voices on this staff */
401 * In case we are going to return the phony SSV, load the
402 * hidesilent field into it. Both visible and hidesilent are
403 * controlled by VISIBLE, but hidesilent is not to be affected
404 * by the kluges needed for "visible".
406 /* if the field is set in the staff structure, use that */
407 if (Staff
[s
-1].used
[VISIBLE
] == YES
) {
408 phony
.hidesilent
= Staff
[s
-1].hidesilent
;
410 /* use the score structure; it's always set there */
411 phony
.hidesilent
= Score
.hidesilent
;
414 /* always return NO if the command line says staff invisible */
415 if (Staff_vis
[s
] == NO
) {
416 /* return phony SSV with NO, ignore real SSV */
421 num_voices
= vscheme_voices(svpath(s
, VSCHEME
)->vscheme
);
424 * If a voice that the command line is allowing to be visible
425 * was requested via an SSV to be visible, we must let the
428 if ((Voice_vis
[s
][1] == YES
&&
429 Voice
[s
-1][0].used
[VISIBLE
] == YES
&&
430 Voice
[s
-1][0].visible
== YES
) ||
433 Voice_vis
[s
][2] == YES
&&
434 Voice
[s
-1][1].used
[VISIBLE
] == YES
&&
435 Voice
[s
-1][1].visible
== YES
) ||
438 Voice_vis
[s
][3] == YES
&&
439 Voice
[s
-1][2].used
[VISIBLE
] == YES
&&
440 Voice
[s
-1][2].visible
== YES
)) {
442 /* return phony SSV with YES, ignore real SSV */
448 * If, for each voice that exists, either the command line is
449 * forcing it to be invisible or else it was requested via an
450 * SSV to be invisible, then the staff must be invisible.
452 if ((Voice_vis
[s
][1] == NO
||
453 Voice
[s
-1][0].used
[VISIBLE
] == YES
&&
454 Voice
[s
-1][0].visible
== NO
) &&
457 (Voice_vis
[s
][2] == NO
||
458 Voice
[s
-1][1].used
[VISIBLE
] == YES
&&
459 Voice
[s
-1][1].visible
== NO
)) &&
462 (Voice_vis
[s
][3] == NO
||
463 Voice
[s
-1][2].used
[VISIBLE
] == YES
&&
464 Voice
[s
-1][2].visible
== NO
))) {
466 /* return phony SSV with NO, ignore real SSV */
472 * The command line and the voice(s) aren't forcing the issue.
473 * So fall through to determine the staff's visibility the
478 /* if the field is set in the staff structure, use that */
479 if (Staff
[s
-1].used
[field
] == YES
)
480 return (&Staff
[s
-1]);
482 /* else use the score structure; it's always set there */
489 * Abstract: Find a field for a voice, using the viewpath.
491 * Returns: pointer to structure containing correct field value
493 * Description: This function, given a staff number, voice number on that
494 * staff, and a field number, looks down the viewpath to find
495 * the first structure where the field is set. It returns a
496 * pointer to that structure. (However, see below for a special
497 * kluge for the "visible" field.)
498 * Note: 0 is allowed for the voice number, and that means use
499 * the staff's value. If staff is 0, the Score is used,
500 * regardless of the voice number.
506 int s
; /* staff number, 1 to MAXSTAFFS; or 0, meaning score */
507 int v
; /* voice number, 1 to MAXVOICES; or 0, meaning staff */
508 int field
; /* the defined symbol for the field desired */
511 static struct SSV phony
; /* phony SSV; see below */
514 if (s
== 0 || v
== 0)
515 return (svpath(s
, field
));
518 * See the comment in svpath() regarding the "visible" field. There's
519 * probably no need to call vvpath() for "visible" after mkchords.c has
520 * run, since voices that are to be invisible are changed to measure
521 * spaces there. But in mkchords.c itself, and earlier, there is
524 * For the "visible" field, first check the command line to see if this
525 * voice or its staff must always be invisible. If so, return a phony
526 * SSV that says that. Otherwise fall through to handle the normal way.
528 if (field
== VISIBLE
&& (Staff_vis
[s
] == NO
|| Voice_vis
[s
][v
] == NO
)) {
530 * Since we are going to force visible to NO, it's irrelevant
531 * what hidesilent is, so don't bother setting it, unlike what
532 * we had to do in svpath().
538 /* if the field is set in the voice structure, use that */
539 if (Voice
[s
-1][v
-1].used
[field
] == YES
)
540 return (&Voice
[s
-1][v
-1]);
542 /* else if the field is set in the staff structure, use that */
543 if (Staff
[s
-1].used
[field
] == YES
)
544 return (&Staff
[s
-1]);
546 /* else use the score structure; it's always set there */
553 * Abstract: Assign fields from an input SSV to a fixed one.
557 * Description: This function is passed an input SSV structure (from an input
558 * context). For each field where "used" is YES in the input SSV,
559 * it copies it to the appropriate fixed SSV and sets its "used"
560 * flag to YES. For each field where "used" is UNSET in the input
561 * SSV, it sets "used" to NO in the appropriate fixed SSV.
562 * In some cases, there are side effects, where it also
563 * alters a lower level structure. E.g., changing the number of
564 * voices of a staff inits its voice structures. In the case
565 * of stafflines, setting a staff to be a tablature staff
566 * automatically automatically forces some other fields to be set
567 * not only in the given staff, but also in the preceding tabnote
568 * staff. Note also that the Score "used" flags are already
569 * always set and don't need to be set here. And Score fields can
576 struct SSV
*i_p
; /* input SSV structure to be copied from */
579 struct SSV
*f_p
; /* ptr to fixed SSV structure to copy into */
580 int s
, v
; /* used for looping through staffs & voices */
581 int start
, stop
; /* loop limits */
582 int n
; /* another loop variable */
585 f_p
= 0; /* to prevent "uninitialized variable" warnings */
588 * Using the selector fields in the input structure, set a pointer to
589 * the fixed structure that is to be populated.
591 switch (i_p
->context
) {
596 /* silently ignore bogus staff no.; it is caught elsewhere */
597 if (i_p
->staffno
< 1 || i_p
->staffno
> MAXSTAFFS
) {
600 f_p
= &Staff
[ i_p
->staffno
- 1 ];
603 /* silently ignore bogus staff/voice; it is caught elsewhere */
604 if (i_p
->staffno
< 1 || i_p
->staffno
> MAXSTAFFS
||
605 i_p
->voiceno
< 1 || i_p
->voiceno
> MAXVOICES
) {
608 f_p
= &Voice
[ i_p
->staffno
- 1 ][ i_p
->voiceno
- 1 ];
613 * ========== ITEMS FOR SCORE CONTEXT ONLY ===========
614 * There's no need to set f_p->used[] = YES here; since this is the
615 * score, those bits are already always YES.
617 if (i_p
->used
[SCALE_FACTOR
] == YES
) {
618 f_p
->scale_factor
= i_p
->scale_factor
;
621 if (i_p
->used
[UNITS
] == YES
) {
622 f_p
->units
= i_p
->units
;
626 * PAGEHEIGHT, PAGEHEIGHT, and PANELSPERPAGE interact, because when the
627 * user sets PAGE*, they are referring to the paper, but internally we
628 * want page* to refer to one "panel" of music, which is a 90 degree
629 * rotated half of the sheet of paper when panelsperpage is 2.
631 if (i_p
->used
[PAGEHEIGHT
] == YES
) {
632 if (f_p
->panelsperpage
== 1) {
633 f_p
->pageheight
= i_p
->pageheight
;
635 f_p
->pagewidth
= i_p
->pageheight
/ 2.0;
639 if (i_p
->used
[PAGEWIDTH
] == YES
) {
640 if (f_p
->panelsperpage
== 1) {
641 f_p
->pagewidth
= i_p
->pagewidth
;
643 f_p
->pageheight
= i_p
->pagewidth
;
647 if (i_p
->used
[PANELSPERPAGE
] == YES
) {
648 /* depending on how this is changing, flip height and width */
650 if (f_p
->panelsperpage
== 1 && i_p
->panelsperpage
== 2) {
651 oldwidth
= f_p
->pagewidth
;
652 f_p
->pagewidth
= f_p
->pageheight
/ 2.0;
653 f_p
->pageheight
= oldwidth
;
654 } else if (f_p
->panelsperpage
== 2 && i_p
->panelsperpage
== 1) {
655 oldwidth
= f_p
->pagewidth
;
656 f_p
->pagewidth
= f_p
->pageheight
;
657 f_p
->pageheight
= oldwidth
* 2.0;
659 f_p
->panelsperpage
= i_p
->panelsperpage
;
662 if (i_p
->used
[TOPMARGIN
] == YES
) {
663 f_p
->topmargin
= i_p
->topmargin
;
666 if (i_p
->used
[BOTMARGIN
] == YES
) {
667 f_p
->botmargin
= i_p
->botmargin
;
670 if (i_p
->used
[LEFTMARGIN
] == YES
) {
671 f_p
->leftmargin
= i_p
->leftmargin
;
674 if (i_p
->used
[RIGHTMARGIN
] == YES
) {
675 f_p
->rightmargin
= i_p
->rightmargin
;
678 if (i_p
->used
[RESTCOMBINE
] == YES
) {
679 f_p
->restcombine
= i_p
->restcombine
;
682 if (i_p
->used
[FIRSTPAGE
] == YES
) {
683 f_p
->firstpage
= i_p
->firstpage
;
686 if (i_p
->used
[NUMSTAFF
] == YES
) {
687 f_p
->staffs
= i_p
->staffs
;
689 /* this destroys all staff and voice info */
690 for (s
= 0; s
< MAXSTAFFS
; s
++) {
692 for (v
= 0; v
< MAXVOICES
; v
++)
693 zapssv(&Voice
[s
][v
]);
697 if (i_p
->used
[MINSCSEP
] == YES
) {
698 f_p
->minscsep
= i_p
->minscsep
;
701 if (i_p
->used
[MAXSCSEP
] == YES
) {
702 f_p
->maxscsep
= i_p
->maxscsep
;
705 if (i_p
->used
[MINSCPAD
] == YES
) {
706 f_p
->minscpad
= i_p
->minscpad
;
709 if (i_p
->used
[MAXSCPAD
] == YES
) {
710 f_p
->maxscpad
= i_p
->maxscpad
;
713 if (i_p
->used
[BRACELIST
] == YES
) {
714 /* if it was already used, free old list if present */
715 if (f_p
->used
[BRACELIST
] == YES
) {
716 freestaffset(f_p
->nbrace
, f_p
->bracelist
);
720 /* set up new list */
721 f_p
->nbrace
= i_p
->nbrace
;
722 asgnstaffset(f_p
->nbrace
, &f_p
->bracelist
, i_p
->bracelist
);
725 if (i_p
->used
[BRACKLIST
] == YES
) {
726 /* if it was already used, free old list if present */
727 if (f_p
->used
[BRACKLIST
] == YES
) {
728 freestaffset(f_p
->nbrack
, f_p
->bracklist
);
732 /* set up new list */
733 f_p
->nbrack
= i_p
->nbrack
;
734 asgnstaffset(f_p
->nbrack
, &f_p
->bracklist
, i_p
->bracklist
);
737 if (i_p
->used
[BARSTLIST
] == YES
) {
738 /* if it was already used, free old list if present */
739 if (f_p
->used
[BARSTLIST
] == YES
&& f_p
->nbarst
!= 0)
740 FREE(f_p
->barstlist
);
742 /* set up new list */
743 f_p
->nbarst
= i_p
->nbarst
;
744 /* the +1 is to guard against allocating 0 */
745 MALLOC(TOP_BOT
, f_p
->barstlist
, f_p
->nbarst
+ 1);
746 for (n
= 0; n
< f_p
->nbarst
; n
++) {
747 f_p
->barstlist
[n
] = i_p
->barstlist
[n
];
751 if (i_p
->used
[TIME
] == YES
) {
752 f_p
->timenum
= i_p
->timenum
;
753 f_p
->timeden
= i_p
->timeden
;
754 f_p
->timevis
= i_p
->timevis
;
755 f_p
->timerep
= i_p
->timerep
;
756 f_p
->time
= i_p
->time
;
759 * Changing the time sig forces a change in default time unit.
760 * Set it to one "beat" for the score, and unset it for all
764 f_p
->timeunit
.d
= f_p
->timeden
;
766 for (s
= 0; s
< MAXSTAFFS
; s
++) {
767 Staff
[s
].used
[TIMEUNIT
] = NO
;
768 for (v
= 0; v
< MAXVOICES
; v
++)
769 Voice
[s
][v
].used
[TIMEUNIT
] = NO
;
773 * Changing the time also destroys all beamstyle lists.
774 * However, the special empty beamstyle list that was set up
775 * for a tablature staff must be retained, so that it will
776 * continue to override any score beamstyle list that may be
779 if (Score
.used
[BEAMSTLIST
] == YES
) {
780 if (Score
.nbeam
!= 0) {
781 FREE(Score
.beamstlist
);
782 Score
.beamstlist
= 0;
784 FREE(Score
.subbeamstlist
);
785 Score
.subbeamstlist
= 0;
789 for (s
= 0; s
< MAXSTAFFS
; s
++) {
790 if (Staff
[s
].used
[BEAMSTLIST
] == YES
&&
791 Staff
[s
].strinfo
== 0) { /* not tablature */
792 if (Staff
[s
].nbeam
!= 0) {
793 FREE(Staff
[s
].beamstlist
);
794 Staff
[s
].beamstlist
= 0;
796 FREE(Staff
[s
].subbeamstlist
);
797 Staff
[s
].subbeamstlist
= 0;
798 Staff
[s
].nsubbeam
= 0;
800 Staff
[s
].used
[BEAMSTLIST
] = NO
;
802 for (v
= 0; v
< MAXVOICES
; v
++) {
803 if (Voice
[s
][v
].used
[BEAMSTLIST
] == YES
) {
804 if (Voice
[s
][v
].nbeam
!= 0) {
805 FREE(Voice
[s
][v
].beamstlist
);
806 Voice
[s
][v
].beamstlist
= 0;
807 Voice
[s
][v
].nbeam
= 0;
808 FREE(Voice
[s
][v
].subbeamstlist
);
809 Voice
[s
][v
].subbeamstlist
= 0;
810 Voice
[s
][v
].nsubbeam
= 0;
812 Voice
[s
][v
].used
[BEAMSTLIST
] = NO
;
818 if (i_p
->used
[DIVISION
] == YES
) {
819 f_p
->division
= i_p
->division
;
822 if (i_p
->used
[ENDINGSTYLE
] == YES
) {
823 f_p
->endingstyle
= i_p
->endingstyle
;
826 if (i_p
->used
[GRIDSATEND
] == YES
) {
827 f_p
->gridsatend
= i_p
->gridsatend
;
830 if (i_p
->used
[MEASNUM
] == YES
) {
831 f_p
->measnum
= i_p
->measnum
;
834 if (i_p
->used
[MEASNUMFAMILY
] == YES
) {
835 f_p
->measnumfamily
= i_p
->measnumfamily
;
838 if (i_p
->used
[MEASNUMFONT
] == YES
) {
839 f_p
->measnumfont
= i_p
->measnumfont
;
842 if (i_p
->used
[MEASNUMSIZE
] == YES
) {
843 f_p
->measnumsize
= i_p
->measnumsize
;
846 if (i_p
->used
[PACKFACT
] == YES
) {
847 f_p
->packfact
= i_p
->packfact
;
850 if (i_p
->used
[PACKEXP
] == YES
) {
851 f_p
->packexp
= i_p
->packexp
;
854 if (i_p
->used
[WARN
] == YES
) {
855 f_p
->warn
= i_p
->warn
;
859 * ========== ITEMS FOR SCORE AND STAFF CONTEXT ===========
862 * Most parameters involve just a single field, and have no side
863 * effects. For this, we can use the following switch statement to
864 * do the work, for parameters that can exist on staff or voice.
865 * (Score-only ones don't need it, since that can't be unset.)
867 #define SETPARM(name, NAME) \
868 switch (i_p->used[NAME]) { \
870 f_p->name = i_p->name; \
871 f_p->used[NAME] = YES; \
874 f_p->used[NAME] = NO; \
876 /* default is NO; do nothing */ \
879 SETPARM(staffscale
, STAFFSCALE
)
881 switch (i_p
->used
[STAFFLINES
]) {
883 struct SSV
*tabnote_p
; /* ptr to tabnote fixed SSV */
884 f_p
->stafflines
= i_p
->stafflines
;
886 if (i_p
->strinfo
!= 0) { /* tablature */
887 struct SSV
*voice_p
; /* ptr to a voice's fixed SSV*/
890 * This is a tablature staff. Set printclef to normal
891 * (even though tab isn't particularly "normal").
892 * Point f_p->strinfo at the same array that
893 * i_p->strinfo points at.
895 f_p
->printclef
= SS_NORMAL
;
896 f_p
->strinfo
= i_p
->strinfo
;
899 * Force some other score/staff items to fixed values
900 * for tab. The parser blocks the user from setting
901 * these. We need to set them here in the staff SSV to
902 * override whatever may be in the score SSV. This
903 * will make it possible to avoid special checks for
904 * tablature in many places; the right values will be
905 * set for this staff. Also force score/staff/voice
910 f_p
->used
[SHARPS
] = YES
;
912 f_p
->inttype
= PERFECT
;
914 f_p
->used
[TRANSPOSITION
] = YES
;
916 f_p
->addinttype
= PERFECT
;
918 f_p
->used
[ADDTRANSPOSITION
] = YES
;
921 f_p
->used
[CLEF
] = YES
;
923 if (f_p
->used
[BEAMSTLIST
] == YES
&& f_p
->nbeam
!= 0) {
924 /* if already used, free old list if present */
925 FREE(f_p
->beamstlist
);
926 FREE(f_p
->subbeamstlist
);
931 f_p
->subbeamstlist
= 0;
932 f_p
->used
[BEAMSTLIST
] = YES
;
935 f_p
->used
[DEFOCT
] = YES
;
937 /* blow away the following in tab staff's voices */
938 for (v
= 0; v
< MAXVOICES
; v
++) {
939 voice_p
= &Voice
[ i_p
->staffno
- 1][ v
];
941 if (voice_p
->used
[BEAMSTLIST
] == YES
) {
942 if (voice_p
->nbeam
!= 0) {
943 FREE(f_p
->beamstlist
);
944 FREE(f_p
->subbeamstlist
);
946 voice_p
->used
[BEAMSTLIST
] = NO
;
948 voice_p
->used
[DEFOCT
] = NO
;
952 * Force fields on the tabnote staff above this tab
955 tabnote_p
= &Staff
[ i_p
->staffno
- 2 ];
958 * The parse phase wouldn't let this be another tab
959 * staff, so we don't need to check for that. But it
960 * might be a 1-line staff. If so, override it to 5
961 * line. If this parameter wasn't set, force printclef
962 * to normal, but if it was, keep the old value. (We
963 * might as well allow 5n and 5 drum as well as 5,
964 * though that would be a weird usage.)
966 tabnote_p
->stafflines
= 5;
967 if (tabnote_p
->used
[STAFFLINES
] == NO
)
968 tabnote_p
->printclef
= SS_NORMAL
;
969 tabnote_p
->used
[STAFFLINES
] = YES
;
971 } else { /* not tablature */
973 * If this staff used to be tablature, we need to unset
974 * some "used" fields that were forced.
976 if (f_p
->strinfo
!= 0) {
977 f_p
->used
[SHARPS
] = NO
;
978 f_p
->used
[TRANSPOSITION
] = NO
;
979 f_p
->used
[ADDTRANSPOSITION
] = NO
;
980 f_p
->used
[CLEF
] = NO
;
981 f_p
->used
[BEAMSTLIST
] = NO
;
982 f_p
->used
[DEFOCT
] = NO
;
983 tabnote_p
= &Staff
[ i_p
->staffno
- 2 ];
985 /* make it non-tablature */
989 f_p
->printclef
= i_p
->printclef
;
991 f_p
->used
[STAFFLINES
] = YES
;
994 f_p
->used
[STAFFLINES
] = NO
;
998 SETPARM(gridswhereused
, GRIDSWHEREUSED
)
1000 SETPARM(gridscale
, GRIDSCALE
)
1002 SETPARM(gridfret
, GRIDFRET
)
1004 SETPARM(numbermrpt
, NUMBERMRPT
)
1006 SETPARM(printmultnum
, PRINTMULTNUM
)
1008 SETPARM(restsymmult
, RESTSYMMULT
)
1010 switch (i_p
->used
[VSCHEME
]) {
1013 * If the vscheme change changes the *number* of voices, we
1014 * have to wipe out the voice information, but otherwise not.
1016 if (i_p
->context
== C_SCORE
) {
1017 start
= 0; /* if score, do test for */
1018 stop
= MAXSTAFFS
- 1; /* all staffs */
1019 } else { /* C_STAFF */
1020 start
= stop
= i_p
->staffno
- 1; /* do just this one */
1023 /* for each staff affected by this change . . . */
1024 for (n
= start
; n
<= stop
; n
++) {
1025 int oldvoices
, newvoices
; /* how many before & after */
1027 oldvoices
= vscheme_voices(svpath(n
+ 1,
1029 newvoices
= vscheme_voices(i_p
->vscheme
);
1031 if (oldvoices
!= newvoices
) {
1033 for (v
= 0; v
< MAXVOICES
; v
++)
1034 zapssv(&Voice
[n
][v
]);
1038 f_p
->vscheme
= i_p
->vscheme
;
1039 f_p
->used
[VSCHEME
] = YES
;
1042 f_p
->used
[VSCHEME
] = NO
;
1046 switch (i_p
->used
[VCOMBINE
]) {
1048 for (v
= 0; v
< MAXVOICES
; v
++) {
1049 f_p
->vcombine
[v
] = i_p
->vcombine
[v
];
1051 f_p
->vcombinequal
= i_p
->vcombinequal
;
1052 f_p
->used
[VCOMBINE
] = YES
;
1055 f_p
->used
[VCOMBINE
] = NO
;
1059 switch (i_p
->used
[SHARPS
]) {
1061 f_p
->sharps
= i_p
->sharps
;
1062 f_p
->is_minor
= i_p
->is_minor
;
1063 f_p
->used
[SHARPS
] = YES
;
1066 f_p
->used
[SHARPS
] = NO
;
1070 SETPARM(cancelkey
, CANCELKEY
)
1072 switch (i_p
->used
[TRANSPOSITION
]) {
1074 f_p
->inttype
= i_p
->inttype
;
1075 f_p
->intnum
= i_p
->intnum
;
1076 f_p
->used
[TRANSPOSITION
] = YES
;
1079 f_p
->used
[TRANSPOSITION
] = NO
;
1083 switch (i_p
->used
[ADDTRANSPOSITION
]) {
1085 f_p
->addinttype
= i_p
->addinttype
;
1086 f_p
->addintnum
= i_p
->addintnum
;
1087 f_p
->used
[ADDTRANSPOSITION
] = YES
;
1090 f_p
->used
[ADDTRANSPOSITION
] = NO
;
1094 switch (i_p
->used
[CLEF
]) {
1096 f_p
->clef
= i_p
->clef
;
1097 f_p
->used
[CLEF
] = YES
;
1100 * Reset the default octave so that the middle line of the
1101 * staff lies within it. If the user also set octave in
1102 * this context, this will get changed again later in this
1105 if (f_p
->clef
> ALTO
) /* lower than alto */
1107 else if (f_p
->clef
< TREBLE
) /* higher than treble */
1111 f_p
->used
[DEFOCT
] = YES
;
1114 f_p
->used
[DEFOCT
] = NO
;
1118 SETPARM(rehstyle
, REHSTYLE
)
1120 SETPARM(fontfamily
, FONTFAMILY
)
1126 SETPARM(lyricsfamily
, LYRICSFAMILY
)
1128 SETPARM(lyricsfont
, LYRICSFONT
)
1130 SETPARM(lyricssize
, LYRICSSIZE
)
1132 SETPARM(lyricsalign
, LYRICSALIGN
)
1134 SETPARM(sylposition
, SYLPOSITION
)
1136 SETPARM(minstsep
, MINSTSEP
)
1138 SETPARM(staffpad
, STAFFPAD
)
1140 switch (i_p
->used
[ABOVEORDER
]) {
1142 setorder(PL_ABOVE
, i_p
, f_p
);
1143 f_p
->used
[ABOVEORDER
] = YES
;
1146 f_p
->used
[ABOVEORDER
] = NO
;
1150 switch (i_p
->used
[BELOWORDER
]) {
1152 setorder(PL_BELOW
, i_p
, f_p
);
1153 f_p
->used
[BELOWORDER
] = YES
;
1156 f_p
->used
[BELOWORDER
] = NO
;
1160 switch (i_p
->used
[BETWEENORDER
]) {
1162 setorder(PL_BETWEEN
, i_p
, f_p
);
1163 f_p
->used
[BETWEENORDER
] = YES
;
1166 f_p
->used
[BETWEENORDER
] = NO
;
1170 SETPARM(pedstyle
, PEDSTYLE
)
1172 SETPARM(chorddist
, CHORDDIST
)
1176 SETPARM(dyndist
, DYNDIST
)
1178 switch (i_p
->used
[LABEL
]) {
1180 /* if it was already used, free old label */
1181 if (f_p
->used
[LABEL
] == YES
&& f_p
->label
!= 0) {
1186 /* set up new label */
1187 MALLOCA(char, f_p
->label
, strlen(i_p
->label
) + 1);
1188 (void)strcpy(f_p
->label
, i_p
->label
);
1190 f_p
->used
[LABEL
] = YES
;
1193 /* if it was already used, free old label */
1194 if (f_p
->used
[LABEL
] == YES
&& f_p
->label
!= 0) {
1198 f_p
->used
[LABEL
] = NO
;
1202 switch (i_p
->used
[LABEL2
]) {
1204 /* if it was already used, free old label2 */
1205 if (f_p
->used
[LABEL2
] == YES
&& f_p
->label2
!= 0) {
1210 /* set up new label */
1211 MALLOCA(char, f_p
->label2
, strlen(i_p
->label2
) + 1);
1212 (void)strcpy(f_p
->label2
, i_p
->label2
);
1214 f_p
->used
[LABEL2
] = YES
;
1217 /* if it was already used, free old label2 */
1218 if (f_p
->used
[LABEL2
] == YES
&& f_p
->label2
!= 0) {
1222 f_p
->used
[LABEL2
] = NO
;
1227 * ========== ITEMS FOR SCORE, STAFF, AND VOICE CONTEXT ===========
1229 switch (i_p
->used
[VISIBLE
]) {
1231 f_p
->visible
= i_p
->visible
;
1232 f_p
->hidesilent
= i_p
->hidesilent
;
1233 f_p
->used
[VISIBLE
] = YES
;
1236 f_p
->used
[VISIBLE
] = NO
;
1239 switch (i_p
->used
[BEAMSTLIST
]) {
1241 /* if it was already used, free old list if present */
1242 if (f_p
->used
[BEAMSTLIST
] == YES
&& f_p
->nbeam
!= 0) {
1243 FREE(f_p
->beamstlist
);
1244 FREE(f_p
->subbeamstlist
);
1245 f_p
->beamstlist
= 0;
1246 f_p
->subbeamstlist
= 0;
1249 /* set up new list */
1250 f_p
->nbeam
= i_p
->nbeam
;
1251 f_p
->beamrests
= i_p
->beamrests
;
1252 f_p
->beamspaces
= i_p
->beamspaces
;
1253 f_p
->nsubbeam
= i_p
->nsubbeam
;
1254 /* the +1 is to guard against allocating 0 */
1255 MALLOCA(RATIONAL
, f_p
->beamstlist
, f_p
->nbeam
+ 1);
1256 MALLOCA(RATIONAL
, f_p
->subbeamstlist
, f_p
->nsubbeam
+ 1);
1257 for (n
= 0; n
< f_p
->nbeam
; n
++) {
1258 f_p
->beamstlist
[n
] = i_p
->beamstlist
[n
];
1260 for (n
= 0; n
< f_p
->nsubbeam
; n
++) {
1261 f_p
->subbeamstlist
[n
] = i_p
->subbeamstlist
[n
];
1264 f_p
->used
[BEAMSTLIST
] = YES
;
1267 /* if it was already used, free old list if present */
1268 if (f_p
->used
[BEAMSTLIST
] == YES
&& f_p
->nbeam
!= 0) {
1269 FREE(f_p
->beamstlist
);
1270 FREE(f_p
->subbeamstlist
);
1271 f_p
->beamstlist
= 0;
1272 f_p
->subbeamstlist
= 0;
1274 f_p
->used
[BEAMSTLIST
] = NO
;
1278 switch (i_p
->used
[BEAMSLOPE
]) {
1280 f_p
->beamfact
= i_p
->beamfact
;
1281 f_p
->beammax
= i_p
->beammax
;
1282 f_p
->used
[BEAMSLOPE
] = YES
;
1285 f_p
->used
[BEAMSLOPE
] = NO
;
1291 SETPARM(stemlen
, STEMLEN
)
1293 SETPARM(stemshorten
, STEMSHORTEN
)
1295 SETPARM(defoct
, DEFOCT
)
1297 switch (i_p
->used
[TIMEUNIT
]) {
1299 f_p
->timeunit
= i_p
->timeunit
;
1300 f_p
->timelist_p
= i_p
->timelist_p
;
1301 f_p
->used
[TIMEUNIT
] = YES
;
1304 f_p
->used
[TIMEUNIT
] = NO
;
1307 SETPARM(swingunit
, SWINGUNIT
)
1309 SETPARM(release
, RELEASE
)
1311 SETPARM(ontheline
, ONTHELINE
)
1313 SETPARM(tabwhitebox
, TABWHITEBOX
)
1315 switch (i_p
->used
[NOTEHEADS
]) {
1317 for (n
= 0; n
< 7; n
++) {
1318 f_p
->noteheads
[n
] = i_p
->noteheads
[n
];
1320 f_p
->used
[NOTEHEADS
] = YES
;
1323 f_p
->used
[NOTEHEADS
] = NO
;
1329 * Name: setssvstate()
1331 * Abstract: Set the static SSVs to the state for a given place in the MML.
1335 * Description: This function, given any structure from the main linked list,
1336 * initializes the static SSVs, and then runs through the MLL up
1337 * to just before that point, assigning SSVs. It assigns not only
1338 * the SSVs in the MLL, but also the timed SSVs hanging off
1339 * barlines. You can pass a null pointer, and then it will go
1340 * through the whole MLL.
1344 setssvstate(mainll_p
)
1346 struct MAINLL
*mainll_p
; /* place in the MLL to stop */
1349 struct MAINLL
*mll_p
; /* for looping through MLL */
1350 struct TIMEDSSV
*tssv_p
; /* for looping through TIMEDSSV lists*/
1354 for (mll_p
= Mainllhc_p
; mll_p
!= 0 && mll_p
!= mainll_p
;
1355 mll_p
= mll_p
->next
) {
1356 switch (mll_p
->str
) {
1358 /* assign this normal input SSV */
1359 asgnssv(mll_p
->u
.ssv_p
);
1362 /* assign each timed SSV, if any */
1363 for (tssv_p
= mll_p
->u
.bar_p
->timedssv_p
; tssv_p
!= 0;
1364 tssv_p
= tssv_p
->next
) {
1365 asgnssv(&tssv_p
->ssv
);
1375 * Abstract: Assign an "order" field from an input SSV to a fixed one.
1379 * Description: This function is called by asgnssv() to assign to the
1380 * appropriate part of the markorder array, based on above, below,
1385 setorder(place
, i_p
, f_p
)
1387 int place
; /* PL_* */
1388 struct SSV
*i_p
; /* input SSV structure to be copied from */
1389 struct SSV
*f_p
; /* ptr to fixed SSV structure to copy into */
1392 int m
; /* mark (MK_*) */
1393 int stk
; /* stacking order */
1397 * First assign all the marks' stacking orders as given. Keep track of
1398 * the highest stacking order number found.
1401 for (m
= 0; m
< NUM_MARK
; m
++) {
1402 f_p
->markorder
[place
][m
] = i_p
->markorder
[place
][m
];
1404 if (f_p
->markorder
[place
][m
] > stk
)
1405 stk
= f_p
->markorder
[place
][m
];
1409 * For every mark type that the user didn't list, the stacking order is
1410 * now 0. Set all these to default settings, higher than all the ones
1411 * the user listed, but in the same order as Defmarkorder. They will
1412 * all be separate numbers, none set equal, unlike Defmarkorder, where
1415 for (m
= 0; m
< NUM_MARK
; m
++) {
1416 if (f_p
->markorder
[place
][m
] == 0) {
1417 f_p
->markorder
[place
][m
] = ++stk
;