b8180d9f6d41dc708a2f249ba892cbca311e7a06 jcasper Mon Feb 27 11:38:55 2023 -0800 Adding transparency support for colors refs #30569 diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index 3409f93..6d317b6 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -199,31 +199,31 @@ long virtSeqBaseCount = 0; // number of bases in virtual chromosome long virtWinBaseCount = 0; // number of bases in virtual chrom (end - start) long virtWinStart = 0; // start of virtual window in bases long virtWinEnd = 0; // end of virtual window in bases long defaultVirtWinStart = 0; // default start of virtual window in bases long defaultVirtWinEnd = 0; // default end of virtual window in bases //char *virtPosition = NULL; /* Name of virtual position. TODO REMOVE? */ char *virtChromName = NULL; /* Name of virtual chrom */ boolean virtMode = FALSE; /* Are we in virtual chrom mode? */ boolean virtChromChanged = FALSE; /* Has the virtChrom changed? */ boolean emAltHighlight = FALSE; /* Highlight alternativing regions in virt view? */ int emPadding = 6; /* # bases padding for exon-mostly regions */ int gmPadding = 6; /* # bases padding for gene-mostly regions */ char *emGeneTable = NULL; /* Gene table to use for exon mostly */ struct track *emGeneTrack = NULL; /* Track for gene table for exon mostly */ -struct rgbColor vertWindowSeparatorColor = { 255, 220, 220}; // light red +struct rgbColor vertWindowSeparatorColor = { 255, 220, 220, 255}; // light red char *multiRegionsBedUrl = ""; /* URL to Multi-window bed regions file */ // demo2 int demo2NumWindows = 70; int demo2WindowSize = 200; int demo2StepSize = 200; // singleTrans (single transcript) char *singleTransId = "uc001uub.1"; // singleAltHaplos (single haplotype) char *singleAltHaploId = "chr6_cox_hap2"; char *virtModeType = "default"; /* virtual chrom mode type */ char *lastVirtModeType = "default"; @@ -257,124 +257,124 @@ boolean withNextExonArrows = FALSE; /* Display next exon navigation buttons near center labels? */ boolean withExonNumbers = FALSE; /* Display exon and intron numbers in mouseOver instead of item name */ boolean revCmplDisp = FALSE; /* reverse-complement display */ boolean measureTiming = FALSE; /* DON'T EDIT THIS -- use CGI param "&measureTiming=." . */ struct track *trackList = NULL; /* List of all tracks. */ struct cart *cart; /* The cart where we keep persistent variables. */ int seqBaseCount; /* Number of bases in sequence. */ int winBaseCount; /* Number of bases in window. */ int maxShade = 9; /* Highest shade in a color gradient. */ Color shadesOfGray[10+1]; /* 10 shades of gray from white to black * Red is put at end to alert overflow. */ Color shadesOfBrown[10+1]; /* 10 shades of brown from tan to tar. */ -struct rgbColor brownColor = {100, 50, 0}; -struct rgbColor tanColor = {255, 240, 200}; -struct rgbColor guidelineColor = {220, 220, 255}; -struct rgbColor multiRegionAltColor = {235, 235, 255}; -struct rgbColor undefinedYellowColor = {240,240,180}; +struct rgbColor brownColor = {100, 50, 0, 255}; +struct rgbColor tanColor = {255, 240, 200, 255}; +struct rgbColor guidelineColor = {220, 220, 255, 255}; +struct rgbColor multiRegionAltColor = {235, 235, 255, 255}; +struct rgbColor undefinedYellowColor = {240,240,180, 255}; Color shadesOfSea[10+1]; /* Ten sea shades. */ -struct rgbColor darkSeaColor = {0, 60, 120}; -struct rgbColor lightSeaColor = {200, 220, 255}; +struct rgbColor darkSeaColor = {0, 60, 120, 255}; +struct rgbColor lightSeaColor = {200, 220, 255, 255}; struct hash *hgFindMatches; /* The matches found by hgFind that should be highlighted. */ struct trackLayout tl; void initTl() /* Initialize layout around small font and a picture about 600 pixels * wide. */ { trackLayoutInit(&tl, cart); } static boolean isTooLightForTextOnWhite(struct hvGfx *hvg, Color color) /* Return TRUE if text in this color would probably be invisible on a white background. */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); int colorTotal = rgbColor.r + 2*rgbColor.g + rgbColor.b; return colorTotal >= 512; } Color darkerColor(struct hvGfx *hvg, Color color) /* Get darker shade of a color - half way between this color and black */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); rgbColor.r = ((int)rgbColor.r)/2; rgbColor.g = ((int)rgbColor.g)/2; rgbColor.b = ((int)rgbColor.b)/2; -return hvGfxFindColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b); +return hvGfxFindAlphaColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b, rgbColor.a); } Color somewhatDarkerColor(struct hvGfx *hvg, Color color) /* Get a somewhat darker shade of a color - 1/3 of the way towards black. */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); rgbColor.r = (2*(int)rgbColor.r)/3; rgbColor.g = (2*(int)rgbColor.g)/3; rgbColor.b = (2*(int)rgbColor.b)/3; -return hvGfxFindColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b); +return hvGfxFindAlphaColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b, rgbColor.a); } Color slightlyDarkerColor(struct hvGfx *hvg, Color color) /* Get a slightly darker shade of a color - 1/4 of the way towards black. */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); rgbColor.r = (9*(int)rgbColor.r)/10; rgbColor.g = (9*(int)rgbColor.g)/10; rgbColor.b = (9*(int)rgbColor.b)/10; -return hvGfxFindColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b); +return hvGfxFindAlphaColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b, rgbColor.a); } Color lighterColor(struct hvGfx *hvg, Color color) /* Get lighter shade of a color - half way between this color and white */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); rgbColor.r = (rgbColor.r+255)/2; rgbColor.g = (rgbColor.g+255)/2; rgbColor.b = (rgbColor.b+255)/2; -return hvGfxFindColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b); +return hvGfxFindAlphaColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b, rgbColor.a); } Color somewhatLighterColor(struct hvGfx *hvg, Color color) /* Get a somewhat lighter shade of a color - 1/3 of the way towards white. */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); rgbColor.r = (2*rgbColor.r+255)/3; rgbColor.g = (2*rgbColor.g+255)/3; rgbColor.b = (2*rgbColor.b+255)/3; -return hvGfxFindColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b); +return hvGfxFindAlphaColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b, rgbColor.a); } boolean trackIsCompositeWithSubtracks(struct track *track) /* Temporary function until all composite tracks point to their own children */ { return (tdbIsComposite(track->tdb) && track->subtracks != NULL); } Color slightlyLighterColor(struct hvGfx *hvg, Color color) /* Get slightly lighter shade of a color - closer to gray actually */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); rgbColor.r = (rgbColor.r+128)/2; rgbColor.g = (rgbColor.g+128)/2; rgbColor.b = (rgbColor.b+128)/2; -return hvGfxFindColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b); +return hvGfxFindAlphaColorIx(hvg, rgbColor.r, rgbColor.g, rgbColor.b, rgbColor.a); } boolean winTooBigDoWiggle(struct cart *cart, struct track *tg) /* return true if we wiggle because the window size exceeds a certain threshold? */ { boolean doWiggle = FALSE; char *setting = trackDbSetting(tg->tdb, "maxWindowCoverage" ); if (setting) { unsigned size = sqlUnsigned(setting); if ((size > 0) && ((winEnd - winStart) > size)) doWiggle = TRUE; } return doWiggle; } @@ -3333,36 +3333,36 @@ { makeGrayShades(hvg); makeBrownShades(hvg); makeSeaShades(hvg); orangeColor = hvGfxFindColorIx(hvg, 230, 130, 0); brickColor = hvGfxFindColorIx(hvg, 230, 50, 110); blueColor = hvGfxFindColorIx(hvg, 0,114,198); darkBlueColor = hvGfxFindColorIx(hvg, 0,70,140); greenColor = hvGfxFindColorIx(hvg, 28,206,40); darkGreenColor = hvGfxFindColorIx(hvg, 28,140,40); } void makeRedGreenShades(struct hvGfx *hvg) /* Allocate the shades of Red, Green, Blue and Yellow for expression tracks */ { -static struct rgbColor black = {0, 0, 0}; -static struct rgbColor red = {255, 0, 0}; -static struct rgbColor green = {0, 255, 0}; -static struct rgbColor blue = {0, 0, 255}; -static struct rgbColor yellow = {255, 255, 0}; -static struct rgbColor white = {255, 255, 255}; +static struct rgbColor black = {0, 0, 0, 255}; +static struct rgbColor red = {255, 0, 0, 255}; +static struct rgbColor green = {0, 255, 0, 255}; +static struct rgbColor blue = {0, 0, 255, 255}; +static struct rgbColor yellow = {255, 255, 0, 255}; +static struct rgbColor white = {255, 255, 255, 255}; hvGfxMakeColorGradient(hvg, &black, &blue, EXPR_DATA_SHADES, shadesOfBlue); hvGfxMakeColorGradient(hvg, &black, &red, EXPR_DATA_SHADES, shadesOfRed); hvGfxMakeColorGradient(hvg, &black, &green, EXPR_DATA_SHADES, shadesOfGreen); hvGfxMakeColorGradient(hvg, &black, &yellow, EXPR_DATA_SHADES, shadesOfYellow); hvGfxMakeColorGradient(hvg, &white, &blue, EXPR_DATA_SHADES, shadesOfBlueOnWhite); hvGfxMakeColorGradient(hvg, &white, &red, EXPR_DATA_SHADES, shadesOfRedOnWhite); hvGfxMakeColorGradient(hvg, &white, &green, EXPR_DATA_SHADES, shadesOfGreenOnWhite); hvGfxMakeColorGradient(hvg, &white, &yellow, EXPR_DATA_SHADES, shadesOfYellowOnWhite); hvGfxMakeColorGradient(hvg, &yellow, &blue, EXPR_DATA_SHADES, shadesOfBlueOnYellow); hvGfxMakeColorGradient(hvg, &yellow, &red, EXPR_DATA_SHADES, shadesOfRedOnYellow); exprBedColorsMade = TRUE; } Color getOrangeColor() { @@ -3571,83 +3571,77 @@ if (x1 < 0) x1 = 0; if (x2 > hvg->width) x2 = hvg->width; if (x2-x1 > 0) hvGfxLine(hvg, x1, y, x2, y, color); } } static void lfColors(struct track *tg, struct linkedFeatures *lf, struct hvGfx *hvg, Color *retColor, Color *retBarbColor) /* Figure out color to draw linked feature in. */ { if (!((lf->isBigGenePred) ||(lf->filterColor == 0)|| (lf->filterColor == -1))) { if (lf->useItemRgb) { - struct rgbColor itemRgb; - itemRgb.r = (lf->filterColor & 0xff0000) >> 16; - itemRgb.g = (lf->filterColor & 0xff00) >> 8; - itemRgb.b = lf->filterColor & 0xff; - *retColor = *retBarbColor = - hvGfxFindColorIx(hvg, itemRgb.r, itemRgb.g, itemRgb.b); + *retColor = *retBarbColor = bedColorToGfxColor(lf->filterColor); } else *retColor = *retBarbColor = lf->filterColor; } else if (tg->itemColor) { *retColor = tg->itemColor(tg, lf, hvg); *retBarbColor = tg->ixAltColor; } else if (tg->colorShades) { boolean isXeno = (tg->subType == lfSubXeno) || (tg->subType == lfSubChain) || startsWith("mrnaBla", tg->table); *retColor = tg->colorShades[lf->grayIx+isXeno]; *retBarbColor = tg->colorShades[lf->grayIx]; } else { *retColor = tg->ixColor; *retBarbColor = tg->ixAltColor; } } Color bigGenePredColor(struct track *tg, void *item, struct hvGfx *hvg) /* Determine the color of the name for the bigGenePred linked feature. */ { struct linkedFeatures *lf = item; -struct rgbColor itemRgb; -itemRgb.r = (lf->filterColor & 0xff0000) >> 16; -itemRgb.g = (lf->filterColor & 0xff00) >> 8; -itemRgb.b = lf->filterColor & 0xff; -return hvGfxFindColorIx(hvg, itemRgb.r, itemRgb.g, itemRgb.b); +return bedColorToGfxColor(lf->filterColor); } Color blackItemNameColor(struct track *tg, void *item, struct hvGfx *hvg) /* Force item name (label) color to black */ { return hvGfxFindColorIx(hvg, 0, 0, 0); } Color linkedFeaturesNameColor(struct track *tg, void *item, struct hvGfx *hvg) /* Determine the color of the name for the linked feature. */ { Color col, barbCol; lfColors(tg, item, hvg, &col, &barbCol); -return col; +// Draw the item name fully opaque even even the item itself is drawn with alpha +struct rgbColor rgb = hvGfxColorIxToRgb(hvg, col); +rgb.a = 255; +return hvGfxFindRgb(hvg, &rgb); } struct simpleFeature *simpleFeatureCloneList(struct simpleFeature *list) /* Just copies the simpleFeature list. This is good for making a copy */ /* when the codon list is made. */ { struct simpleFeature *ret = NULL; struct simpleFeature *cur; for (cur = list; cur != NULL; cur = cur->next) { struct simpleFeature *newSf = NULL; AllocVar(newSf); newSf->start = cur->start; newSf->end = cur->end; newSf->qStart = cur->qStart; @@ -7727,31 +7721,31 @@ { nonCodingTypeIncludeCart[i] = cartUsualBoolean(cart, nonCodingTypeIncludeStrings[i], nonCodingTypeIncludeDefault[i]); } /* Convert genePred in window to linked feature */ tg->items = lfFromGenePredInRange(tg, tg->table, chromName, winStart, winEnd); /* filter items on selected criteria if filter is available */ filterItems(tg, filterNonCoding, "include"); } Color ensGeneNonCodingColor(struct track *tg, void *item, struct hvGfx *hvg) /* Return color to draw Ensembl non-coding gene/pseudogene in. */ { char condStr[255]; char *bioType; Color color = {MG_GRAY}; /* Set default to gray */ -struct rgbColor hAcaColor = {0, 128, 0}; /* darker green, per request by Weber */ +struct rgbColor hAcaColor = {0, 128, 0, 255}; /* darker green, per request by Weber */ Color hColor; struct sqlConnection *conn; char *name; conn = hAllocConn(database); hColor = hvGfxFindColorIx(hvg, hAcaColor.r, hAcaColor.g, hAcaColor.b); name = tg->itemName(tg, item); sqlSafef(condStr, sizeof condStr, "name='%s'", name); bioType = sqlGetField(database, "ensGeneNonCoding", "biotype", condStr); if (sameWord(bioType, "miRNA")) color = MG_RED; if (sameWord(bioType, "misc_RNA")) color = MG_BLACK; if (sameWord(bioType, "snRNA")) color = MG_BLUE; if (sameWord(bioType, "snoRNA")) color = MG_MAGENTA; if (sameWord(bioType, "rRNA")) color = MG_CYAN; @@ -9568,31 +9562,31 @@ /* Make track for rna genes . */ { tg->loadItems = loadRnaGene; tg->freeItems = freeRnaGene; tg->itemName = rnaGeneName; tg->itemColor = rnaGeneColor; } Color ncRnaColor(struct track *tg, void *item, struct hvGfx *hvg) /* Return color of ncRna track item. */ { char condStr[255]; char *rnaType; Color color = {MG_GRAY}; /* Set default to gray */ -struct rgbColor hAcaColor = {0, 128, 0}; /* darker green, per request by Weber */ +struct rgbColor hAcaColor = {0, 128, 0, 255}; /* darker green, per request by Weber */ Color hColor; struct sqlConnection *conn; char *name; conn = hAllocConn(database); hColor = hvGfxFindColorIx(hvg, hAcaColor.r, hAcaColor.g, hAcaColor.b); name = tg->itemName(tg, item); sqlSafef(condStr, sizeof condStr, "name='%s'", name); rnaType = sqlGetField(database, "ncRna", "type", condStr); if (sameWord(rnaType, "miRNA")) color = MG_RED; if (sameWord(rnaType, "misc_RNA")) color = MG_BLACK; if (sameWord(rnaType, "snRNA")) color = MG_BLUE; if (sameWord(rnaType, "snoRNA")) color = MG_MAGENTA; @@ -9606,31 +9600,31 @@ } void ncRnaMethods(struct track *tg) /* Make track for ncRna. */ { tg->itemColor = ncRnaColor; } Color wgRnaColor(struct track *tg, void *item, struct hvGfx *hvg) /* Return color of wgRna track item. */ { char condStr[255]; char *rnaType; Color color = {MG_BLACK}; /* Set default to black. But, if we got black, something is wrong. */ Color hColor; -struct rgbColor hAcaColor = {0, 128, 0}; /* darker green */ +struct rgbColor hAcaColor = {0, 128, 0, 255}; /* darker green */ struct sqlConnection *conn; char *name; conn = hAllocConn(database); hColor = hvGfxFindColorIx(hvg, hAcaColor.r, hAcaColor.g, hAcaColor.b); name = tg->itemName(tg, item); sqlSafef(condStr, sizeof condStr, "name='%s'", name); rnaType = sqlGetField(database, "wgRna", "type", condStr); if (sameWord(rnaType, "miRna")) color = MG_RED; if (sameWord(rnaType, "HAcaBox")) color = hColor; if (sameWord(rnaType, "CDBox")) color = MG_BLUE; if (sameWord(rnaType, "scaRna")) color = MG_MAGENTA; hFreeConn(&conn); @@ -12088,30 +12082,31 @@ found = FALSE; break; } } } sqlFreeResult(&sr); if (found) { /* need to convert color string to rgb */ // check how these are found for trackDb colorClone = cloneString(colorString); chopString(colorClone, sep, rgbVals, size); gClassColor.r = (sqlUnsigned(rgbVals[0])); gClassColor.g = (sqlUnsigned(rgbVals[1])); gClassColor.b = (sqlUnsigned(rgbVals[2])); + gClassColor.a = 0xff; /* find index for color */ color = hvGfxFindRgb(hvg, &gClassColor); } } hFreeConn(&conn); /* return index for color to draw item */ return color; } void drawColorMethods(struct track *tg) /* Fill in color track items based on chrom */ { char *optionStr ; optionStr = cartUsualStringClosestToHome(cart, tg->tdb,FALSE,"color", "off"); @@ -13006,34 +13001,36 @@ Lighter Green: for Class 1 OMIM records Light Green: for Class 2 OMIM records Dark Green: for Class 3 OMIM records Purple: for Class 4 OMIM records Light Gray: for Others */ lighter.r = (6*normal->r + 4*255) / 10; lighter.g = (6*normal->g + 4*255) / 10; lighter.b = (6*normal->b + 4*255) / 10; +lighter.a = normal->a; lightest.r = (1*normal->r + 2*255) / 3; lightest.g = (1*normal->g + 2*255) / 3; lightest.b = (1*normal->b + 2*255) / 3; +lightest.a = normal->a; struct sqlConnection *conn = hAllocConn(database); class1Clr = hvGfxFindColorIx(hvg, lightest.r, lightest.g, lightest.b); class2Clr = hvGfxFindColorIx(hvg, lighter.r, lighter.g, lighter.b); class3Clr = hvGfxFindColorIx(hvg, normal->r, normal->g, normal->b); class4Clr = hvGfxFindColorIx(hvg, 105,50,155); classOtherClr = hvGfxFindColorIx(hvg, 190, 190, 190); // light gray sqlSafef(query, sizeof(query), "select omimId, %s from omimPhenotype where omimId=%s order by %s desc", omimPhenotypeClassColName, el->name, omimPhenotypeClassColName); sr = sqlMustGetResult(conn, query); @@ -13343,34 +13340,36 @@ Lighter Green: for Class 1 OMIM records Light Green: for Class 2 OMIM records Dark Green: for Class 3 OMIM records Purple: for Class 4 OMIM records Light Gray: for Others */ lighter.r = (6*normal->r + 4*255) / 10; lighter.g = (6*normal->g + 4*255) / 10; lighter.b = (6*normal->b + 4*255) / 10; +lighter.a = normal->a; lightest.r = (1*normal->r + 2*255) / 3; lightest.g = (1*normal->g + 2*255) / 3; lightest.b = (1*normal->b + 2*255) / 3; +lightest.a = normal->a; class1Clr = hvGfxFindColorIx(hvg, lightest.r, lightest.g, lightest.b); class2Clr = hvGfxFindColorIx(hvg, lighter.r, lighter.g, lighter.b); class3Clr = hvGfxFindColorIx(hvg, normal->r, normal->g, normal->b); class4Clr = hvGfxFindColorIx(hvg, 105,50,155); classOtherClr = hvGfxFindColorIx(hvg, 190, 190, 190); // light gray struct sqlConnection *conn = hAllocConn(database); sqlSafef(query, sizeof(query), "select omimId, %s from omimPhenotype where omimId=%s", omimPhenotypeClassColName, el->name); sr = sqlMustGetResult(conn, query); row = sqlNextRow(sr); hFreeConn(&conn); @@ -14560,34 +14559,34 @@ if (sameString(type, "mathWig")) { buildMathWig(subTdb); } } } } #endif void makeCompositeTrack(struct track *track, struct trackDb *tdb) /* Construct track subtrack list from trackDb entry. * Sets up color gradient in subtracks if requested */ { buildMathWig(tdb); unsigned char finalR = track->color.r, finalG = track->color.g, - finalB = track->color.b; + finalB = track->color.b, finalA = track->color.a; unsigned char altR = track->altColor.r, altG = track->altColor.g, - altB = track->altColor.b; -unsigned char deltaR = 0, deltaG = 0, deltaB = 0; + altB = track->altColor.b, altA = track->altColor.a; +unsigned char deltaR = 0, deltaG = 0, deltaB = 0, deltaA = 0; struct slRef *tdbRef, *tdbRefList = trackDbListGetRefsToDescendantLeaves(tdb->subtracks); struct trackDb *subTdb; int subCount = slCount(tdbRefList); int altColors = subCount - 1; struct track *subtrack = NULL; TrackHandler handler; boolean smart = FALSE; /* ignore if no subtracks */ if (!subCount) return; char *compositeTrack = trackDbLocalSetting(tdb, "compositeTrack"); @@ -14602,30 +14601,33 @@ /* handles it's own load and height */ handler(track); else { track->loadItems = compositeLoad; track->totalHeight = compositeTotalHeight; } if (altColors && (finalR || finalG || finalB)) { /* not black -- make a color gradient for the subtracks, from black, to the specified color */ deltaR = (finalR - altR) / altColors; deltaG = (finalG - altG) / altColors; deltaB = (finalB - altB) / altColors; + // speculative - no harm, but there's no current way for a track to set its alpha, + // so both final and altA should be 255 + deltaA = (finalA - altA) / altColors; } /* fill in subtracks of composite track */ for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { subTdb = tdbRef->val; subtrack = trackFromTrackDb(subTdb); handler = lookupTrackHandlerClosestToHome(subTdb); if (handler != NULL) handler(subtrack); /* Add subtrack settings (table, colors, labels, vis & pri). This is only * needed in the "not noInherit" case that hopefully will go away soon. */ subtrack->track = subTdb->track; @@ -14635,39 +14637,44 @@ subtrack->priority = subTdb->priority; subtrack->parent = track; /* Add color gradient. */ if (finalR || finalG || finalB) { subtrack->color.r = altR; subtrack->altColor.r = (255+altR)/2; altR += deltaR; subtrack->color.g = altG; subtrack->altColor.g = (255+altG)/2; altG += deltaG; subtrack->color.b = altB; subtrack->altColor.b = (255+altB)/2; altB += deltaB; + subtrack->color.a = altA; + subtrack->altColor.a = altA; + altA += deltaA; } else { subtrack->color.r = subTdb->colorR; subtrack->color.g = subTdb->colorG; subtrack->color.b = subTdb->colorB; + subtrack->color.a = 255; subtrack->altColor.r = subTdb->altColorR; subtrack->altColor.g = subTdb->altColorG; subtrack->altColor.b = subTdb->altColorB; + subtrack->altColor.a = 255; } slAddHead(&track->subtracks, subtrack); } slSort(&track->subtracks, trackPriCmp); } struct track *trackFromTrackDb(struct trackDb *tdb) /* Create a track based on the tdb */ { struct track *track = NULL; char *exonArrows; char *nextItem; if (!tdb) return NULL; @@ -14707,33 +14714,35 @@ if (version) { char longLabel[1024]; safef(longLabel, sizeof(longLabel), "%s - Annotation Release %s", tdb->longLabel, version); track->longLabel = cloneString(longLabel); tdb->longLabel = cloneString(longLabel); } else track->longLabel = cloneString(tdb->longLabel); } else track->longLabel = cloneString(tdb->longLabel); track->color.r = tdb->colorR; track->color.g = tdb->colorG; track->color.b = tdb->colorB; +track->color.a = 255; // No way to specify alpha in tdb currently - assume it's fully opaque track->altColor.r = tdb->altColorR; track->altColor.g = tdb->altColorG; track->altColor.b = tdb->altColorB; +track->altColor.a = 255; track->lineHeight = tl.fontHeight+1; track->heightPer = track->lineHeight - 1; track->private = tdb->private; track->defaultPriority = tdb->priority; char lookUpName[256]; safef(lookUpName, sizeof(lookUpName), "%s.priority", tdb->track); tdb->priority = cartUsualDouble(cart, lookUpName, tdb->priority); track->priority = tdb->priority; track->groupName = cloneString(tdb->grp); /* save default priority and group so we can reset it later */ track->defaultGroupName = cloneString(tdb->grp); track->canPack = tdb->canPack; if (tdb->useScore) { /* Todo: expand spectrum opportunities. */