[Intel-gfx] [PATCH i-g-t 13/16] plot: Add axis titles

Damien Lespiau damien.lespiau at intel.com
Mon Jul 6 05:35:41 PDT 2015


Signed-off-by: Damien Lespiau <damien.lespiau at 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



More information about the Intel-gfx mailing list