-\f
-/* GUI rendering helpers. */
-
-struct xr_rendering
- {
- /* Table items. */
- struct render_page *page;
- struct xr_driver *xr;
- int title_height;
-
- /* Chart items. */
- struct chart_item *chart;
- };
-
-#define CHART_WIDTH 500
-#define CHART_HEIGHT 375
-
-struct xr_driver *
-xr_create_driver (cairo_t *cairo)
-{
- struct xr_driver *xr;
- struct string_map map;
-
- string_map_init (&map);
- xr = xr_allocate ("cairo", 0, &map);
- string_map_destroy (&map);
-
- xr->width = INT_MAX / 8;
- xr->length = INT_MAX / 8;
- if (!xr_set_cairo (xr, cairo))
- {
- output_driver_destroy (&xr->driver);
- return NULL;
- }
- return xr;
-}
-
-static struct xr_rendering *
-xr_rendering_create_text (struct xr_driver *xr, const char *text, cairo_t *cr)
-{
- struct table_item *table_item;
- struct xr_rendering *r;
-
- table_item = table_item_create (table_from_string (0, text), NULL);
- r = xr_rendering_create (xr, &table_item->output_item, cr);
- table_item_unref (table_item);
-
- return r;
-}
-
-struct xr_rendering *
-xr_rendering_create (struct xr_driver *xr, const struct output_item *item,
- cairo_t *cr)
-{
- struct xr_rendering *r = NULL;
-
- if (is_text_item (item))
- r = xr_rendering_create_text (xr, text_item_get_text (to_text_item (item)),
- cr);
- else if (is_message_item (item))
- {
- const struct message_item *message_item = to_message_item (item);
- const struct msg *msg = message_item_get_msg (message_item);
- char *s = msg_to_string (msg, NULL);
- r = xr_rendering_create_text (xr, s, cr);
- free (s);
- }
- else if (is_table_item (item))
- {
- r = xzalloc (sizeof *r);
- r->xr = xr;
- xr_set_cairo (xr, cr);
- r->page = xr_render_table_item (xr, to_table_item (item),
- &r->title_height);
- }
- else if (is_chart_item (item))
- {
- r = xzalloc (sizeof *r);
- r->chart = to_chart_item (output_item_ref (item));
- }
-
- return r;
-}
-
-void
-xr_rendering_measure (struct xr_rendering *r, int *w, int *h)
-{
- if (r->chart == NULL)
- {
- *w = render_page_get_size (r->page, H) / 1024;
- *h = (render_page_get_size (r->page, V) + r->title_height) / 1024;
- }
- else
- {
- *w = CHART_WIDTH;
- *h = CHART_HEIGHT;
- }
-}
-
-void
-xr_rendering_draw (struct xr_rendering *r, cairo_t *cr)
-{
- if (r->chart == NULL)
- {
- struct xr_driver *xr = r->xr;
-
- xr_set_cairo (xr, cr);
- xr->y = 0;
- render_page_draw (r->page);
- }
- else
- xr_draw_chart (r->chart, cr, 0, 0, CHART_WIDTH, CHART_HEIGHT);
-}
-
-void
-xr_draw_chart (const struct chart_item *chart_item, cairo_t *cr,
- double x, double y, double width, double height)
-{
- struct xrchart_geometry geom;
-
- cairo_save (cr);
- cairo_translate (cr, x, y + height);
- cairo_scale (cr, 1.0, -1.0);
- xrchart_geometry_init (cr, &geom, width, height);
- if (is_boxplot (chart_item))
- xrchart_draw_boxplot (chart_item, cr, &geom);
- else if (is_histogram_chart (chart_item))
- xrchart_draw_histogram (chart_item, cr, &geom);
- else if (is_np_plot_chart (chart_item))
- xrchart_draw_np_plot (chart_item, cr, &geom);
- else if (is_piechart (chart_item))
- xrchart_draw_piechart (chart_item, cr, &geom);
- else if (is_roc_chart (chart_item))
- xrchart_draw_roc (chart_item, cr, &geom);
- else if (is_scree (chart_item))
- xrchart_draw_scree (chart_item, cr, &geom);
- else
- NOT_REACHED ();
- xrchart_geometry_free (cr, &geom);
-
- cairo_restore (cr);
-}
-
-char *
-xr_draw_png_chart (const struct chart_item *item,
- const char *file_name_template, int number)
-{
- const int width = 640;
- const int length = 480;
-
- cairo_surface_t *surface;
- cairo_status_t status;
- const char *number_pos;
- char *file_name;
- cairo_t *cr;
-
- number_pos = strchr (file_name_template, '#');
- if (number_pos != NULL)
- file_name = xasprintf ("%.*s%d%s", (int) (number_pos - file_name_template),
- file_name_template, number, number_pos + 1);
- else
- file_name = xstrdup (file_name_template);
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, length);
- cr = cairo_create (surface);
-
- cairo_save (cr);
- cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
- cairo_rectangle (cr, 0, 0, width, length);
- cairo_fill (cr);
- cairo_restore (cr);
-
- cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
-
- xr_draw_chart (item, cr, 0.0, 0.0, width, length);
-
- status = cairo_surface_write_to_png (surface, file_name);
- if (status != CAIRO_STATUS_SUCCESS)
- error (0, 0, _("writing output file \"%s\": %s"),
- file_name, cairo_status_to_string (status));
-
- cairo_destroy (cr);
- cairo_surface_destroy (surface);
-
- return file_name;
-}