+
+ xr->fonts[XR_FONT_FIXED].desc = parse_font (d, o, "fixed-font", "monospace",
+ font_points);
+ xr->fonts[XR_FONT_PROPORTIONAL].desc = parse_font (d, o, "prop-font",
+ "serif", font_points);
+ xr->fonts[XR_FONT_EMPHASIS].desc = parse_font (d, o, "emph-font",
+ "serif italic", font_points);
+
+ xr->line_gutter = parse_dimension (opt (d, o, "gutter", "3pt"));
+ xr->line_space = XR_POINT;
+ xr->line_width = XR_POINT / 2;
+ xr->page_number = 0;
+
+ parse_color (d, o, "background-color", "#FFFFFFFFFFFF", &xr->bg);
+ parse_color (d, o, "foreground-color", "#000000000000", &xr->fg);
+
+ parse_paper_size (opt (d, o, "paper-size", ""), &paper_width, &paper_length);
+ xr->left_margin = parse_dimension (opt (d, o, "left-margin", ".5in"));
+ xr->right_margin = parse_dimension (opt (d, o, "right-margin", ".5in"));
+ xr->top_margin = parse_dimension (opt (d, o, "top-margin", ".5in"));
+ xr->bottom_margin = parse_dimension (opt (d, o, "bottom-margin", ".5in"));
+
+ xr->width = paper_width - xr->left_margin - xr->right_margin;
+ xr->length = paper_length - xr->top_margin - xr->bottom_margin;
+}
+
+static struct xr_driver *
+xr_allocate (const char *name, int device_type, struct string_map *o)
+{
+ struct xr_driver *xr = xzalloc (sizeof *xr);
+ struct output_driver *d = &xr->driver;
+
+ output_driver_init (d, &cairo_driver_class, name, device_type);
+
+ apply_options (xr, o);
+
+ return xr;
+}
+
+static bool
+xr_set_cairo (struct xr_driver *xr, cairo_t *cairo)
+{
+ int i;
+
+ xr->cairo = cairo;
+
+ cairo_set_line_width (xr->cairo, xr_to_pt (xr->line_width));
+
+ xr->char_width = 0;
+ xr->char_height = 0;
+ for (i = 0; i < XR_N_FONTS; i++)
+ {
+ struct xr_font *font = &xr->fonts[i];
+ int char_width, char_height;
+
+ font->layout = pango_cairo_create_layout (cairo);
+ pango_layout_set_font_description (font->layout, font->desc);
+
+ pango_layout_set_text (font->layout, "0", 1);
+ pango_layout_get_size (font->layout, &char_width, &char_height);
+ xr->char_width = MAX (xr->char_width, char_width);
+ xr->char_height = MAX (xr->char_height, char_height);
+ }
+
+ if (xr->params == NULL)
+ {
+ int single_width, double_width;
+
+ xr->params = xmalloc (sizeof *xr->params);
+ xr->params->draw_line = xr_draw_line;
+ xr->params->measure_cell_width = xr_measure_cell_width;
+ xr->params->measure_cell_height = xr_measure_cell_height;
+ xr->params->draw_cell = xr_draw_cell;
+ xr->params->aux = xr;
+ xr->params->size[H] = xr->width;
+ xr->params->size[V] = xr->length;
+ xr->params->font_size[H] = xr->char_width;
+ xr->params->font_size[V] = xr->char_height;
+
+ single_width = 2 * xr->line_gutter + xr->line_width;
+ double_width = 2 * xr->line_gutter + xr->line_space + 2 * xr->line_width;
+ for (i = 0; i < TABLE_N_AXES; i++)
+ {
+ xr->params->line_widths[i][RENDER_LINE_NONE] = 0;
+ xr->params->line_widths[i][RENDER_LINE_SINGLE] = single_width;
+ xr->params->line_widths[i][RENDER_LINE_DOUBLE] = double_width;
+ }
+ }
+
+ cairo_set_source_rgb (xr->cairo, xr->fg.red, xr->fg.green, xr->fg.blue);
+
+ return true;
+}
+
+static struct output_driver *
+xr_create (const char *file_name, enum settings_output_devices device_type,
+ struct string_map *o, enum xr_output_type file_type)
+{
+ enum { MIN_WIDTH = 3, MIN_LENGTH = 3 };
+ struct xr_driver *xr;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ double width_pt, length_pt;
+
+ xr = xr_allocate (file_name, device_type, o);
+
+ width_pt = (xr->width + xr->left_margin + xr->right_margin) / 1000.0;
+ length_pt = (xr->length + xr->top_margin + xr->bottom_margin) / 1000.0;
+ if (file_type == XR_PDF)
+ surface = cairo_pdf_surface_create (file_name, width_pt, length_pt);
+ else if (file_type == XR_PS)
+ surface = cairo_ps_surface_create (file_name, width_pt, length_pt);
+ else if (file_type == XR_SVG)
+ surface = cairo_svg_surface_create (file_name, width_pt, length_pt);