free(im->gdes[i].rpnp);
}
free(im->gdes);
+
+ for (i = 0; i < DIM(text_prop);i++){
+ pango_font_description_free(im->text_prop[i].font_desc);
+ im->text_prop[i].font_desc = NULL;
+ }
+
if (im->font_options)
cairo_font_options_destroy(im->font_options);
status = cairo_status(im->cr);
cairo_destroy(im->cr);
}
+
+
if (im->rendered_image) {
free(im->rendered_image);
}
}
}
else {
- sprintf(graph_label_right,im->second_axis_format,sval);
+ sprintf(graph_label_right,im->second_axis_format,sval,"");
}
gfx_text ( im,
char *old_locale;
rrd_graph_init(&im);
/* a dummy surface so that we can measure text sizes for placements */
- old_locale = setlocale(LC_NUMERIC, "C");
+ old_locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
rrd_graph_options(argc, argv, &im);
if (rrd_test_error()) {
+ setlocale(LC_NUMERIC, old_locale); /* reenable locale */
rrd_info_free(im.grinfo);
im_free(&im);
return NULL;
}
if (optind >= argc) {
+ setlocale(LC_NUMERIC, old_locale); /* reenable locale */
rrd_info_free(im.grinfo);
im_free(&im);
rrd_set_error("missing filename");
}
if (strlen(argv[optind]) >= MAXPATH) {
+ setlocale(LC_NUMERIC, old_locale); /* reenable locale */
rrd_set_error("filename (including path) too long");
rrd_info_free(im.grinfo);
im_free(&im);
if (font){
strncpy(im->text_prop[prop].font, font, sizeof(text_prop[prop].font) - 1);
im->text_prop[prop].font[sizeof(text_prop[prop].font) - 1] = '\0';
+ /* if we already got one, drop it first */
+ pango_font_description_free(im->text_prop[prop].font_desc);
im->text_prop[prop].font_desc = pango_font_description_from_string( font );
};
if (size > 0){
for (i = 0; i < DIM(text_prop); i++) {
im->text_prop[i].size = -1;
+ im->text_prop[i].font_desc = NULL;
rrd_set_font_desc(im,i, deffont ? deffont : text_prop[i].font,text_prop[i].size);
}
pango_cairo_update_context(im->cr,context);
im->layout = pango_layout_new(context);
+ g_object_unref (context);
// im->layout = pango_cairo_create_layout(im->cr);
}
}
+
void time_clean(
char *result,
char *format)
{
int j, jj;
+/* Handling based on
+ - ANSI C99 Specifications http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
+ - Single UNIX Specification version 2 http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
+ - POSIX:2001/Single UNIX Specification version 3 http://www.opengroup.org/onlinepubs/009695399/functions/strftime.html
+ - POSIX:2008 Specifications http://www.opengroup.org/onlinepubs/9699919799/functions/strftime.html
+ Specifications tells
+ "If a conversion specifier is not one of the above, the behavior is undefined."
+
+ C99 tells
+ "A conversion specifier consists of a % character, possibly followed by an E or O modifier character (described below), followed by a character that determines the behavior of the conversion specifier.
+
+ POSIX:2001 tells
+ "A conversion specification consists of a '%' character, possibly followed by an E or O modifier, and a terminating conversion specifier character that determines the conversion specification's behavior."
+
+ POSIX:2008 introduce more complexe behavior that are not handled here.
+
+ According to this, this code will replace:
+ - % followed by @ by a %@
+ - % followed by by a %SPACE
+ - % followed by . by a %.
+ - % followed by % by a %
+ - % followed by t by a TAB
+ - % followed by E then anything by '-'
+ - % followed by O then anything by '-'
+ - % followed by anything else by at least one '-'. More characters may be added to better fit expected output length
+*/
+
jj = 0;
- for(j = 0; j < FMT_LEG_LEN - 1; j++) { /* we don't need to parse the last char */
+ for(j = 0; (j < FMT_LEG_LEN - 1) && (jj < FMT_LEG_LEN); j++) { /* we don't need to parse the last char */
if (format[j] == '%') {
- if ((format[j+1] == 'A') || (format[j+1] == 'a') ||
- (format[j+1] == 'B') || (format[j+1] == 'b') ||
- (format[j+1] == 'C') || (format[j+1] == 'c') ||
- (format[j+1] == 'D') || (format[j+1] == 'd') ||
- (format[j+1] == 'E') || (format[j+1] == 'e') ||
- (format[j+1] == 'F') ||
- (format[j+1] == 'G') || (format[j+1] == 'g') ||
- (format[j+1] == 'H') || (format[j+1] == 'h') ||
- (format[j+1] == 'I') ||
- (format[j+1] == 'j') ||
- (format[j+1] == 'k') ||
- (format[j+1] == 'l') ||
- (format[j+1] == 'M') || (format[j+1] == 'm') ||
- (format[j+1] == 'O') ||
- (format[j+1] == 'P') || (format[j+1] == 'p') ||
- (format[j+1] == 'R') || (format[j+1] == 'r') ||
- (format[j+1] == 'S') || (format[j+1] == 's') ||
- (format[j+1] == 'T') ||
- (format[j+1] == 'U') || (format[j+1] == 'u') ||
- (format[j+1] == 'V') || (format[j+1] == 'v') ||
- (format[j+1] == 'W') || (format[j+1] == 'w') ||
- (format[j+1] == 'X') || (format[j+1] == 'x') ||
- (format[j+1] == 'Y') || (format[j+1] == 'y') ||
- (format[j+1] == 'Z') || (format[j+1] == 'z') ||
- (format[j+1] == '+')) {
+ if ((format[j+1] == 'E') || (format[j+1] == 'O')) {
+ result[jj++] = '-';
+ j+=2; /* We skip next 2 following char */
+ } else if ((format[j+1] == 'C') || (format[j+1] == 'd') ||
+ (format[j+1] == 'g') || (format[j+1] == 'H') ||
+ (format[j+1] == 'I') || (format[j+1] == 'm') ||
+ (format[j+1] == 'M') || (format[j+1] == 'S') ||
+ (format[j+1] == 'U') || (format[j+1] == 'V') ||
+ (format[j+1] == 'W') || (format[j+1] == 'y')) {
result[jj++] = '-';
+ if (jj < FMT_LEG_LEN) {
+ result[jj++] = '-';
+ }
j++; /* We skip the following char */
- } else if (format[j+1] == '%') {
- result[jj++] = '%';
+ } else if (format[j+1] == 'j') {
+ result[jj++] = '-';
+ if (jj < FMT_LEG_LEN - 1) {
+ result[jj++] = '-';
+ result[jj++] = '-';
+ }
+ j++; /* We skip the following char */
+ } else if ((format[j+1] == 'G') || (format[j+1] == 'Y')) {
+ /* Assuming Year on 4 digit */
+ result[jj++] = '-';
+ if (jj < FMT_LEG_LEN - 2) {
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ }
+ j++; /* We skip the following char */
+ } else if (format[j+1] == 'R') {
+ result[jj++] = '-';
+ if (jj < FMT_LEG_LEN - 3) {
+ result[jj++] = '-';
+ result[jj++] = ':';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ }
+ j++; /* We skip the following char */
+ } else if (format[j+1] == 'T') {
+ result[jj++] = '-';
+ if (jj < FMT_LEG_LEN - 6) {
+ result[jj++] = '-';
+ result[jj++] = ':';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = ':';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ }
+ j++; /* We skip the following char */
+ } else if (format[j+1] == 'F') {
+ result[jj++] = '-';
+ if (jj < FMT_LEG_LEN - 8) {
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ }
+ j++; /* We skip the following char */
+ } else if (format[j+1] == 'D') {
+ result[jj++] = '-';
+ if (jj < FMT_LEG_LEN - 6) {
+ result[jj++] = '-';
+ result[jj++] = '/';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ result[jj++] = '/';
+ result[jj++] = '-';
+ result[jj++] = '-';
+ }
j++; /* We skip the following char */
} else if (format[j+1] == 'n') {
result[jj++] = '\r';
} else if (format[j+1] == 't') {
result[jj++] = '\t';
j++; /* We skip the following char */
+ } else if (format[j+1] == '%') {
+ result[jj++] = '%';
+ j++; /* We skip the following char */
+ } else if (format[j+1] == ' ') {
+ if (jj < FMT_LEG_LEN - 1) {
+ result[jj++] = '%';
+ result[jj++] = ' ';
+ }
+ j++; /* We skip the following char */
+ } else if (format[j+1] == '.') {
+ if (jj < FMT_LEG_LEN - 1) {
+ result[jj++] = '%';
+ result[jj++] = '.';
+ }
+ j++; /* We skip the following char */
+ } else if (format[j+1] == '@') {
+ if (jj < FMT_LEG_LEN - 1) {
+ result[jj++] = '%';
+ result[jj++] = '@';
+ }
+ j++; /* We skip the following char */
} else {
- result[jj++] = format[j];
+ result[jj++] = '-';
+ j++; /* We skip the following char */
}
} else {
- result[jj++] = format[j];
+ result[jj++] = format[j];
}
}
result[jj] = '\0'; /* We must force the end of the string */