Signed-off-by: Damien Lespiau <damien.lespiau@xxxxxxxxx> --- lib/igt_plot.c | 100 +++++++++++++++++++++++++++++++++++++++++++++------ lib/igt_plot.h | 9 ++++- lib/tests/igt_plot.c | 2 ++ 3 files changed, 100 insertions(+), 11 deletions(-) diff --git a/lib/igt_plot.c b/lib/igt_plot.c index 763c000..b3d4bc7 100644 --- a/lib/igt_plot.c +++ b/lib/igt_plot.c @@ -422,6 +422,7 @@ typedef struct { char *text; cairo_text_extents_t extents; igt_align_t halign, valign; + double rotation; } igt_label_t; typedef struct { @@ -430,9 +431,10 @@ typedef struct { double title_font_size; double tick_label_font_size; igt_box_t plot_area; - igt_label_t title; + igt_label_t title, x_title, y_title; igt_label_t *x_tick_labels; igt_label_t *y_tick_labels; + double y_tick_width, x_tick_height; } flush_t; static double plot_length(igt_plot_t *plot, double percent) @@ -476,15 +478,22 @@ igt_plot_draw_text(igt_plot_t *plot, double x, double y, igt_label_t *label) if (plot->debug) { cairo_set_source_rgb(plot->cr, 1.0, 0.0, 0.0); - cairo_move_to(plot->cr, x, y); - cairo_rectangle(plot->cr, x, y, + cairo_translate(plot->cr, x, y); + if (label->rotation) + cairo_rotate(plot->cr, label->rotation); + cairo_rectangle(plot->cr, 0, 0, label->extents.width, -label->extents.height); cairo_stroke(plot->cr); + cairo_identity_matrix(plot->cr); } cairo_set_source_rgb(plot->cr, 0.0, 0.0, 0.0); cairo_move_to(plot->cr, x, y); + if (label->rotation) + cairo_rotate(plot->cr, label->rotation); cairo_show_text(plot->cr, label->text); + if (label->rotation) + cairo_identity_matrix(plot->cr); } static void igt_plot_draw_background(igt_plot_t *plot, flush_t *flush) @@ -521,6 +530,30 @@ static void igt_plot_draw_title(igt_plot_t *plot, flush_t *flush) igt_plot_draw_text(plot, SNAP(x), SNAP(y), &flush->title); } +static void igt_plot_draw_axis_title(igt_plot_t *plot, igt_plot_axis_t *axis, + igt_label_t *label, flush_t *flush) +{ + igt_box_t *area = &flush->plot_area; + double x, y; + + if (!plot->title) + return; + + cairo_set_font_size(plot->cr, flush->title_font_size); + cairo_set_source_rgb(plot->cr, 0.0, 0.0, 0.0); + + if (axis->side == IGT_SIDE_BOTTOM) { + x = area->x1 + (area->x2 - area->x1 ) / 2.0; + y = area->y2 + flush->x_tick_height + flush->inner_padding; + igt_plot_draw_text(plot, SNAP(x), SNAP(y), label); + } else { + x = area->x1 - 2 * flush->tick_label_padding - + flush->y_tick_width; + y = area->y1 + (area->y2 - area->y1) / 2.0; + igt_plot_draw_text(plot, SNAP(x), SNAP(y), label); + } +} + static void igt_plot_draw_grid(igt_plot_t *plot, flush_t *flush) { unsigned int i, n_ticks; @@ -661,6 +694,9 @@ static void igt_plot_draw_axis(igt_plot_t *plot, flush_t *flush) igt_box_t *area = &flush->plot_area; const double tick_length = plot_length(plot, 0.01); + igt_plot_draw_axis_title(plot, &plot->x_axis, &flush->x_title, flush); + igt_plot_draw_axis_title(plot, &plot->y_axis, &flush->y_title, flush); + igt_plot_draw_grid(plot, flush); /* X-axis */ @@ -695,6 +731,33 @@ static void igt_plot_layout_title(igt_plot_t *plot, flush_t *flush) label->valign = IGT_ALIGN_BOTTOM; cairo_set_font_size(plot->cr, flush->title_font_size); cairo_text_extents(plot->cr, label->text, &label->extents); + + flush->plot_area.y1 += flush->title.extents.height + + flush->inner_padding; +} + +static void igt_plot_layout_axis_title(igt_plot_t *plot, igt_plot_axis_t *axis, + igt_label_t *label, flush_t *flush) +{ + if (!axis->title) + return; + + label->text = axis->title; + cairo_set_font_size(plot->cr, flush->title_font_size); + cairo_text_extents(plot->cr, label->text, &label->extents); + + if (axis->side == IGT_SIDE_BOTTOM) { + label->halign = IGT_ALIGN_CENTER; + label->valign = IGT_ALIGN_TOP; + flush->plot_area.y2 -= flush->x_title.extents.height + + flush->inner_padding; + } else { + label->halign = IGT_ALIGN_LEFT; + label->valign = IGT_ALIGN_CENTER; + label->rotation = -M_PI / 2; + flush->plot_area.x1 += flush->y_title.extents.height + + flush->inner_padding; + } } static void igt_plot_layout_tick_labels(igt_plot_t *plot, @@ -731,7 +794,6 @@ static void igt_plot_layout_tick_labels(igt_plot_t *plot, static void igt_plot_layout(igt_plot_t *plot, flush_t *flush) { const double outer_padding = 0.10; - double max_width, max_height; flush->inner_padding = plot_length(plot, 0.05); flush->tick_label_padding = plot_length(plot, 0.02); @@ -746,17 +808,19 @@ static void igt_plot_layout(igt_plot_t *plot, flush_t *flush) /* plot title */ igt_plot_layout_title(plot, flush); - flush->plot_area.y1 += flush->title.extents.height + - flush->inner_padding; + + /* axis titles */ + igt_plot_layout_axis_title(plot, &plot->x_axis, &flush->x_title, flush); + igt_plot_layout_axis_title(plot, &plot->y_axis, &flush->y_title, flush); /* measure tick labels and adjust the plot area */ cairo_set_font_size(plot->cr, flush->tick_label_font_size); igt_plot_layout_tick_labels(plot, &plot->x_axis, flush->x_tick_labels, - &max_height); - flush->plot_area.y2 -= max_height - flush->tick_label_padding; + &flush->x_tick_height); + flush->plot_area.y2 -= flush->x_tick_height - flush->tick_label_padding; igt_plot_layout_tick_labels(plot, &plot->y_axis, flush->y_tick_labels, - &max_width); - flush->plot_area.x1 += max_width + flush->tick_label_padding; + &flush->y_tick_width); + flush->plot_area.x1 += flush->y_tick_width + flush->tick_label_padding; } static void igt_plot_flush_init(igt_plot_t *plot, flush_t *flush) @@ -801,3 +865,19 @@ void igt_plot_write(igt_plot_t *plot, const char *filename) igt_plot_flush_fini(plot, &flush); } + +/** + * igt_plot_axis_set_title: + * @axis: An #igt_plot_axis_t instance + * @title: An UTF-8 string + * + * Set a title for the plot. + */ +void igt_plot_axis_set_title(igt_plot_axis_t *axis, const char *title) +{ + free(axis->title); + axis->title = NULL; + if (!title) + return; + axis->title = strndup(title, 64); +} diff --git a/lib/igt_plot.h b/lib/igt_plot.h index 49d5819..dce21e7 100644 --- a/lib/igt_plot.h +++ b/lib/igt_plot.h @@ -75,6 +75,7 @@ typedef struct { /*< private >*/ igt_orientation_t orientation; igt_side_t side; + char *title; unsigned int n_ticks; double min, max; /* range of the values on this axis */ } igt_plot_axis_t; @@ -91,6 +92,8 @@ typedef struct { /** * igt_plot_t: + * @x_axis: X axis + * @y_axis: Y axis * * Draw nice plots! */ @@ -106,9 +109,12 @@ typedef struct { unsigned int width, height; char *title; igt_trbl_t margin; - igt_plot_axis_t x_axis, y_axis; igt_plot_axis_t x_axis_top, y_axis_right; + /*< public >*/ + igt_plot_axis_t x_axis, y_axis; + + /*< private >*/ /* per draw command contexts */ igt_plot_ctx_t contexts[IGT_PLOT_MAX_PLOTS + 1]; unsigned int n_valid_contexts; @@ -135,5 +141,6 @@ void igt_plot_set_color(igt_plot_t *plot, void igt_plot_set_line_width(igt_plot_t *plot, double width); void igt_plot_draw(igt_plot_t *plot, igt_vector_t *x, igt_vector_t *y); void igt_plot_write(igt_plot_t *plot, const char *filename); +void igt_plot_axis_set_title(igt_plot_axis_t *axis, const char *title); #endif /* __IGT_PLOT_H__ */ diff --git a/lib/tests/igt_plot.c b/lib/tests/igt_plot.c index 81946f3..a178fbf 100644 --- a/lib/tests/igt_plot.c +++ b/lib/tests/igt_plot.c @@ -84,6 +84,8 @@ static void test_simple_plot(void) igt_plot_init(&plot, 800, 600); igt_plot_set_title(&plot, "f(x) = sin(2πx)"); + igt_plot_axis_set_title(&plot.x_axis, "x"); + igt_plot_axis_set_title(&plot.y_axis, "f(x)"); igt_plot_set_color(&plot, 0.0, 0.0, 1.0, 1.0); igt_plot_draw(&plot, x, y); igt_plot_write(&plot, "test_simple_plot.png"); -- 2.1.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx