diff -ur mup-5.1-orig/mup/absvert.c mup-5.1/mup/absvert.c --- mup-5.1-orig/mup/absvert.c 2005-05-01 01:00:29.000000000 +0200 +++ mup-5.1/mup/absvert.c 2005-05-31 09:19:23.000000000 +0200 @@ -1661,14 +1661,14 @@ horzavoid(); /* - * Back in relvert.c, we skipped placing phrases whose endpoint groups - * were affected by CSS. Now that we know where the final group - * boundaries are, we set up the coords for these phrases. - * phrase_points destroys groups' AN and AS, and depends on them - * starting out as zero. So zero them now and restore them later. - * Because phrases can cross bar lines, we need to zap all of these - * coords in this first loop, and have a separate loop below to do the - * phrase work (and restore the groups' coords). + * Back in relvert.c, we skipped placing tie/slur/bend/phrases whose + * endpoint groups were affected by CSS. Now that we know where the + * final group boundaries are, we set up the coords for these items. + * tieslur_points and phrase_points destroy groups' AN and AS, and + * depends on them starting out as zero. So zero them now and restore + * them later. Because these items can cross bar lines, we need + * to zap all of these coords in this first loop, and have a separate + * loop to do the main work (and restore the groups' coords). */ for (mainll_p = Mainllhc_p; mainll_p != 0; mainll_p = mainll_p->next) { if (mainll_p->str != S_STAFF) { @@ -1692,29 +1692,57 @@ thisstaff_p = mainll_p->u.staff_p; /* - * Find every phrase starting in this staff and handle them. + * Find and handle every tie/slur/bend/phrase starting in this + * staff. */ for (stuff_p = thisstaff_p->stuff_p; stuff_p != 0; stuff_p = stuff_p->next) { - if (stuff_p->stuff_type != ST_PHRASE) { - continue; - } - if (css_affects_phrase(stuff_p, mainll_p) == YES) { - phrase_points(mainll_p, stuff_p); + switch (stuff_p->stuff_type) { + case ST_PHRASE: + if (css_affects_phrase(stuff_p, + mainll_p) == YES) { + phrase_points(mainll_p, stuff_p); + + stuff_p->c[AY] = thisstaff_p->c[AY] + + stuff_p->c[RY]; + stuff_p->c[AN] = thisstaff_p->c[AY] + + stuff_p->c[RN]; + stuff_p->c[AS] = thisstaff_p->c[AY] + + stuff_p->c[RS]; + + /* do the phrase points too */ + for (pp_p = stuff_p->crvlist_p; + pp_p != 0; pp_p = pp_p->next) { + + pp_p->y += thisstaff_p->c[AY]; + } + } + break; + case ST_TIESLUR: + case ST_BEND: + if (css_affects_tieslurbend(stuff_p, + mainll_p) == YES) { + if (stuff_p->stuff_type == ST_TIESLUR) { + tieslur_points(mainll_p, stuff_p); + } else { + bend_points(mainll_p, stuff_p); + } - stuff_p->c[AY] = thisstaff_p->c[AY] - + stuff_p->c[RY]; - stuff_p->c[AN] = thisstaff_p->c[AY] - + stuff_p->c[RN]; - stuff_p->c[AS] = thisstaff_p->c[AY] - + stuff_p->c[RS]; - - /* do the phrase points too */ - for (pp_p = stuff_p->crvlist_p; - pp_p != 0; pp_p = pp_p->next) { + stuff_p->c[AY] = thisstaff_p->c[AY] + + stuff_p->c[RY]; + stuff_p->c[AN] = thisstaff_p->c[AY] + + stuff_p->c[RN]; + stuff_p->c[AS] = thisstaff_p->c[AY] + + stuff_p->c[RS]; + + /* do the tie/slur/bend points too */ + for (pp_p = stuff_p->crvlist_p; + pp_p != 0; pp_p = pp_p->next) { - pp_p->y += thisstaff_p->c[AY]; + pp_p->y += thisstaff_p->c[AY]; + } } + break; } } diff -ur mup-5.1-orig/mup/globals.h mup-5.1/mup/globals.h --- mup-5.1-orig/mup/globals.h 2005-05-01 01:00:29.000000000 +0200 +++ mup-5.1/mup/globals.h 2005-05-31 09:19:23.000000000 +0200 @@ -568,6 +568,8 @@ extern double solvecubic P((double a, double b, double c, double d, double lo, double hi, double thresh)); extern int css_affects_stemtip P((struct GRPSYL *gs1_p)); +extern int css_affects_tieslurbend P((struct STUFF *stuff_p, + struct MAINLL *mll_p)); extern int css_affects_phrase P((struct STUFF *stuff_p, struct MAINLL *mll_p)); extern struct GRPSYL *nextsimilar P((struct GRPSYL *)); extern struct GRPSYL *prevsimilar P((struct GRPSYL *)); diff -ur mup-5.1-orig/mup/plutils.c mup-5.1/mup/plutils.c --- mup-5.1-orig/mup/plutils.c 2005-05-01 01:00:29.000000000 +0200 +++ mup-5.1/mup/plutils.c 2005-05-31 09:19:23.000000000 +0200 @@ -1853,6 +1853,95 @@ } /* + * Name: css_affects_tieslurbend() + * + * Abstract: Do CSS notes (if any) affect the position of this tie/slur/bend? + * + * Returns: YES or NO + * + * Description: This function decides whether the given tie, slur, or bend is + * affected by CSS notes in any of the groups it covers. + */ + +int +css_affects_tieslurbend(stuff_p, mll_p) + +struct STUFF *stuff_p; /* the tie, slur, or bend */ +struct MAINLL *mll_p; /* MLL item where this tie/slur/bend starts */ + +{ + struct GRPSYL *sg_p; /* starting group of the tie/slur/bend */ + struct GRPSYL *eg_p; /* starting group of the tie/slur/bend */ + struct NOTE *snote_p; /* starting note of the tie/slur/bend */ + struct NOTE *enote_p; /* ending note of the tie/slur/bend */ + int idx; /* index of note in the group */ + + + /* if not cross staff stemming, don't waste time checking */ + if (CSSused == NO) { + return (NO); + } + + sg_p = stuff_p->beggrp_p; + snote_p = stuff_p->begnote_p; + + /* find the index of the note in the group */ + for (idx = 0; idx < sg_p->nnotes; idx++) { + if (&sg_p->notelist[idx] == snote_p) { + break; + } + } + if (idx == sg_p->nnotes) { + pfatal("can't find tied/slurred/bent note in group"); + } + + /* if this starting note is CSS, return YES */ + if (IS_CSS_NOTE(sg_p, idx)) { + return (YES); + } + + /* + * Find the end note of the tie/slur/bend. If none, we don't care + * about the end note. + */ + eg_p = nextgrpsyl(sg_p, &mll_p); + if (eg_p == 0) { + return (NO); + } + + /* find the note tied/slurred/bent to */ + if (stuff_p->curveno == -1) { /* this is a tie */ + enote_p = find_matching_note(eg_p, snote_p->letter, + snote_p->octave, (char *)0); + } else { /* this is a slur or bend */ + enote_p = find_matching_note(eg_p, + snote_p->slurtolist[stuff_p->curveno].letter, + snote_p->slurtolist[stuff_p->curveno].octave, + (char *)0); + } + + if (enote_p == 0) { + return (NO); + } + + /* find the index of the note in the group */ + for (idx = 0; idx < eg_p->nnotes; idx++) { + if (&eg_p->notelist[idx] == enote_p) { + break; + } + } + if (idx == eg_p->nnotes) { + pfatal("can't find tied/slurred/bent-to note in group"); + } + + /* if this ending note is CSS, return YES */ + if (IS_CSS_NOTE(eg_p, idx)) { + return (YES); + } + + return (NO); +} +/* * Name: css_affects_phrase() * * Abstract: Do CSS notes (if any) affect the position of this phrase mark? diff -ur mup-5.1-orig/mup/relvert.c mup-5.1/mup/relvert.c --- mup-5.1-orig/mup/relvert.c 2005-05-01 01:00:29.000000000 +0200 +++ mup-5.1/mup/relvert.c 2005-05-31 09:19:23.000000000 +0200 @@ -1000,12 +1000,26 @@ if (place == PL_ABOVE) { switch (stuff_p->stuff_type) { case ST_TIESLUR: + /* don't call tieslur_points now if the + * positions of the tie/slur's endpoints + * would change later due to CSS */ + if (css_affects_tieslurbend(stuff_p, + mainll_p) == YES) { + break; + } tieslur_points(mainll_p, stuff_p); break; case ST_TABSLUR: tabslur_points(mainll_p, stuff_p); break; case ST_BEND: + /* don't call bend_points now if the + * positions of the bend's endpoints + * would change later due to CSS */ + if (css_affects_tieslurbend(stuff_p, + mainll_p) == YES) { + break; + } bend_points(mainll_p, stuff_p); break; case ST_PHRASE: