X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fcairo-chart.c;h=78f5fabab7249ae2fdfff448be9891f120cb40f1;hb=319a66b560b7ca7144b88ced1982ba5e490e6e57;hp=070319a58ed07ae78c40c896bea092f2ff4b58e1;hpb=084a3ed2450295a9f1ebfd30b9a93f1e3dac7bf1;p=pspp diff --git a/src/output/cairo-chart.c b/src/output/cairo-chart.c index 070319a58e..78f5fabab7 100644 --- a/src/output/cairo-chart.c +++ b/src/output/cairo-chart.c @@ -46,13 +46,14 @@ void xrchart_geometry_init (cairo_t *cr, struct xrchart_geometry *geom, double width, double length) { - /* Set default chartetry. */ + /* Set default chart geometry. */ geom->axis[SCALE_ORDINATE].data_max = 0.900 * length; - geom->axis[SCALE_ABSCISSA].data_max = 0.800 * width; geom->axis[SCALE_ORDINATE].data_min = 0.120 * length; + geom->axis[SCALE_ABSCISSA].data_min = 0.150 * width; - geom->abscissa_top = 0.070 * length; - geom->ordinate_right = 0.120 * width; + geom->axis[SCALE_ABSCISSA].data_max = 0.800 * width; + geom->abscissa_bottom = 0.070 * length; + geom->ordinate_left = 0.050 * width; geom->title_bottom = 0.920 * length; geom->legend_left = 0.810 * width; geom->legend_right = width; @@ -150,8 +151,8 @@ xrchart_draw_marker (cairo_t *cr, double x, double y, } void -xrchart_label (cairo_t *cr, int horz_justify, int vert_justify, - double font_size, const char *string) +xrchart_label_rotate (cairo_t *cr, int horz_justify, int vert_justify, + double font_size, const char *string, double angle) { PangoFontDescription *desc; PangoLayout *layout; @@ -166,6 +167,7 @@ xrchart_label (cairo_t *cr, int horz_justify, int vert_justify, pango_font_description_set_absolute_size (desc, font_size * PANGO_SCALE); cairo_save (cr); + cairo_rotate (cr, angle); cairo_get_current_point (cr, &x, &y); cairo_translate (cr, x, y); cairo_move_to (cr, 0, 0); @@ -214,14 +216,51 @@ xrchart_label (cairo_t *cr, int horz_justify, int vert_justify, pango_font_description_free (desc); } +void +xrchart_label (cairo_t *cr, int horz_justify, int vert_justify, + double font_size, const char *string) +{ + xrchart_label_rotate (cr, horz_justify, vert_justify, font_size, string, 0); +} + + /* Draw a tick mark at position - If label is non zero, then print it at the tick mark + If label is non null, then print it at the tick mark */ +static void +draw_tick_internal (cairo_t *cr, const struct xrchart_geometry *geom, + enum tick_orientation orientation, + bool rotated, + double position, + const char *s); + void draw_tick (cairo_t *cr, const struct xrchart_geometry *geom, enum tick_orientation orientation, + bool rotated, double position, const char *label, ...) +{ + va_list ap; + char *s; + va_start (ap, label); + s = xvasprintf (label, ap); + + if (fabs (position) < DBL_EPSILON) + position = 0; + + draw_tick_internal (cr, geom, orientation, rotated, position, s); + free (s); + va_end (ap); +} + + +static void +draw_tick_internal (cairo_t *cr, const struct xrchart_geometry *geom, + enum tick_orientation orientation, + bool rotated, + double position, + const char *s) { const int tickSize = 10; double x, y; @@ -244,25 +283,23 @@ draw_tick (cairo_t *cr, const struct xrchart_geometry *geom, cairo_stroke (cr); - if (label != NULL) + if (s != NULL) { - va_list ap; - char *s; - cairo_move_to (cr, x, y); - va_start (ap, label); - s = xvasprintf (label, ap); if (orientation == SCALE_ABSCISSA) - xrchart_label (cr, 'c', 't', geom->font_size, s); + { + if ( rotated) + xrchart_label_rotate (cr, 'l', 'c', geom->font_size, s, -G_PI_4); + else + xrchart_label (cr, 'c', 't', geom->font_size, s); + } else if (orientation == SCALE_ORDINATE) { if (fabs (position) < DBL_EPSILON) cairo_rel_move_to (cr, 0, 10); xrchart_label (cr, 'r', 'c', geom->font_size, s); } - free (s); - va_end (ap); } } @@ -288,33 +325,34 @@ xrchart_write_title (cairo_t *cr, const struct xrchart_geometry *geom, } -/* Set the scale for the ordinate */ + static void xrchart_write_scale (cairo_t *cr, struct xrchart_geometry *geom, double smin, double smax, int ticks, enum tick_orientation orient) { - double y; + int s; const double tick_interval = chart_rounded_tick ((smax - smin) / (double) ticks); - geom->axis[orient].max = ceil (smax / tick_interval) * tick_interval; - geom->axis[orient].min = floor (smin / tick_interval) * tick_interval; + int upper = ceil (smax / tick_interval); + int lower = floor (smin / tick_interval); - geom->axis[orient].scale = (fabs (geom->axis[orient].data_max - geom->axis[orient].data_min) - / fabs (geom->axis[orient].max - geom->axis[orient].min)); + geom->axis[orient].max = tick_interval * upper; + geom->axis[orient].min = tick_interval * lower; - /* - geom->axis[orient].scale = (fabs (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min) + geom->axis[orient].scale = (fabs (geom->axis[orient].data_max - geom->axis[orient].data_min) / fabs (geom->axis[orient].max - geom->axis[orient].min)); - */ - - for (y = geom->axis[orient].min; y <= geom->axis[orient].max; y += tick_interval) - draw_tick (cr, geom, orient, - (y - geom->axis[orient].min) * geom->axis[orient].scale, "%g", y); + for (s = 0 ; s < upper - lower; ++s) + { + double pos = (s + lower) * tick_interval; + draw_tick (cr, geom, orient, false, + s * tick_interval * geom->axis[orient].scale, "%g", pos); + } } +/* Set the scale for the ordinate */ void xrchart_write_yscale (cairo_t *cr, struct xrchart_geometry *geom, double smin, double smax, int ticks) @@ -336,7 +374,7 @@ void xrchart_write_xlabel (cairo_t *cr, const struct xrchart_geometry *geom, const char *label) { - cairo_move_to (cr, geom->axis[SCALE_ABSCISSA].data_min, geom->abscissa_top); + cairo_move_to (cr, geom->axis[SCALE_ABSCISSA].data_min, geom->abscissa_bottom); xrchart_label (cr, 'l', 't', geom->font_size, label); } @@ -346,9 +384,9 @@ xrchart_write_ylabel (cairo_t *cr, const struct xrchart_geometry *geom, const char *label) { cairo_save (cr); - cairo_translate (cr, -geom->axis[SCALE_ORDINATE].data_min, -geom->ordinate_right); - cairo_move_to (cr, 0, 0); + cairo_translate (cr, geom->ordinate_left, geom->axis[SCALE_ORDINATE].data_min); cairo_rotate (cr, M_PI / 2.0); + xrchart_label (cr, 'l', 'x', geom->font_size, label); cairo_restore (cr); }