Index: prsDeco.c =================================================================== --- prsDeco.c (revision 4925) +++ prsDeco.c (working copy) @@ -23,19 +23,29 @@ case 'K': dt = D_HAT; break; case 'k': dt = D_ATT; break; case '!': + case '+': V5 "%s: Deco !%4s ...\n",F,P V; - dt = prsAnn(); - V5 "%s: Deco %d type %d=%s.\n",F,decos,dt,annname[dt].value V; + if (prsAnn ()) // prsAnn will call addDeco if it finds a decoration + { // and will return true if it finds any sort of + continue; // annotation at all +// V5 "%s: Deco %d type %d=%s.\n",F,decos,dt,annname[dt].value V; + } + else + { + // not a valid annotation, the list of decorations must + // be done + break; + } } if (dt) { - V5 "%s: DECO %d is type %d.\n",F,decos,dt V; +// V5 "%s: DECO %d is type %d.\n",F,decos,dt V; P++; - dtype[decos++] = dt; + addDeco (dt); n++; } else { break; } } - V3 "%s: %d decos found, %d total.\n",F,n,decos V; +// V3 "%s: %d decos found, %d total.\n",F,n,decos V; return n; } Index: syms.c =================================================================== --- syms.c (revision 4925) +++ syms.c (working copy) @@ -423,6 +423,45 @@ add_cv (fp,f1,f2,p,5,1); fprintf (fp, " fill\n} bind def\n"); + // Code borrowed from yaps, + // copyright Michael Methfessel and James Allwright + fprintf(fp, "/segno { %% segno symbol usage: y segno\n"); + fprintf(fp, " x 3.75 sub exch\n"); // make it x y like the original + fprintf(fp, " gsave translate\n"); + fprintf(fp, " 5.82 0.84 moveto\n"); + fprintf(fp, " 4.62 1.15 5.04 3.20 4.6 3.64 curveto\n"); + fprintf(fp, " 4.17 4.08 3.19 2.75 3.9 1.51 curveto\n"); + fprintf(fp, " 4.62 0.27 7.45 0.0 8.03 1.82 curveto\n"); + fprintf(fp, " 8.61 3.64 5.06 7.81 3.38 9.67 curveto\n"); + fprintf(fp, " 1.69 11.53 1.59 14.46 2.79 14.16 curveto\n"); + fprintf(fp, " 3.99 13.85 3.55 11.80 4.00 11.36 curveto\n"); + fprintf(fp, " 4.44 10.92 5.33 12.25 4.66 13.49 curveto\n"); + fprintf(fp, " 3.99 14.73 1.15 15.0 0.57 13.18 curveto\n"); + fprintf(fp, " 0.0 11.36 3.50 7.19 5.21 5.32 curveto\n"); + fprintf(fp, " 6.92 3.46 7.01 0.53 5.82 0.84 curveto\n"); + fprintf(fp, " closepath fill\n"); + fprintf(fp, " -0.43 2.93 moveto\n"); + fprintf(fp, " 8.79 12.25 lineto 9.32 11.72 lineto -0.09 2.40 lineto\n"); + fprintf(fp, " closepath fill\n"); + fprintf(fp, " 0.71 7.50 1.0 0 360 arc\n"); + fprintf(fp, " closepath fill\n"); + fprintf(fp, " 7.85 7.50 1.0 0 360 arc\n"); + fprintf(fp, " closepath fill\n"); + fprintf(fp, " grestore\n"); + fprintf(fp, "} bind def\n"); + fprintf(fp, "\n"); + fprintf(fp, "/coda { %% coda : usage y coda\n"); + fprintf(fp, " x 7.5 sub exch\n"); // make it x y like the original? + fprintf(fp, " gsave\n"); + fprintf(fp, " translate\n"); + fprintf(fp, " 1.0 setlinewidth\n"); + fprintf(fp, " 0.0 7.5 moveto 15.0 7.5 lineto stroke\n"); + fprintf(fp, " 7.5 0.0 moveto 7.5 15.0 lineto stroke\n"); + fprintf(fp, " 7.5 7.5 5.0 0 360 arc stroke\n"); + fprintf(fp, " grestore\n"); + fprintf(fp, "} bind def\n"); + fprintf(fp, "\n"); + f1=f2=0.8; fprintf (fp, "\n/dnb { %% usage: y dnb - down bow\n" " x exch moveto\n"); Index: jcabc2ps.h =================================================================== --- jcabc2ps.h (revision 4925) +++ jcabc2ps.h (working copy) @@ -250,6 +250,8 @@ #define D_TRILL 9 #define D_HAT 10 #define D_ATT 11 +#define D_SEGNO 12 +#define D_CODA 13 /* types of heads */ Index: prsAnn.c =================================================================== --- prsAnn.c (revision 4925) +++ prsAnn.c (working copy) @@ -17,6 +17,8 @@ {D_TRILL, "TRILL"}, /* 9 */ {D_HAT, "HAT"}, /* 10 */ {D_ATT, "ATT"}, /* 11 */ + {D_SEGNO, "segno"}, /* 12 */ + {D_CODA, "coda"}, /* 13 */ {0}, }; @@ -32,81 +34,104 @@ int c, i, l; int n=0; // Annotation count float yy; + char ann_t[200]; + double ann_x, ann_y; + int ann_p = 0; + char marker; V3 "%s: Called at <%s>\n",F,P V; - if (*P != '!') {V5 "%s: No annotation\n",F V; return 0;} - if (!P[1]) {V5 "%s: Trailing '!'\n",F V; return 0;} + marker = *P; + if (*P != '!' && *P != '+') { + V5 "%s: No annotation\n",F V; return 0; + } + if (!P[1]) {V5 "%s: Trailing '%c'\n",F,marker V; return 0;} if (!ann) { V5 "%s: No current annotation\n",F V; TextInit(&ann,32); } q = P; /* Note position of opening quote */ P++; /* Skip to first char of string */ - ann->p = 0; - ann->x = ann->y = 0.0; + ann_p = 0; + ann_x = ann_y = 0.0; + l = 0; switch (c = *P) { /* Check for position char */ case '^': /* Above staff */ V3 " Annotation position '%c' above staff.\n",c V; - P++; ann->p = P_ABOVE; ann->y = 38; break; + P++; ann_p = P_ABOVE; ann_y = 38; break; case '<': /* Left of note */ V3 " Annotation position '%c' left of note.\n",c V; - P++; ann->p = P_LEFT; break; + P++; ann_p = P_LEFT; break; case '=': /* Next to note */ V3 " Annotation position '%c' next to note.\n",c V; - P++; ann->p = P_NEXT; break; + P++; ann_p = P_NEXT; break; case '>': /* Right of note */ V3 " Annotation position '%c' right of note.\n",c V; - P++; ann->p = P_RIGHT; break; + P++; ann_p = P_RIGHT; break; case '_': /* Below staff */ V3 " Annotation position '%c' below staff.\n",c V; - P++; ann->p = P_BELOW; ann->y = -12; break; + P++; ann_p = P_BELOW; ann_y = -12; break; } - V3 "%s: Position is %d ann->y=%.3f\n",F,ann->p,ann->y V; - l = ann->l; /* Length of annotation so far */ - if (l > 0) { /* Only one allowed at present */ - syntax("Overwrite earlier annotation", q); - TextInit(&ann,64); - } - while ((c = *P) && (c != '!') && (c != ' ')) { - ann->t[l++] = c; - ann->t[l] = 0; - ann->l ++; + V3 "%s: Position is %d ann_y=%.3f\n",F,ann_p,ann_y V; + while ((c = *P) && (c != marker) && (c != ' ')) { + ann_t[l++] = c; + ann_t[l] = 0; if (c == '@') { if (sscanf(P+1,"%f",&yy) > 0) { - ann->y = yy; - V5 "%s: Matched ann->y=%6.3f\n",F,yy V; + ann_y = yy; + V5 "%s: Matched ann_y=%6.3f\n",F,yy V; } } - V7 "%s: ann=\"%s\"\n",F,ann->t V; + V7 "%s: ann=\"%s\"\n",F,ann_t V; if (l >= 200) { syntax("String for annotation too long", q); - return 1; + return 1; // this behavior strikes me as questionable } P++; } - if (c != '!') { + if (c != marker) { if (!c) V3 "%s: EOL reached while parsing annotation.\n",F V; if ( c) V3 "%s: '%c' found while parsing annotation.\n",F,c V; P = q + 1; /* Reposition just after the ! */ while ((c = *P) && isspace(c)) P++; - TextInit(&ann,64); /* Discard accumulated chars */ +// TextInit(&ann,64); /* Discard accumulated chars */ -- no longer needed V3 "%s: Continue at <%3.3s>\n",F,P V; return 0; /* Ignore it; it's an abc2win ! */ } + P++; - V3 " parsed annotation <%s>\n",TextStr(ann) V; + + // skip trailing whitespaces + while ((c = *P) && (c == ' ') || (c == '\t')) { + P++; + } + + V3 " parsed annotation <%s>\n",ann_t V; for (i=0; annname[i].value; i++) { - if (!strcasecmp(ann->t,annname[i].value)) { + if (!strcasecmp(ann_t,annname[i].value)) { V5 "%s: Matched annotation name %d.\n",F,i V; - dtype[decos] = annname[i].type; - V5 "%s: Deco dtype[%d] is %d \"%s\"\n",F,decos,dtype[decos],TextStr(ann) V; - decos++; + addDeco (annname[i].type); +// V5 "%s: Deco dtype[%d] is %d \"%s\"\n",F,decos,dtype[decos],TextStr(ann) V; ++n; // Number of decos found break; } } - V3 "%s: %d decos found, %d total.\n",F,n,decos V; - V3 "%s: Return 1 for ann !%s!\n",F,TextStr(ann) V; + + if (n == 0) // if no decoration found, treat as annotation + { + if (ann->l > 0) { /* Only one allowed at present */ + syntax("Overwrite earlier annotation", q); + TextInit(&ann,64); + } + + strcpy (ann->t, ann_t); + ann->l = l; + ann->x = ann_x; + ann->y = ann_y; + ann->p = ann_p; + } + +// V3 "%s: %d decos found, %d total.\n",F,n,decos V; + V3 "%s: Return 1 for ann %c%s%c\n",F,marker,TextStr(ann),marker V; return 1; } Index: parse.c =================================================================== --- parse.c (revision 4925) +++ parse.c (working copy) @@ -99,6 +99,44 @@ /* subroutines connected with parsing the input file */ +void clearDecos (void) +{ + char *F ="clearDecos"; + + V3 "%s: DECOs cleared out\n",F V; + decos = 0; +} + +void addDeco( + int deco_type) +{ + char *F ="addDeco"; + + if (decos < 30) + { + V5 "%s: DECO %d is type %d.\n",F,decos,deco_type V; + dtype[decos++] = deco_type; + } + else + { + V5 "%s: DECO buffer full, skipping DECO of type %d.\n",F,deco_type V; + } +} + +void copyDecosToSym( + Sym *sp) +{ + char *F ="copyDecosToSym"; + int i; + + V3 "%s: Copying DECOs to symbol\n",F V; + for (i = 0;idc.t[i] = dtype[i]; + V5 "%s: decoration %d is type %d.\n",F,i,sp->dc.t[i] V; + } + sp->dc.n = decos; /* Decoration count */ +} + /* ----- sytax: print message for syntax errror -------- */ void syntax( char *msg, @@ -2284,7 +2322,7 @@ // ngr = prsGrSeq(pgr,agr); /* grace notes */ // while ((c = *P) && isspace(c)) ++P; V3 "%s: Bar sym has %d grace notes at <%s>.\n",F,ngr,P V; - prsAnn(); // Allow annotations on par lines + prsDeco(); // Allow decorations and annotations on par lines prsAch(); // Allow "chords" on bar lines // special cases: [ and digit or quote without a preceeding bar, [ ending @@ -2387,6 +2425,9 @@ V3 "%s: Bar symv[%d][%d] has %d grace notes.\n",F,ivc,k,ngr V; sp = &symv[ivc][k]; sp->gr.n = ngr; /* Grace note count */ + + copyDecosToSym (sp); + clearDecos (); V3 "%s: Bar symv[%d][%d] has %d decorations and %d grace notes.\n",F,ivc,k,sp->dc.n,sp->gr.n V; for (i = 0;igr.p[i] = pgr[i]; @@ -2983,11 +3024,7 @@ k = add_sym(type); /* add new symbol to list */ sp = &symv[ivc][k]; - for (i = 0;idc.t[i] = dtype[i]; - V5 "%s: symv[%d][%d] decoration %d is type %d.\n",F,ivc,k,i,sp->dc.t[i] V; - } - sp->dc.n = decos; /* Decoration count */ + copyDecosToSym (sp); sp->gr.n = ngr; /* Grace note count */ V5 "%s: Bar symv[%d][%d] has %d decorations and %d grace notes.\n",F,ivc,k,sp->dc.n,sp->gr.n V; for (i = 0;idc.t[i+sp->dc.n] = dtype[i]; - sp->dc.n = decos; + copyDecosToSym (sp); if ((rc = parse_basic_note(&pitch,&length,&accidental)) == 0) { voice[ivc].nsym--; @@ -3135,6 +3170,7 @@ #endif identify_note(&symv[ivc][k],q0); V3 "%s: symv[%d][%d] returns type %d with annotation !%s!\n",F,ivc,k,type,TextStr(sp->ann) V; + clearDecos (); return type; } @@ -3196,7 +3232,6 @@ int i; V5 "%s: Called at <%s>\n",F,P V; - decos = 0; doMacro(); if (prsAnn()) {V4 "%s: Return %d=ANNOT\n",F,ANNOT V; return ANNOT;} if (prsAch()) {V4 "%s: Return %d=ACHORD\n",F,ACHORD V; return ACHORD;} @@ -3310,6 +3345,7 @@ nbr = 0; P = Q = line; // Positions in music line pmx = P+strlen(P); // End of music line + clearDecos (); while (*P != 0) { // End at null byte if (vb > 6) { Index: parse.h =================================================================== --- parse.h (revision 4925) +++ parse.h (working copy) @@ -10,9 +10,10 @@ #include "jcabc2ps.h" extern int oldks; -extern int dtype[30]; /* Decoration types */ -extern int decos; /* Number of decorations on current symbol */ +// extern int dtype[30]; /* Decoration types */ +// extern int decos; /* Number of decorations on current symbol */ +void addDeco(int deco_type); int add_sym(int type); int find_voice(char vid[], int *new); int get_halftones(struct KEYSTR key, char transpose[]); Index: music.c =================================================================== --- music.c (revision 4925) +++ music.c (working copy) @@ -2069,6 +2069,7 @@ Sym *sp) // Symbol { char *F="drawBar"; int n; + float top, top2; V5 "%s: Called at x=%.2f sp->u=%d.\n",F,x,sp->u V; if (sp->gr.n > 0) { @@ -2122,6 +2123,10 @@ } else { fprintf(stderr,">>> dont know how to draw bar type %d\n", sp->u); } + + PUT1("/x %.2f def", x) + top = drawDecos (x,sp,&top2); /* add decorations */ + PUT0("\n") } @@ -2320,36 +2325,44 @@ { char *F = "drawRest"; int y,i; float dotx,doty; + float top, top2; drawGraceNotes(x, w, d, &s); /* draw grace notes */ *achy = DflChYYA; *anny = DflAnYYA; - if (s.invis) return; + if (!s.invis) + { + y = (int)s.y; + PUT2("%.2f %.0f", x, yy) - y = (int)s.y; - PUT2("%.2f %.0f", x, yy) + if (s.head == H_OVAL) {PUT0(" r1");} + elsif (s.head == H_EMPTY) {PUT0(" r2");} + else { + if (s.flags == 0) {PUT0(" r4");} + elsif (s.flags == 1) {PUT0(" r8");} + elsif (s.flags == 2) {PUT0(" r16");} + elsif (s.flags == 3) {PUT0(" r32");} + else {PUT0(" r64");} + } - if (s.head == H_OVAL) {PUT0(" r1");} - elsif (s.head == H_EMPTY) {PUT0(" r2");} - else { - if (s.flags == 0) {PUT0(" r4");} - elsif (s.flags == 1) {PUT0(" r8");} - elsif (s.flags == 2) {PUT0(" r16");} - elsif (s.flags == 3) {PUT0(" r32");} - else {PUT0(" r64");} - } + if (y%6) { dotx=6.5; doty=0; } /* dots */ + else { dotx=6.5; doty=3; } + if (s.head == H_OVAL) { dotx=8; doty=-3; } + if (s.head == H_EMPTY) { dotx=8; doty=3; } + for (i=0;istem == 1) { + y1=s->ys+4; + } else { + y1=s->ymx+6; + } + if (ycstem == 1) { + y1=s->ys+4; + } else { + y1=s->ymx+6; + } + if (ycstem == 1) {