ace7d6c2a03c2ad76c14134546785b8c3fa61ac2
kate
  Tue Jan 8 11:39:09 2019 -0800
Implement 'packDense' setting (tentative name) to support Regeneron 2nd contract amino acide display.  This setting will pack items on a single line if they are adjacent (suppresses padding between packed items). refs #22739

diff --git src/lib/spaceSaver.c src/lib/spaceSaver.c
index f5297a6..32e07c2 100644
--- src/lib/spaceSaver.c
+++ src/lib/spaceSaver.c
@@ -47,60 +47,60 @@
     slFreeList(&ss->nodeList);
     freez(pSs);
     }
 }
 
 static boolean allClear(bool *b, int count)
 /* Return TRUE if count bools starting at b are all 0 */
 {
 int i;
 for (i=0; i<count; ++i)
     if (b[i])
 	return FALSE;
 return TRUE;
 }
 
-struct spaceNode *spaceSaverAddOverflowMulti(struct spaceSaver *ss, 
+struct spaceNode *spaceSaverAddOverflowMultiOptionalPadding(struct spaceSaver *ss, 
 	                struct spaceRange *rangeList, struct spaceNode *nodeList, 
-					boolean allowOverflow)
+					boolean allowOverflow, boolean doPadding)
 /* Add new nodes for multiple windows to space saver. Returns NULL if can't fit item in
  * and allowOverflow == FALSE. If allowOverflow == TRUE then put items
  * that won't fit in first row (ends up being last row after
- * spaceSaverFinish()). */
+ * spaceSaverFinish()). Allow caller to suppress padding between items 
+ * (show adjacent items on single row */
 {
-//int cellStart, cellEnd, cellWidth;
 struct spaceRowTracker *srt, *freeSrt = NULL;
 int rowIx = 0;
 struct spaceNode *sn;
 
 if (ss->isFull)
     return NULL;
 
 struct spaceRange *range;
 struct spaceRange *cellRanges = NULL, *cellRange;
 
 for (range = rangeList; range; range = range->next)
     {
     AllocVar(cellRange);
     int start = range->start;
     int end   = range->end;
     if ((start -= ss->winStart) < 0)
     	start = 0;
     end -= ss->winStart;	/* We'll clip this in cell coordinates. */
-
     cellRange->start = round(start * ss->scale);
-    cellRange->end = round(end * ss->scale)+1;
+    int padding = doPadding ? 1 : 0;
+    cellRange->end = round(end * ss->scale) + padding;
     if (cellRange->end > ss->cellsInRow)
 	cellRange->end = ss->cellsInRow;
     cellRange->width = cellRange->end - cellRange->start;
     slAddHead(&cellRanges, cellRange);
     }
 slReverse(&cellRanges);
 
 
 if (ss->vis == 2) // tvFull for BEDLIKE tracks does not pack, so force a new line
     {
     rowIx = ss->rowCount;
     }
 else
     {
     /* Find free row. */
@@ -160,30 +160,40 @@
 //
 struct spaceNode *snNext;
 for (sn=nodeList; sn; sn=snNext)
     {
     /* Make a space node. If allowing overflow it will
      all end up in the last row. */
     //AllocVar(sn);
     sn->row = rowIx;
     //sn->val = val;
     snNext = sn->next;
     slAddHead(&sn->parentSs->nodeList, sn);
     }
 return nodeList;
 }
 
+struct spaceNode *spaceSaverAddOverflowMulti(struct spaceSaver *ss, 
+	struct spaceRange *rangeList, struct spaceNode *nodeList, 
+					boolean allowOverflow)
+/* Add new nodes for multiple windows to space saver. Returns NULL if can't fit item in
+ * and allowOverflow == FALSE. If allowOverflow == TRUE then put items
+ * that won't fit in first row (ends up being last row after
+ * spaceSaverFinish()). */
+{
+return spaceSaverAddOverflowMultiOptionalPadding(ss, rangeList, nodeList, allowOverflow, TRUE);
+}
 
 struct spaceNode *spaceSaverAddOverflowExtended(struct spaceSaver *ss, int start, int end, 
 					void *val, boolean allowOverflow, struct spaceSaver *parentSs, bool noLabel)
 /* Add a new node to space saver. Returns NULL if can't fit item in
  * and allowOverflow == FALSE. If allowOverflow == TRUE then put items
  * that won't fit in last row. parentSs allows specification of destination for node from alternate window.*/
 {
 struct spaceRange *range;
 AllocVar(range);
 range->start = start;
 range->end = end;
 struct spaceNode *node;
 AllocVar(node);
 node->val = val;
 node->parentSs = parentSs;