X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Foutput%2Fcairo.c;h=e29e6583c5f63a74fa9bc6b75d70125d09073098;hb=14be690de6bd259d26e710ad5363e106afde1e93;hp=cb901258d3acaaf8f760d371f7fc6010a31de98c;hpb=d036c4b79922f2339e7db9d0aef7ecad5e93bd91;p=pspp diff --git a/src/output/cairo.c b/src/output/cairo.c index cb901258d3..e29e6583c5 100644 --- a/src/output/cairo.c +++ b/src/output/cairo.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. + Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -64,8 +65,8 @@ #define H TABLE_HORZ #define V TABLE_VERT -/* Measurements as we present to the rest of PSPP. */ -#define XR_POINT 1000 +/* The unit used for internal measurements is inch/(72 * XR_POINT). */ +#define XR_POINT PANGO_SCALE /* Conversions to and from points. */ static double @@ -110,13 +111,6 @@ struct xr_render_fsm void (*destroy) (struct xr_render_fsm *); }; -struct xr_color -{ - double red; - double green; - double blue; -}; - /* Cairo output driver. */ struct xr_driver { @@ -128,10 +122,10 @@ struct xr_driver int width; /* Page width minus margins. */ int length; /* Page length minus margins and header. */ - int left_margin; /* Left margin in XR units. */ - int right_margin; /* Right margin in XR units. */ - int top_margin; /* Top margin in XR units. */ - int bottom_margin; /* Bottom margin in XR units. */ + int left_margin; /* Left margin in inch/(72 * XR_POINT). */ + int right_margin; /* Right margin in inch/(72 * XR_POINT). */ + int top_margin; /* Top margin in inch/(72 * XR_POINT). */ + int bottom_margin; /* Bottom margin in inch/(72 * XR_POINT). */ int line_gutter; /* Space around lines. */ int line_space; /* Space between lines. */ @@ -191,7 +185,7 @@ opt (struct output_driver *d, struct string_map *options, const char *key, Future implementations might allow things like "yellow" and "sky-blue-ultra-brown" */ -static void +void parse_color (struct output_driver *d, struct string_map *options, const char *key, const char *default_value, struct xr_color *color) @@ -220,7 +214,7 @@ parse_color (struct output_driver *d, struct string_map *options, static PangoFontDescription * parse_font (struct output_driver *d, struct string_map *options, const char *key, const char *default_value, - int default_points) + int default_size) { PangoFontDescription *desc; char *string; @@ -240,10 +234,10 @@ parse_font (struct output_driver *d, struct string_map *options, free (string); /* If the font description didn't include an explicit font size, then set it - to DEFAULT_POINTS. */ + to DEFAULT_SIZE, which is in inch/72000 units. */ if (!(pango_font_description_get_set_fields (desc) & PANGO_FONT_MASK_SIZE)) pango_font_description_set_size (desc, - default_points / 1000.0 * PANGO_SCALE); + (default_size / 1000.0) * PANGO_SCALE); return desc; } @@ -254,9 +248,16 @@ apply_options (struct xr_driver *xr, struct string_map *o) { struct output_driver *d = &xr->driver; - int paper_width, paper_length, i; + /* In inch/72000 units used by parse_paper_size() and parse_dimension(). */ + int left_margin, right_margin; + int top_margin, bottom_margin; + int paper_width, paper_length; + int font_size; - int font_points = parse_int (opt (d, o, "font-size", "10000"), 1000, 1000000); + /* Scale factor from inch/72000 to inch/(72 * XR_POINT). */ + const double scale = XR_POINT / 1000.; + + int i; for (i = 0; i < XR_N_FONTS; i++) { @@ -266,14 +267,15 @@ apply_options (struct xr_driver *xr, struct string_map *o) pango_font_description_free (font->desc); } + font_size = parse_int (opt (d, o, "font-size", "10000"), 1000, 1000000); xr->fonts[XR_FONT_FIXED].desc = parse_font (d, o, "fixed-font", "monospace", - font_points); + font_size); xr->fonts[XR_FONT_PROPORTIONAL].desc = parse_font (d, o, "prop-font", - "serif", font_points); + "serif", font_size); xr->fonts[XR_FONT_EMPHASIS].desc = parse_font (d, o, "emph-font", - "serif italic", font_points); + "serif italic", font_size); - xr->line_gutter = parse_dimension (opt (d, o, "gutter", "3pt")); + xr->line_gutter = parse_dimension (opt (d, o, "gutter", "3pt")) * scale; xr->line_space = XR_POINT; xr->line_width = XR_POINT / 2; xr->page_number = 0; @@ -281,14 +283,20 @@ apply_options (struct xr_driver *xr, struct string_map *o) parse_color (d, o, "background-color", "#FFFFFFFFFFFF", &xr->bg); parse_color (d, o, "foreground-color", "#000000000000", &xr->fg); + /* Get dimensions. */ 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; + left_margin = parse_dimension (opt (d, o, "left-margin", ".5in")); + right_margin = parse_dimension (opt (d, o, "right-margin", ".5in")); + top_margin = parse_dimension (opt (d, o, "top-margin", ".5in")); + bottom_margin = parse_dimension (opt (d, o, "bottom-margin", ".5in")); + + /* Convert to inch/(XR_POINT * 72). */ + xr->left_margin = left_margin * scale; + xr->right_margin = right_margin * scale; + xr->top_margin = top_margin * scale; + xr->bottom_margin = bottom_margin * scale; + xr->width = (paper_width - left_margin - right_margin) * scale; + xr->length = (paper_length - top_margin - bottom_margin) * scale; } static struct xr_driver * @@ -304,6 +312,22 @@ xr_allocate (const char *name, int device_type, struct string_map *o) return xr; } +static int +pango_to_xr (int pango) +{ + return (XR_POINT != PANGO_SCALE + ? ceil (pango * (1. * XR_POINT / PANGO_SCALE)) + : pango); +} + +static int +xr_to_pango (int xr) +{ + return (XR_POINT != PANGO_SCALE + ? ceil (xr * (1. / XR_POINT * PANGO_SCALE)) + : xr); +} + static bool xr_set_cairo (struct xr_driver *xr, cairo_t *cairo) { @@ -325,8 +349,8 @@ xr_set_cairo (struct xr_driver *xr, cairo_t *cairo) 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); + xr->char_width = MAX (xr->char_width, pango_to_xr (char_width)); + xr->char_height = MAX (xr->char_height, pango_to_xr (char_height)); } if (xr->params == NULL) @@ -371,8 +395,8 @@ xr_create (const char *file_name, enum settings_output_devices device_type, 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; + width_pt = xr_to_pt (xr->width + xr->left_margin + xr->right_margin); + length_pt = xr_to_pt (xr->length + xr->top_margin + xr->bottom_margin); if (file_type == XR_PDF) surface = cairo_pdf_surface_create (file_name, width_pt, length_pt); else if (file_type == XR_PS) @@ -622,7 +646,7 @@ xr_driver_run_fsm (struct xr_driver *xr) static void xr_layout_cell (struct xr_driver *, const struct table_cell *, int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2], - PangoWrapMode, int *width, int *height); + int *width, int *height); static void dump_line (struct xr_driver *xr, int x0, int y0, int x1, int y1) @@ -798,10 +822,10 @@ xr_measure_cell_width (void *xr_, const struct table_cell *cell, bb[V][0] = 0; bb[V][1] = INT_MAX; clip[H][0] = clip[H][1] = clip[V][0] = clip[V][1] = 0; - xr_layout_cell (xr, cell, bb, clip, PANGO_WRAP_WORD, max_width, &h); + xr_layout_cell (xr, cell, bb, clip, max_width, &h); bb[H][1] = 1; - xr_layout_cell (xr, cell, bb, clip, PANGO_WRAP_WORD, min_width, &h); + xr_layout_cell (xr, cell, bb, clip, min_width, &h); } static int @@ -817,7 +841,7 @@ xr_measure_cell_height (void *xr_, const struct table_cell *cell, int width) bb[V][0] = 0; bb[V][1] = INT_MAX; clip[H][0] = clip[H][1] = clip[V][0] = clip[V][1] = 0; - xr_layout_cell (xr, cell, bb, clip, PANGO_WRAP_WORD, &w, &h); + xr_layout_cell (xr, cell, bb, clip, &w, &h); return h; } @@ -828,15 +852,16 @@ xr_draw_cell (void *xr_, const struct table_cell *cell, struct xr_driver *xr = xr_; int w, h; - xr_layout_cell (xr, cell, bb, clip, PANGO_WRAP_WORD, &w, &h); + xr_layout_cell (xr, cell, bb, clip, &w, &h); } static void xr_layout_cell (struct xr_driver *xr, const struct table_cell *cell, int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2], - PangoWrapMode wrap, int *width, int *height) + int *width, int *height) { struct xr_font *font; + int w, h; font = (cell->options & TAB_FIX ? &xr->fonts[XR_FONT_FIXED] : cell->options & TAB_EMPH ? &xr->fonts[XR_FONT_EMPHASIS] @@ -849,9 +874,10 @@ xr_layout_cell (struct xr_driver *xr, const struct table_cell *cell, ((cell->options & TAB_ALIGNMENT) == TAB_RIGHT ? PANGO_ALIGN_RIGHT : (cell->options & TAB_ALIGNMENT) == TAB_LEFT ? PANGO_ALIGN_LEFT : PANGO_ALIGN_CENTER)); - pango_layout_set_width (font->layout, - bb[H][1] == INT_MAX ? -1 : bb[H][1] - bb[H][0]); - pango_layout_set_wrap (font->layout, wrap); + pango_layout_set_width ( + font->layout, + bb[H][1] == INT_MAX ? -1 : xr_to_pango (bb[H][1] - bb[H][0])); + pango_layout_set_wrap (font->layout, PANGO_WRAP_WORD); if (clip[H][0] != clip[H][1]) { @@ -875,16 +901,9 @@ xr_layout_cell (struct xr_driver *xr, const struct table_cell *cell, cairo_restore (xr->cairo); } - if (width != NULL || height != NULL) - { - int w, h; - - pango_layout_get_size (font->layout, &w, &h); - if (width != NULL) - *width = w; - if (height != NULL) - *height = h; - } + pango_layout_get_size (font->layout, &w, &h); + *width = pango_to_xr (w); + *height = pango_to_xr (h); } static void @@ -1096,7 +1115,10 @@ xr_draw_chart (const struct chart_item *chart_item, cairo_t *cr, char * xr_draw_png_chart (const struct chart_item *item, - const char *file_name_template, int number) + const char *file_name_template, int number, + const struct xr_color *fg, + const struct xr_color *bg + ) { const int width = 640; const int length = 480; @@ -1117,7 +1139,10 @@ xr_draw_png_chart (const struct chart_item *item, surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, length); cr = cairo_create (surface); - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_set_source_rgb (cr, bg->red, bg->green, bg->blue); + cairo_paint (cr); + + cairo_set_source_rgb (cr, fg->red, fg->green, fg->blue); xr_draw_chart (item, cr, 0.0, 0.0, width, length);