431ca2b29dd35a0ebd83029e95bca9363022a037 braney Tue Jan 31 17:33:19 2017 -0800 fix some problems with long chrom names and the cyto band track diff --git src/hg/lib/hCytoBand.c src/hg/lib/hCytoBand.c index 8084815..7732624 100644 --- src/hg/lib/hCytoBand.c +++ src/hg/lib/hCytoBand.c @@ -1,170 +1,170 @@ /* hCytoBand - stuff to help draw chromosomes where we have * banding data. */ /* Copyright (C) 2014 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "hvGfx.h" #include "hCommon.h" #include "hgColors.h" #include "cytoBand.h" #include "hCytoBand.h" static char *abbreviatedBandName(struct cytoBand *band, MgFont *font, int width, boolean isDmel) /* Return a string abbreviated enough to fit into space. */ { int textWidth; -static char string[32]; +static char string[1024]; /* If have enough space, return original chromosome/band. */ -sprintf(string, "%s%s", (isDmel ? "" : skipChr(band->chrom)), band->name); +safef(string, sizeof string, "%s%s", (isDmel ? "" : skipChr(band->chrom)), band->name); textWidth = mgFontStringWidth(font, string); if (textWidth <= width) return string; /* Try leaving off chromosome */ -sprintf(string, "%s", band->name); +safef(string, sizeof string, "%s", band->name); textWidth = mgFontStringWidth(font, string); if (textWidth <= width) return string; /* Try leaving off initial letter */ -sprintf(string, "%s", band->name+1); +safef(string, sizeof string, "%s", band->name+1); textWidth = mgFontStringWidth(font, string); if (textWidth <= width) return string; return NULL; } static Color cytoBandColorGiemsa(struct cytoBand *band, struct hvGfx *hvg, Color aColor, Color bColor, Color *shades, int maxShade) /* Figure out color of band based on gieStain field. */ { char *stain = band->gieStain; if (startsWith("gneg", stain)) { return shades[1]; } else if (startsWith("gpos", stain)) { int percentage = 100; stain += 4; if (isdigit(stain[0])) percentage = atoi(stain); return shades[hGrayInRange(percentage, -30, 100, maxShade)]; } else if (startsWith("gvar", stain)) { return shades[maxShade]; } else { return bColor; } } static Color cytoBandColorDmel(struct cytoBand *band, struct hvGfx *hvg, Color aColor, Color bColor, Color *shades, int maxShade) /* Figure out color of band based on D. melanogaster band name: just toggle * color based on subband letter before the number at end of name (number * at end of name gives too much resolution!). There must be a better way * but the only online refs I've been able to get for these bands are books * and too-old-for-online journal articles... */ { char *lastAlpha = band->name + strlen(band->name) - 1; int parity = 0; while (isdigit(*lastAlpha) && lastAlpha > band->name) lastAlpha--; parity = ((*lastAlpha) - 'A') & 0x1; if (parity) return aColor; else return bColor; } Color hCytoBandColor(struct cytoBand *band, struct hvGfx *hvg, boolean isDmel, Color aColor, Color bColor, Color *shades, int maxShade) /* Return appropriate color for band. */ { if (isDmel) return cytoBandColorDmel(band, hvg, aColor, bColor, shades, maxShade); else return cytoBandColorGiemsa(band, hvg, aColor, bColor, shades, maxShade); } char *hCytoBandName(struct cytoBand *band, boolean isDmel) /* Return name of band. Returns a static buffer, so don't free result. */ { static char buf[32]; sprintf(buf, "%s%s", (isDmel ? "" : skipChr(band->chrom)), band->name); return buf; } void hCytoBandDrawAt(struct cytoBand *band, struct hvGfx *hvg, int x, int y, int width, int height, boolean isDmel, MgFont *font, int fontPixelHeight, Color aColor, Color bColor, Color *shades, int maxShade) /* Draw a single band in appropriate color at given position. If there's * room put in band label. */ { Color col = hCytoBandColor(band, hvg, isDmel, aColor, bColor, shades, maxShade); hvGfxBox(hvg, x, y, width, height, col); if (height >= mgFontLineHeight(font)) { char *s = abbreviatedBandName(band, font, width, isDmel); if (s != NULL) { Color textCol = hvGfxContrastingColor(hvg, col); hvGfxTextCentered(hvg, x, y, width, height, textCol, font, s); } } } Color hCytoBandCentromereColor(struct hvGfx *hvg) /* Get the color used traditionally to draw centromere */ { return hvGfxFindColorIx(hvg, 150, 50, 50); } void hCytoBandDrawCentromere(struct hvGfx *hvg, int x, int y, int width, int height, Color bgColor, Color fgColor) /* Draw the centromere. */ { struct gfxPoly *poly; int xCen = x+width/2, yCen = y+height/2; int xEnd = x+width-1, yEnd = y+height-1; /* Draw box over centromere, may be drawn already with lettering * which we don't want. */ hvGfxBox(hvg, x, y, width, height, bgColor); char *savedHint = hvGfxGetHint(hvg,"fat"); hvGfxSetHint(hvg,"fat","on"); /* Make up triangle on left of centromere and draw. */ poly = gfxPolyNew(); gfxPolyAddPoint(poly, x, y); gfxPolyAddPoint(poly, xCen, yCen); gfxPolyAddPoint(poly, x, yEnd); hvGfxDrawPoly(hvg, poly, fgColor, TRUE); gfxPolyFree(&poly); /* Make up triangle on right of centromere and draw. */ poly = gfxPolyNew(); gfxPolyAddPoint(poly, xEnd, y); gfxPolyAddPoint(poly, xCen, yCen); gfxPolyAddPoint(poly, xEnd, yEnd); hvGfxDrawPoly(hvg, poly, fgColor, TRUE); gfxPolyFree(&poly); hvGfxSetHint(hvg,"fat",savedHint); }