From patchwork Mon Jul 6 12:35:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lespiau, Damien" X-Patchwork-Id: 6723381 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 952849F731 for ; Mon, 6 Jul 2015 12:36:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 87BC320628 for ; Mon, 6 Jul 2015 12:36:03 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 8B488202F0 for ; Mon, 6 Jul 2015 12:36:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9CBC36E878; Mon, 6 Jul 2015 05:36:00 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 967126E87A for ; Mon, 6 Jul 2015 05:35:58 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 06 Jul 2015 05:35:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,414,1432623600"; d="scan'208";a="741421062" Received: from magarwal-mobl.amr.corp.intel.com (HELO strange.amr.corp.intel.com) ([10.254.77.111]) by fmsmga001.fm.intel.com with ESMTP; 06 Jul 2015 05:35:57 -0700 From: Damien Lespiau To: intel-gfx@lists.freedesktop.org Date: Mon, 6 Jul 2015 13:35:41 +0100 Message-Id: <1436186144-19665-14-git-send-email-damien.lespiau@intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1436186144-19665-1-git-send-email-damien.lespiau@intel.com> References: <1436186144-19665-1-git-send-email-damien.lespiau@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 13/16] plot: Add axis titles X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Damien Lespiau --- 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");