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);
     }