6777815b495172716ac5fe8f18a5b375a4196397
jcasper
  Wed Oct 4 15:09:41 2023 -0700
Fix for label mapboxes not being drawn, refs #30237

diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index c727904..7ffcb9d 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -4510,65 +4510,86 @@
 void genericItemMapAndArrows(struct track *tg, struct spaceNode *sn,
                                     struct hvGfx *hvg, int xOff, int y, int width,
                                     MgFont *font, Color color, Color labelColor, enum trackVisibility vis,
                                     double scale, boolean withLeftLabels)
 /* Generic function for putting down a mapbox with a label and drawing exon arrows */
 {
 struct slList *item = sn->val;
 int s = tg->itemStart(tg, item);
 int e = tg->itemEnd(tg, item);
 int sClp = (s < winStart) ? winStart : s;
 int eClp = (e > winEnd)   ? winEnd   : e;
 int x1 = round((sClp - winStart)*scale) + xOff;
 int x2 = round((eClp - winStart)*scale) + xOff;
 int textX = x1;
 
+if (tg->drawLabelInBox)
+    withLeftLabels = FALSE;
+
+boolean withLabels = (withLeftLabels && withIndividualLabels && ((vis == tvPack) || (vis == tvFull && isTypeBedLike(tg))) && (!sn->noLabel) && !tg->drawName);
+if (withLabels)
+    {
+    char *name = tg->itemName(tg, item);
+    int nameWidth = mgFontStringWidth(font, name);
+    int dotWidth = tl.nWidth/2;
+    boolean snapLeft = FALSE;
+    textX -= nameWidth + dotWidth;
+    snapLeft = (textX < fullInsideX);
+    snapLeft |= (vis == tvFull && isTypeBedLike(tg));
+
+    /* Special tweak for expRatio in pack mode: force all labels
+     * left to prevent only a subset from being placed right: */
+    snapLeft |= (startsWith("expRatio", tg->tdb->type));
+
+#ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
+    if (theImgBox == NULL && snapLeft)
+#else///ifndef IMAGEv2_NO_LEFTLABEL_ON_FULL
+    if (snapLeft)        /* Snap label to the left. */
+#endif ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL
+        {
+        textX = leftLabelX;
+        assert(hvgSide != NULL);
+        }
+    }
 
 if (!tg->mapsSelf)
     {
     int w = x2-textX;
     /* Arrows? */
     if (w > 0)
         {
         if (nextItemCompatible(tg))
             genericDrawNextItemStuff(tg, hvg, vis, item, scale, x2, x1, textX, y, tg->heightPer, color, TRUE);
         else if (exonNumberMapsCompatible(tg, vis))
             genericDrawNextItemStuff(tg, hvg, vis, item, scale, x2, x1, textX, y, tg->heightPer, color, FALSE);
         else
             {
             tg->mapItem(tg, hvg, item, tg->itemName(tg, item),
                         tg->mapItemName(tg, item), s, e, textX, y, w, tg->heightPer);
             }
         }
     }
 }
 
 
 static void genericDrawItem(struct track *tg, struct spaceNode *sn,
                             struct hvGfx *hvg, int xOff, int yOff, int width,
                             MgFont *font, Color color, Color labelColor, enum trackVisibility vis,
                             double scale, boolean withLeftLabels)
 /* draw one non-overflow item */
 {
 struct slList *item = sn->val;
-//int s = tg->itemStart(tg, item);
-//int e = tg->itemEnd(tg, item);
-//int sClp = (s < winStart) ? winStart : s;
-//int eClp = (e > winEnd)   ? winEnd   : e;
-//int x1 = round((sClp - winStart)*scale) + xOff;
-//int x2 = round((eClp - winStart)*scale) + xOff;
-//int textX = x1;
 
 if (tg->drawLabelInBox)
     withLeftLabels = FALSE;
 
 if (tg->itemNameColor != NULL)
     {
     color = tg->itemNameColor(tg, item, hvg);
     labelColor = color;
     if (withLeftLabels && isTooLightForTextOnWhite(hvg, color))
 	labelColor = somewhatDarkerColor(hvg, color);
     }
 
 // get y offset for item in pack mode
 int yRow = 0;
 if (tg->ss && tg->ss->rowSizes != NULL)
@@ -4580,30 +4601,33 @@
     yRow += (tg->ss->rowSizes[sn->row] - itemHeight + 1);
     tg->heightPer = itemHeight;
     }
 else
     yRow = tg->lineHeight * sn->row;
 int y = yOff + yRow;
 
 tg->drawItemAt(tg, item, hvg, xOff, y, scale, font, color, vis);
 
 // GALT non-proportional track like gtexGene
 handleNonPropDrawItemAt(tg, sn, item, hvg, xOff, y, scale, font, color, vis);
 
 tg->drawItemLabel(tg, sn, hvg, xOff, y, width, font, color, labelColor, vis, scale, withLeftLabels);
 
 // do mapping and arrows
+// NB: I'd be happy to move the label mapbox draw from the next function into the preceding function,
+// so that it sits with the label drawing and doesn't duplicate those calculations.  That's a problem
+// to tackle another time though.
 
 tg->doItemMapAndArrows(tg, sn, hvg, xOff, y, width, font, color, labelColor, vis, scale, withLeftLabels);
 }
 
 int normalizeCount(struct preDrawElement *el, double countFactor,
     double minVal, double maxVal, double sumData, double sumSquares)
 /* Normalize statistics to be based on an integer number of valid bases.
  * Integer value is the smallest integer not less than countFactor. */
 {
 bits32 validCount = ceil(countFactor);
 double normFactor = (double)validCount/countFactor;
 
 el->count = validCount;
 el->min = minVal;
 el->max = maxVal;