diff mbox

[i-g-t,11/16] plot: Add a title to plots

Message ID 1436186144-19665-12-git-send-email-damien.lespiau@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lespiau, Damien July 6, 2015, 12:35 p.m. UTC
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 lib/igt_plot.c       | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_plot.h       |  2 ++
 lib/tests/igt_plot.c |  1 +
 3 files changed, 62 insertions(+)
diff mbox

Patch

diff --git a/lib/igt_plot.c b/lib/igt_plot.c
index afe4a1c..2ca005e 100644
--- a/lib/igt_plot.c
+++ b/lib/igt_plot.c
@@ -303,6 +303,8 @@  void igt_plot_fini(igt_plot_t *plot)
 {
 	unsigned int i;
 
+	free(plot->title);
+
 	for (i = 0; i < plot->n_valid_contexts; i++)
 		igt_plot_ctx_fini(&plot->contexts[i]);
 
@@ -314,6 +316,22 @@  void igt_plot_fini(igt_plot_t *plot)
 }
 
 /**
+ * igt_plot_set_title:
+ * @plot: An #igt_plot_t instance
+ * @title: An UTF-8 string
+ *
+ * Set a title for the plot.
+ */
+void igt_plot_set_title(igt_plot_t *plot, const char *title)
+{
+	free(plot->title);
+	plot->title = NULL;
+	if (!title)
+		return;
+	plot->title = strndup(title, 64);
+}
+
+/**
  * igt_plot_set_color:
  * @plot: An #igt_plot_t instance
  * @r: Red component in the [0, 1] range
@@ -407,9 +425,12 @@  typedef struct {
 } igt_label_t;
 
 typedef struct {
+	double inner_padding;		/* padding for most things */
 	double tick_label_padding;	/* padding between label and axis */
+	double title_font_size;
 	double tick_label_font_size;
 	igt_box_t plot_area;
+	igt_label_t title;
 	igt_label_t *x_tick_labels;
 	igt_label_t *y_tick_labels;
 } flush_t;
@@ -470,6 +491,22 @@  static void igt_plot_draw_background(igt_plot_t *plot, flush_t *flush)
 	cairo_fill(plot->cr);
 }
 
+static void igt_plot_draw_title(igt_plot_t *plot, 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);
+
+	x = area->x1 + (area->x2 - area->x1 ) / 2.0;
+	y = flush->plot_area.y1 - flush->inner_padding;
+	igt_plot_draw_text(plot, SNAP(x), SNAP(y), &flush->title);
+}
+
 static void igt_plot_draw_grid(igt_plot_t *plot, flush_t *flush)
 {
 	unsigned int i, n_ticks;
@@ -632,6 +669,20 @@  static void igt_plot_draw_axis(igt_plot_t *plot, flush_t *flush)
 
 }
 
+static void igt_plot_layout_title(igt_plot_t *plot, flush_t *flush)
+{
+	igt_label_t *label = &flush->title;
+
+	if (!plot->title)
+		return;
+
+	label->text = plot->title;
+	label->halign = IGT_ALIGN_CENTER;
+	label->valign = IGT_ALIGN_BOTTOM;
+	cairo_set_font_size(plot->cr, flush->title_font_size);
+	cairo_text_extents(plot->cr, label->text, &label->extents);
+}
+
 static void igt_plot_layout_tick_labels(igt_plot_t *plot,
 					igt_plot_axis_t *axis,
 					igt_label_t *labels,
@@ -668,7 +719,9 @@  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);
+	flush->title_font_size = round(0.025 * plot->width);
 	flush->tick_label_font_size = round(0.015 * plot->width);
 
 	/* outer padding */
@@ -677,6 +730,11 @@  static void igt_plot_layout(igt_plot_t *plot, flush_t *flush)
 	flush->plot_area.x2 = SNAP(plot->width * (1.0 - outer_padding));
 	flush->plot_area.y2 = SNAP(plot->height * (1.0 - outer_padding));
 
+	/* plot title */
+	igt_plot_layout_title(plot, flush);
+	flush->plot_area.y1 += flush->title.extents.height +
+			       flush->inner_padding;
+
 	/* 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,
@@ -720,6 +778,7 @@  void igt_plot_write(igt_plot_t *plot, const char *filename)
 	igt_plot_layout(plot, &flush);
 
 	igt_plot_draw_background(plot, &flush);
+	igt_plot_draw_title(plot, &flush);
 	igt_plot_draw_axis(plot, &flush);
 	for (i = 0; i < plot->n_valid_contexts; i++)
 		igt_plot_draw_one(plot, &plot->contexts[i], &flush);
diff --git a/lib/igt_plot.h b/lib/igt_plot.h
index c8b031f..cca498a 100644
--- a/lib/igt_plot.h
+++ b/lib/igt_plot.h
@@ -103,6 +103,7 @@  typedef struct {
 
 	/* plot-wide states */
 	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;
@@ -127,6 +128,7 @@  typedef enum {
 
 void igt_plot_init(igt_plot_t *plot, unsigned int width, unsigned int height);
 void igt_plot_fini(igt_plot_t *plot);
+void igt_plot_set_title(igt_plot_t *plot, const char *title);
 void igt_plot_set_color(igt_plot_t *plot,
 			double r, double g, double b, double a);
 void igt_plot_set_line_width(igt_plot_t *plot, double width);
diff --git a/lib/tests/igt_plot.c b/lib/tests/igt_plot.c
index 2f5ad27..81946f3 100644
--- a/lib/tests/igt_plot.c
+++ b/lib/tests/igt_plot.c
@@ -83,6 +83,7 @@  static void test_simple_plot(void)
 	y = igt_vector_map(x, f);
 
 	igt_plot_init(&plot, 800, 600);
+	igt_plot_set_title(&plot, "f(x) = sin(2?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");