6d15c4259016e2b9bca547840c4edba7f25bdfcd
jcasper
  Mon Oct 13 13:35:01 2025 -0700
Adding plus and X decoration glyphs, and correcting placement for decorating
multi-row items, no ticket (request from Max)

diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index f3da11ba9cb..a4204665135 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -1724,31 +1724,35 @@
  * Note that triangle and inverse triangle subvert this a little by extending just outside those bounds.
  */
 static struct glyphShape glyphShapes[] = {
     [GLYPH_CIRCLE] = (struct glyphShape) {0, NULL},
 
     [GLYPH_TRIANGLE] = (struct glyphShape) {3, (struct xyPair[]) {{0.5,0},{1.07735,1},{-0.07735,1}}},
     [GLYPH_INV_TRIANGLE] = (struct glyphShape) {3, (struct xyPair[]) {{0.5,1},{1.07735,0},{-0.07735,0}}},
     [GLYPH_SQUARE] = (struct glyphShape) {4, (struct xyPair[]) {{0,0},{1,0},{1,1},{0,1}}},
     [GLYPH_DIAMOND] = (struct glyphShape) {4, (struct xyPair[]) {{0.5,0},{1,0.5},{0.5,1},{0,0.5}}},
     [GLYPH_PENTAGRAM] = (struct glyphShape) {5, (struct xyPair[]) {{0.5,0.0},{0.824920,1.0},{-0.025731,0.381966},
             {1.02573,0.381966},{0.175080,1}}},
     [GLYPH_OCTAGON] = (struct glyphShape) {8, (struct xyPair[]) {{0.292893,1},{0.707107,1},{1,0.707107},
             {1,0.292893},{0.707107,0},{0.292893,0},{0,0.292893},{0,0.707107}}},
     [GLYPH_STAR] = (struct glyphShape) {10, (struct xyPair[]) {{0.500000,0.000000},{0.624108,0.381966},{1.025731,0.381966},
             {0.700811,0.618034},{0.824920,1.000000},{0.500000,0.763932},{0.175080,1.000000},{0.299189,0.618034},
-            {-0.025731,0.381966},{0.375892,0.381966}}}
+            {-0.025731,0.381966},{0.375892,0.381966}}},
+    [GLYPH_PLUS] = (struct glyphShape) {12, (struct xyPair[]) {{0.4,0},{0.6,0},{0.6,0.4},{1.0,0.4},{1.0,0.6},{0.6,0.6},
+            {0.6,1.0},{0.4,1.0},{0.4,0.6},{0,0.6},{0,0.4},{0.4,0.4}}},
+    [GLYPH_X] = (struct glyphShape) {12, (struct xyPair[]) {{0.1,0},{0.5,0.4},{0.9,0},{1,0.1},{0.6,0.5},{1,0.9},{0.9,1},
+            {0.5,0.6},{0.1,1},{0,0.9},{0.4,0.5},{0,0.1}}}
 };
 
 
 void drawScaledGlyph(struct hvGfx *hvg, int chromStart, int chromEnd, double scale, int xOff, int y,
                       int heightPer, glyphType glyph, boolean filled, Color outlineColor, Color fillColor)
 /* Draw a glyph as a circle/polygon.  If filled, draw as with fillColor,
  * which may have transparency.
  */
 {
 int glyphHeight = heightPer-1;
 int startX, endX;
 double middleX, middleY = y+heightPer/2.0;
 // A glyph might be defined on a wide range - find the center and draw specifically there
 // so we don't have a glyph shifting if only part of that window is in view.
 int centeredStart, centeredEnd;
@@ -1776,49 +1780,55 @@
         hvGfxDrawPoly(hvg,poly,fillColor,TRUE);
         hvGfxDrawPoly(hvg,poly,outlineColor,FALSE);
         gfxPolyFree(&poly);
         break;
     }
 }
 
 #define GLYPH_STRING_CIRCLE "Circle"
 #define GLYPH_STRING_TRIANGLE "Triangle"
 #define GLYPH_STRING_INV_TRIANGLE "InvTriangle"
 #define GLYPH_STRING_SQUARE "Square"
 #define GLYPH_STRING_DIAMOND "Diamond"
 #define GLYPH_STRING_OCTAGON "Octagon"
 #define GLYPH_STRING_STAR "Star"
 #define GLYPH_STRING_PENTAGRAM "Pentagram"
+#define GLYPH_STRING_PLUS "Plus"
+#define GLYPH_STRING_X "X"
 
 glyphType parseGlyphType(char *glyphStr)
 /* Return the enum glyph type for a string specifying a glyph.
  * Defaults to GLYPH_CIRCLE if the string is unrecognized. */
 {
 if (sameWordOk(glyphStr, GLYPH_STRING_TRIANGLE))
     return GLYPH_TRIANGLE;
 if (sameWordOk(glyphStr, GLYPH_STRING_INV_TRIANGLE))
     return GLYPH_INV_TRIANGLE;
 if (sameWordOk(glyphStr, GLYPH_STRING_SQUARE))
     return GLYPH_SQUARE;
 if (sameWordOk(glyphStr, GLYPH_STRING_DIAMOND))
     return GLYPH_DIAMOND;
 if (sameWordOk(glyphStr, GLYPH_STRING_OCTAGON))
     return GLYPH_OCTAGON;
 if (sameWordOk(glyphStr, GLYPH_STRING_STAR))
     return GLYPH_STAR;
 if (sameWordOk(glyphStr, GLYPH_STRING_PENTAGRAM))
     return GLYPH_PENTAGRAM;
+if (sameWordOk(glyphStr, GLYPH_STRING_PLUS))
+    return GLYPH_PLUS;
+if (sameWordOk(glyphStr, GLYPH_STRING_X))
+    return GLYPH_X;
 
 return GLYPH_CIRCLE;
 }
 
 void filterItemsOnNames(struct track *tg)
 /* Only keep items with a name in the .nameFilter cart var. 
  * Not using filterItems(), because filterItems has no state at all. */
 {
 char varName[SMALLBUF];
 safef(varName, sizeof(varName), "%s.nameFilter", tg->tdb->track);
 char *nameFilterStr = cartNonemptyString(cart, varName);
 
 if (nameFilterStr==NULL)
     return;