Signed-off-by: Damien Lespiau <damien.lesp...@intel.com>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to