+ double leftmost_digit;
+ uint64_t exp10;
+ int i;
+
+ /* The following code determines the max_value in the graph as well as
+ * how many describing lines are drawn. The max_value is rounded up,
+ * so that all drawn numbers are rounded for readability.
+ * We want to print multiples of a simple number instead of multiples of
+ * hard-to-read numbers like 1.753.
+ */
+
+ /* Find the left-most digit. */
+ exp10 = 1;
+ for (i = 0; value > 9 * exp10; i++) {
+ exp10 *= 10;
+ fixup_bytes(pane->type, i + 1, &exp10);
+ }
+
+ leftmost_digit = DIV_ROUND_UP(value, exp10);
+
+ /* Round 9 to 10. */
+ if (leftmost_digit == 9) {
+ leftmost_digit = 1;
+ exp10 *= 10;
+ fixup_bytes(pane->type, i + 1, &exp10);
+ }
+
+ switch ((unsigned)leftmost_digit) {
+ case 1:
+ pane->last_line = 5; /* lines in +1/5 increments */
+ break;
+ case 2:
+ pane->last_line = 8; /* lines in +1/4 increments. */
+ break;
+ case 3:
+ case 4:
+ pane->last_line = leftmost_digit * 2; /* lines in +1/2 increments */
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ pane->last_line = leftmost_digit; /* lines in +1 increments */
+ break;
+ default:
+ assert(0);
+ }
+
+ /* Truncate {3,4} to {2.5, 3.5} if possible. */
+ for (i = 3; i <= 4; i++) {
+ if (leftmost_digit == i && value <= (i - 0.5) * exp10) {
+ leftmost_digit = i - 0.5;
+ pane->last_line = leftmost_digit * 2; /* lines in +1/2 increments. */
+ }
+ }
+
+ /* Truncate 2 to a multiple of 0.2 in (1, 1.6] if possible. */
+ if (leftmost_digit == 2) {
+ for (i = 1; i <= 3; i++) {
+ if (value <= (1 + i*0.2) * exp10) {
+ leftmost_digit = 1 + i*0.2;
+ pane->last_line = 5 + i; /* lines in +1/5 increments. */
+ break;
+ }
+ }
+ }
+
+ pane->max_value = leftmost_digit * exp10;
+ pane->yscale = -(int)pane->inner_height / (float)pane->max_value;
+}
+
+static void
+hud_pane_update_dyn_ceiling(struct hud_graph *gr, struct hud_pane *pane)
+{
+ unsigned i;
+ float tmp = 0.0f;
+
+ if (pane->dyn_ceil_last_ran != gr->index) {
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ for (i = 0; i < gr->num_vertices; ++i) {
+ tmp = gr->vertices[i * 2 + 1] > tmp ?
+ gr->vertices[i * 2 + 1] : tmp;
+ }
+ }
+
+ /* Avoid setting it lower than the initial starting height. */
+ tmp = tmp > pane->initial_max_value ? tmp : pane->initial_max_value;
+ hud_pane_set_max_value(pane, tmp);
+ }
+
+ /*
+ * Mark this adjustment run so we could avoid repeating a full update
+ * again needlessly in case the pane has more than one graph.
+ */
+ pane->dyn_ceil_last_ran = gr->index;