38cc0731871ba38d4278bf5acc3e22663c778253 hiram Fri Oct 17 09:24:56 2014 -0700 fixup font sizing issues refs #9741 diff --git src/hg/hgTracks/rmskJoinedTrack.c src/hg/hgTracks/rmskJoinedTrack.c index d69d324..8642be6 100644 --- src/hg/hgTracks/rmskJoinedTrack.c +++ src/hg/hgTracks/rmskJoinedTrack.c @@ -28,31 +28,31 @@ * detailed view of repeats is turned on, otherwise it reverts * back to the original UCSC glyph. */ #define DETAIL_VIEW_MAX_SCALE 30000 /* MAX_UNALIGNED_PIXEL_LEN: The maximum size of unaligned sequence * to draw before switching to the unscaled view: ie. "----/###/---" * This is measured in pixels *not* base pairs due to the * mixture of scaled ( lines ) and unscaled ( text ) glyph * components. */ #define MAX_UNALIGNED_PIXEL_LEN 150 // TODO: Document #define LABEL_PADDING 5 - +#define MINHEIGHT 24 // TODO: Document static float pixelsPerBase = 1.0; /* Hash of the repeatItems ( tg->items ) for this track. * This is used to hold display names for the lines of * the track, the line heights, and class colors. */ struct hash *classHash = NULL; static struct repeatItem *otherRepeatItem = NULL; /* Hash of subtracks * The joinedRmskTrack is designed to be used as a composite track. * When rmskJoinedLoadItems is called this hash is populated with the * results of one or more table queries @@ -170,47 +170,60 @@ safef(lenLabel, sizeof(lenLabel), "%d", rm->blockSizes[rm->blockCount - 1]); ex.end += (int) (MAX_UNALIGNED_PIXEL_LEN / pixelsPerBase) + (int) ((mgFontStringWidth(tl.font, lenLabel) + LABEL_PADDING) / pixelsPerBase); } else { ex.end += rm->blockSizes[rm->blockCount - 1]; } return &ex; } -static int cmpRepeatVisStart(const void *va, const void *vb) +// A better way to organize the display +static int cmpRepeatDiv(const void *va, const void *vb) +/* Sort repeats by divergence. + */ +{ +struct rmskJoined *a = *((struct rmskJoined **) va); +struct rmskJoined *b = *((struct rmskJoined **) vb); + +return (b->score - a->score); +} + +//static int cmpRepeatVisStart(const void *va, const void *vb) /* Sort repeats by display start position. Note: We * account for the fact we may not start the visual * display at chromStart. See MAX_UNALIGNED_PIXEL_LEN. */ +/* { struct rmskJoined *a = *((struct rmskJoined **) va); struct rmskJoined *b = *((struct rmskJoined **) vb); struct Extents *ext = NULL; ext = getExtents(a); int aStart = ext->start; ext = getExtents(b); int bStart = ext->start; return (aStart - bStart); } +*/ static struct repeatItem * makeJRepeatItems() /* Initialize the track */ { classHash = newHash(6); struct repeatItem *ri, *riList = NULL; int i; int numClasses = ArraySize(rptClasses); for (i = 0; i < numClasses; ++i) { AllocVar(ri); ri->class = rptClasses[i]; ri->className = rptClassNames[i]; // New color attribute ri->color = rmskJoinedClassColors[i]; @@ -247,31 +260,32 @@ st->levels[0] = NULL; st->levelCount = 0; struct rmskJoined *rm = NULL; char **row; int rowOffset; struct sqlConnection *conn = hAllocConn(database); struct sqlResult *sr = hRangeQuery(conn, tg->table, chromName, winStart, winEnd, NULL, &rowOffset); struct rmskJoined *detailList = NULL; while ((row = sqlNextRow(sr)) != NULL) { rm = rmskJoinedLoad(row + rowOffset); slAddHead(&detailList, rm); } - slSort(&detailList, cmpRepeatVisStart); + //slSort(&detailList, cmpRepeatVisStart); + slSort(&detailList, cmpRepeatDiv); sqlFreeResult(&sr); hFreeConn(&conn); int crChromStart, crChromEnd; while (detailList) { st->levels[st->levelCount++] = detailList; struct rmskJoined *cr = detailList; detailList = detailList->next; cr->next = NULL; int rmChromStart, rmChromEnd; struct rmskJoined *prev = NULL; rm = detailList; @@ -328,57 +342,63 @@ /* * In detail view mode the items represent different packing * levels. No need to display a label at each level. Instead * Just return a label for the first level. */ if (tg->limitedVis == tvFull && winBaseCount <= DETAIL_VIEW_MAX_SCALE) { if (strcmp(ri->className, "SINE") == 0) return("Repeats"); else return ∅ } return ri->className; } -#define HEIGHT24 24 -int rmskJoinedTotalHeight(struct track *tg, enum trackVisibility vis) +int rmskJoinedItemHeight(struct track *tg, void *item) { // Are we in full view mode and at the scale needed to display // the detail view? if (tg->limitedVis == tvFull && winBaseCount <= DETAIL_VIEW_MAX_SCALE) { - // Lookup the depth of this subTrack and report it - struct subTrack *st = hashFindVal(subTracksHash, tg->table); - if (st) - return ((st->levelCount + 1) * HEIGHT24); + if ( tg->heightPer < MINHEIGHT ) + return MINHEIGHT; else - return (HEIGHT24); // Just display one line + return tg->heightPer; } else -return tgFixedTotalHeightNoOverflow(tg, vis); + { + return tgFixedItemHeight(tg, item); + } } -int rmskJoinedItemHeight(struct track *tg, void *item) +int rmskJoinedTotalHeight(struct track *tg, enum trackVisibility vis) { // Are we in full view mode and at the scale needed to display // the detail view? if (tg->limitedVis == tvFull && winBaseCount <= DETAIL_VIEW_MAX_SCALE) - return HEIGHT24; + { + // Lookup the depth of this subTrack and report it + struct subTrack *st = hashFindVal(subTracksHash, tg->table); + if (st) + return ((st->levelCount + 1) * rmskJoinedItemHeight(tg, NULL) ); else - return tgFixedItemHeight(tg, item); + return (rmskJoinedItemHeight(tg, NULL)); // Just display one line + } +else +return tgFixedTotalHeightNoOverflow(tg, vis); } static void drawDashedHorizLine(struct hvGfx *hvg, int x1, int x2, int y, int dashLen, int gapLen, Color lineColor) // ie. - - - - - - - - - - - - - - - - { int cx1 = x1; int cx2; while (1) { cx2 = cx1 + dashLen; if (cx2 > x2) cx2 = x2; hvGfxLine(hvg, cx1, y, cx2, y, lineColor); cx1 += (dashLen + gapLen); @@ -399,62 +419,62 @@ safef(lenLabel, sizeof(lenLabel), "%d", unalignedLen); MgFont *font = tl.font; int fontHeight = tl.fontHeight; int stringWidth = mgFontStringWidth(font, lenLabel) + LABEL_PADDING; int glyphWidth = x2 - x1; if (glyphWidth < stringWidth + 6 + (2 * dashLen)) stringWidth = 0; int midX = ((glyphWidth) / 2) + x1; int startHash = midX - (stringWidth * 0.5); int midPointDrawn = 0; /* - Degrade Gracefully: + * Degrade Gracefully: * Too little space to draw dashes or even * hash marks, give up. */ if (glyphWidth < 6 + dashLen) { hvGfxLine(hvg, x1, y, x2, y, lineColor); return; } if (glyphWidth < 6 + (2 * dashLen)) { midX -= 3; hvGfxLine(hvg, x1, y, midX, y, lineColor); hvGfxLine(hvg, midX, y - 3, midX + 3, y + 3, lineColor); hvGfxLine(hvg, midX + 3, y - 3, midX + 6, y + 3, lineColor); hvGfxLine(hvg, midX + 6, y, x2, y, lineColor); return; } while (1) { cx2 = cx1 + dashLen; if (cx2 > x2) cx2 = x2; if (!midPointDrawn && cx2 > startHash) { // Draw double slashes "\\" instead of dash hvGfxLine(hvg, cx1, y - 3, cx1 + 3, y + 3, lineColor); if (stringWidth) { - hvGfxTextCentered(hvg, cx1 + 3, y - 3, stringWidth, + hvGfxTextCentered(hvg, cx1 + 3, y - (fontHeight/2), stringWidth, fontHeight, MG_BLACK, font, lenLabel); cx1 += stringWidth; } hvGfxLine(hvg, cx1 + 3, y - 3, cx1 + 6, y + 3, lineColor); cx1 += 6; midPointDrawn = 1; } else { // Draw a dash hvGfxLine(hvg, cx1, y, cx2, y, lineColor); cx1 += dashLen; } if (!midPointDrawn && cx1 + gapLen > midX) @@ -744,31 +764,31 @@ drawDashedHorizLine(hvg, lx1, lx2, y + unalignedBlockOffset, 5, 5, black); } // Line down hvGfxLine(hvg, lx2, y + alignedBlockOffset, lx2, y + unalignedBlockOffset, black); hvGfxLine(hvg, lx1, y + unalignedBlockOffset - 3, lx1, y + unalignedBlockOffset + 3, black); // Draw labels MgFont *font = tl.font; int fontHeight = tl.fontHeight; int stringWidth = mgFontStringWidth(font, rm->name) + LABEL_PADDING; hvGfxTextCentered(hvg, lx1 - stringWidth, - y + unalignedBlockOffset + fontHeight, + heightPer - fontHeight + y, stringWidth, fontHeight, MG_BLACK, font, rm->name); } else if (idx == (rm->blockCount - 1)) { /* * Unaligned sequence at the end of an annotation * Draw as: * -------------| or ------//------| * | | * >>>>> >>>>>>> */ lx1 = roundingScale(rm->chromStart +