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 &empty;
     }
 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 +