5d028b1ce2b846df0794e25f6d101620fe6a8828 angie Fri Jul 1 16:12:49 2011 -0700 While working on VCF, caught a couple little bugs in pgSnpTextRight: 1. When restoring the clipping rectangle after snapping a label to the left, pgSnpTextRight thought it was using the track y offset -- but the DrawAt routine only gets the item y, not track y. So when an item on row N had a label that snapped left, the restored clipping rectangle clips out any subsequent items on rows 0..N-1. The top row(s) looks suspiciously empty, as if the packer hadn't fully utilized the row, but it's only that those items are made invisible. The fix was to get the real y clipping coords before clipping for left text, so they could be restored correctly. 2. The text width was subtracted twice from the item pixel start before the comparison with insideX (by the caller, and inside pgSnpTextRight). Thus snapLeft was triggered too easily, causing overwriting of left labels when items in the same row were close to each other and to the left edge. Fix: the caller doesn't subtract (width + 2); pgSnpTextRight uses textX, not x1, when drawing text. diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index b4a9b26..246cf7b 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -9416,65 +9416,66 @@ { reverseComplement(list[i], strlen(list[i])); dyStringPrintf(ds, "%s", list[i]); if (i != myItem->alleleCount - 1) dyStringPrintf(ds, "%s", "/"); } name = cloneString(ds->string); freeDyString(&ds); } /* if no changes needed return bed name */ if (name == NULL) name = cloneString(myItem->name); return name; } -void pgSnpTextRight(char *display, struct hvGfx *hvg, int x1, int y, int width, int height, Color color, MgFont *font, char *allele, int trackY, int trackHeight) +void pgSnpTextRight(char *display, struct hvGfx *hvg, int x1, int y, int width, int height, Color color, MgFont *font, char *allele, int itemY, int lineHeight) /* put text anchored on right upper corner, doing separate colors if needed */ { -boolean snapLeft = FALSE; -int textX = x1 - width; -snapLeft = (textX < insideX); +int textX = x1 - width - 2; +boolean snapLeft = (textX < insideX); +int clipYBak = 0, clipHeightBak = 0; if (snapLeft) /* Snap label to the left. */ { + hvGfxGetClip(hvg, NULL, &clipYBak, NULL, &clipHeightBak); hvGfxUnclip(hvg); - hvGfxSetClip(hvg, leftLabelX, trackY, insideWidth, trackHeight); - x1 = leftLabelX; + hvGfxSetClip(hvg, leftLabelX, itemY, insideWidth, lineHeight); + textX = leftLabelX; width = leftLabelWidth-1; } if (sameString(display, "freq")) { Color allC = MG_BLACK; if (startsWith("A", allele)) allC = MG_RED; else if (startsWith("C", allele)) allC = MG_BLUE; else if (startsWith("G", allele)) allC = darkGreenColor; else if (startsWith("T", allele)) allC = MG_MAGENTA; - hvGfxTextRight(hvg, x1, y, width, height, allC, font, allele); + hvGfxTextRight(hvg, textX, y, width, height, allC, font, allele); } else { - hvGfxTextRight(hvg, x1, y, width, height, color, font, allele); + hvGfxTextRight(hvg, textX, y, width, height, color, font, allele); } if (snapLeft) { hvGfxUnclip(hvg); - hvGfxSetClip(hvg, insideX, trackY, insideWidth, trackHeight); + hvGfxSetClip(hvg, insideX, clipYBak, insideWidth, clipHeightBak); } } void pgSnpDrawAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y, double scale, MgFont *font, Color color, enum trackVisibility vis) /* Draw the personal genome SNPs at a given position. */ { struct pgSnp *myItem = item; boolean cmpl = cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE); char *display = "freq"; //cartVar? if (revCmplDisp) cmpl = !cmpl; if (vis == tvSquish || vis == tvDense || myItem->alleleCount > 2) { withIndividualLabels = TRUE; //haven't done label for this one bedDrawSimpleAt(tg, myItem, hvg, xOff, y, scale, font, color, vis); @@ -9552,51 +9553,51 @@ if (cnt > 1) { all2Width = mgFontStringWidth(font, allele[1]); if (all2Width > allWidth) allWidth = all2Width; /* use max */ } int yCopy = y + 1; /* allele 1, should be insertion if doesn't fit */ if (sameString(display, "freq")) { if (cmpl) complement(allele[0], strlen(allele[0])); if (revCmplDisp) reverseComplement(allele[0], strlen(allele[0])); - pgSnpTextRight(display, hvg, x1-allWidth-2, yCopy, allWidth, allHeight, color, font, allele[0], y, tg->height); + pgSnpTextRight(display, hvg, x1, yCopy, allWidth, allHeight, color, font, allele[0], y, tg->lineHeight); } else { if (cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE)) complement(allele[0], strlen(allele[0])); /* sequence in box automatically reversed with browser */ spreadBasesString(hvg, x1, yCopy, w, allHeight, MG_WHITE, font, allele[0], strlen(allele[0]), FALSE); } if (cnt > 1) { /* allele 2 */ yCopy += allHeight; if (sameString(display, "freq")) { if (cmpl) complement(allele[1], strlen(allele[1])); if (revCmplDisp) reverseComplement(allele[1], strlen(allele[1])); - pgSnpTextRight(display, hvg, x1-allWidth-2, yCopy, allWidth, allHeight, color, font, allele[1], y, tg->height); + pgSnpTextRight(display, hvg, x1, yCopy, allWidth, allHeight, color, font, allele[1], y, tg->lineHeight); } else { if (cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE)) complement(allele[1], strlen(allele[1])); spreadBasesString(hvg, x1, yCopy, w, allHeight, MG_WHITE, font, allele[1], strlen(allele[1]), FALSE); } } /* map box for link, when text outside box */ if (allWidth >= w || sameString(display, "freq")) { tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item), myItem->chromStart, myItem->chromEnd, x1-allWidth-2, y+1, allWidth+w, tg->heightPer); }