*d = '\0';
w -= VERDANA_KERNING;
w += VERDANA_PADDING;
- return ceil(w);
+ return (int)ceil(w);
}
static inline size_t escape_xmlz(char *dst, const char *src, size_t len) {
break;
}
else {
- calculated_number v = strtold(value_buffer, NULL);
+ calculated_number v = str2l(value_buffer);
if(comparison == '<' && value < v) break;
else if(comparison == '(' && value <= v) break;
strncpyz(final, b, len);
}
+// value + units
+#define VALUE_STRING_SIZE 100
+
+// label
+#define LABEL_STRING_SIZE 200
+
+// colors
+#define COLOR_STRING_SIZE 100
+
void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int value_is_null, int precision) {
- char label_buffer[256 + 1], value_string[512 + 1], value_color_buffer[256 + 1];
- char label_escaped[256 + 1], value_escaped[512 + 1], label_color_escaped[256 + 1], value_color_escaped[256 + 1];
+ char label_buffer[LABEL_STRING_SIZE + 1]
+ , value_color_buffer[COLOR_STRING_SIZE + 1]
+ , value_string[VALUE_STRING_SIZE + 1]
+ , label_escaped[LABEL_STRING_SIZE + 1]
+ , value_escaped[VALUE_STRING_SIZE + 1]
+ , label_color_escaped[COLOR_STRING_SIZE + 1]
+ , value_color_escaped[COLOR_STRING_SIZE + 1];
+
int label_width, value_width, total_width;
- if(!label_color || !*label_color) label_color = "#555";
- if(!value_color || !*value_color) value_color = (value_is_null)?"#999":"#4c1";
+ if(unlikely(!label_color || !*label_color))
+ label_color = "#555";
+
+ if(unlikely(!value_color || !*value_color))
+ value_color = (value_is_null)?"#999":"#4c1";
units = fix_units(units);
- calc_colorz(value_color, value_color_buffer, 256, value, value_is_null);
+ calc_colorz(value_color, value_color_buffer, COLOR_STRING_SIZE, value, value_is_null);
char *separator = "";
- if(isalnum(*units)) separator = " ";
+ if(unlikely(isalnum(*units)))
+ separator = " ";
+
+ if(unlikely(!strcmp(units, "seconds"))) {
+ size_t s = (size_t)value;
+ size_t d = s / 86400;
+ s = s % 86400;
+
+ size_t h = s / 3600;
+ s = s % 3600;
+
+ size_t m = s / 60;
+ s = s % 60;
+
+ if(d)
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zu %s %02zu:%02zu:%02zu", d, (d == 1)?"day":"days", h, m, s);
+ else
+ snprintfz(value_string, VALUE_STRING_SIZE, "%02zu:%02zu:%02zu", h, m, s);
+ }
+
+ else if(unlikely(!strcmp(units, "minutes"))) {
+ size_t m = (size_t)value;
+ size_t d = m / (60 * 24);
+ m = m % (60 * 24);
+
+ size_t h = m / 60;
+ m = m % 60;
+
+ if(d)
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zud %02zuh %02zum", d, h, m);
+ else
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zuh %zum", h, m);
+ }
+
+ else if(unlikely(!strcmp(units, "hours"))) {
+ size_t h = (size_t)value;
+ size_t d = h / 24;
+ h = h % 24;
- if(value_is_null)
+ if(d)
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zud %zuh", d, h);
+ else
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zuh", h);
+ }
+
+ else if(unlikely(value_is_null))
strcpy(value_string, "-");
+
else if(precision < 0) {
- calculated_number abs = (value < (calculated_number)0)?-value:value;
- if(abs > (calculated_number)1000.0) snprintfz(value_string, 512, "%0.0Lf%s%s", (long double)value, separator, units);
- else if(abs > (calculated_number)100.0) snprintfz(value_string, 512, "%0.1Lf%s%s", (long double)value, separator, units);
- else if(abs > (calculated_number)1.0) snprintfz(value_string, 512, "%0.2Lf%s%s", (long double)value, separator, units);
- else if(abs > (calculated_number)0.1) snprintfz(value_string, 512, "%0.3Lf%s%s", (long double)value, separator, units);
- else snprintfz(value_string, 512, "%0.4Lf%s%s", (long double)value, separator, units);
+ int len, lstop = 0, trim_zeros = 1;
+
+ calculated_number abs = value;
+ if(isless(value, 0)) {
+ lstop = 1;
+ abs = -value;
+ }
+
+ if(isgreaterequal(abs, 1000)) { len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.0Lf", (long double)value); trim_zeros = 0; }
+ else if(isgreaterequal(abs, 100)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.1Lf", (long double)value);
+ else if(isgreaterequal(abs, 1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.2Lf", (long double)value);
+ else if(isgreaterequal(abs, 0.1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.3Lf", (long double)value);
+ else len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.4Lf", (long double)value);
+
+ if(unlikely(trim_zeros)) {
+ int l;
+ // remove trailing zeros from the decimal part
+ for(l = len - 1; l > lstop ; l--) {
+ if(likely(value_string[l] == '0')) {
+ value_string[l] = '\0';
+ len--;
+ }
+
+ else if(unlikely(value_string[l] == '.')) {
+ value_string[l] = '\0';
+ len--;
+ break;
+ }
+
+ else
+ break;
+ }
+ }
+
+ if(len >= 0)
+ snprintfz(&value_string[len], VALUE_STRING_SIZE - len, "%s%s", separator, units);
}
else {
if(precision > 50) precision = 50;
- snprintfz(value_string, 512, "%0.*Lf%s%s", precision, (long double)value, separator, units);
+ snprintfz(value_string, VALUE_STRING_SIZE, "%0.*Lf%s%s", precision, (long double)value, separator, units);
}
// we need to copy the label, since verdana11_width may write to it
- strncpyz(label_buffer, label, 256);
+ strncpyz(label_buffer, label, LABEL_STRING_SIZE);
label_width = verdana11_width(label_buffer) + (BADGE_HORIZONTAL_PADDING * 2);
value_width = verdana11_width(value_string) + (BADGE_HORIZONTAL_PADDING * 2);
total_width = label_width + value_width;
- escape_xmlz(label_escaped, label_buffer, 256);
- escape_xmlz(value_escaped, value_string, 256);
- escape_xmlz(label_color_escaped, color_map(label_color), 256);
- escape_xmlz(value_color_escaped, color_map(value_color_buffer), 256);
+ escape_xmlz(label_escaped, label_buffer, LABEL_STRING_SIZE);
+ escape_xmlz(value_escaped, value_string, VALUE_STRING_SIZE);
+ escape_xmlz(label_color_escaped, color_map(label_color), COLOR_STRING_SIZE);
+ escape_xmlz(value_color_escaped, color_map(value_color_buffer), COLOR_STRING_SIZE);
wb->contenttype = CT_IMAGE_SVG_XML;