d1d559e9bee7fcaec3a50ae43688ca436656ad7b
kate
  Wed Nov 18 08:25:58 2015 -0800
Finish variable height item packing. Adds an optional rowSizes field to spaceSaver. refs #15645

diff --git src/lib/spaceSaver.c src/lib/spaceSaver.c
index b39bd60..59a1d50 100644
--- src/lib/spaceSaver.c
+++ src/lib/spaceSaver.c
@@ -125,20 +125,49 @@
 AllocVar(sn);
 sn->row = rowIx;
 sn->val = val;
 slAddHead(&ss->nodeList, sn);
 return sn;
 }
 
 struct spaceNode *spaceSaverAdd(struct spaceSaver *ss, 
 	int start, int end, void *val)
 /* Add a new node to space saver. Returns NULL if can't fit
  * item in. */
 {
 return spaceSaverAddOverflow(ss, start, end, val, FALSE);
 }
 
+int spaceSaverSetRowHeights(struct spaceSaver *ss, int (*itemHeight)(void *item))
+/* Determine maximum height of items in a row. Return total height.
+   Used by tracks with variable height items */
+{
+assert(ss != NULL);
+AllocArray(ss->rowSizes, ss->rowCount);
+struct spaceNode *sn;
+for (sn = ss->nodeList; sn != NULL; sn = sn->next)
+    {
+    ss->rowSizes[sn->row] = max(ss->rowSizes[sn->row], itemHeight(sn->val));
+    }
+return spaceSaverGetRowHeightsTotal(ss);
+}
+
+int spaceSaverGetRowHeightsTotal(struct spaceSaver *ss)
+/* Return height of all rows. Used by tracks with variable height items */
+{
+assert(ss != NULL);
+if (ss->rowSizes == NULL)
+    return 0;
+int height = 0;
+int i;
+for (i=0; i<ss->rowCount; i++)
+    {
+    height += ss->rowSizes[i];
+    }
+return height;
+}
+
 void spaceSaverFinish(struct spaceSaver *ss)
 /* Tell spaceSaver done adding nodes. */
 {
 slReverse(&ss->nodeList);
 }