diff options
author | taw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1> | 2007-10-28 22:59:55 +0000 |
---|---|---|
committer | taw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1> | 2007-10-28 22:59:55 +0000 |
commit | 7363aac90000245b866d85fea61f1928c755d813 (patch) | |
tree | a512439aa949786a0de08d3fbfb72962e327028a /src/gtk-valuegraph.c | |
parent | 58a5004f61bb54162675a99804bf274a0ae212ec (diff) |
Make GtkValueGraph use Cairo
git-svn-id: svn://cook.msm.cam.ac.uk:745/diff-tomo/dtr@182 bf6ca9ba-c028-0410-8290-897cf20841d1
Diffstat (limited to 'src/gtk-valuegraph.c')
-rw-r--r-- | src/gtk-valuegraph.c | 145 |
1 files changed, 81 insertions, 64 deletions
diff --git a/src/gtk-valuegraph.c b/src/gtk-valuegraph.c index a847946..47c6060 100644 --- a/src/gtk-valuegraph.c +++ b/src/gtk-valuegraph.c @@ -62,47 +62,67 @@ static void gtk_value_graph_class_init(GtkValueGraphClass *class) { } - static gint gtk_value_graph_draw(GtkWidget *graph, GdkEventExpose *event, gpointer data) { GtkValueGraph *vg; - unsigned int bw_left, bw_right, bw_top, bw_bottom; + double bw_left, bw_right, bw_top, bw_bottom; PangoLayout *y0_layout; PangoLayout *y1_layout; PangoLayout *x0_layout; PangoLayout *x1_layout; PangoRectangle y0_extent, y1_extent, x0_extent, x1_extent; - unsigned int width, height; + double width, height; char tmp[32]; - unsigned int i; - + int i; + cairo_t *cr; + PangoFontDescription *desc; + double scale; + vg = GTK_VALUE_GRAPH(graph); + cr = gdk_cairo_create(graph->window); + /* Blank white background */ - gdk_draw_rectangle(graph->window, graph->style->white_gc, TRUE, 0, 0, graph->allocation.width, graph->allocation.height); + cairo_rectangle(cr, 0.0, 0.0, graph->allocation.width, graph->allocation.height); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_fill(cr); /* Create PangoLayouts for labels */ - y0_layout = gtk_widget_create_pango_layout(graph, "0"); - pango_layout_get_pixel_extents(y0_layout, NULL, &y0_extent); - + desc = pango_font_description_from_string("Sans, Normal, 10"); + if ( fabs(log(vg->ymax)/log(10)) < 3 ) { + snprintf(tmp, 31, "%.4f", vg->ymin); + } else { + snprintf(tmp, 31, "%1.1e", vg->ymin); + } + y0_layout = pango_cairo_create_layout(cr); + pango_layout_set_text(y0_layout, tmp, -1); + pango_layout_set_font_description(y0_layout, desc); + pango_layout_get_pixel_extents(y0_layout, NULL, &y0_extent); + if ( fabs(log(vg->ymax)/log(10)) < 3 ) { snprintf(tmp, 31, "%.4f", vg->ymax); } else { snprintf(tmp, 31, "%1.1e", vg->ymax); } - y1_layout = gtk_widget_create_pango_layout(graph, tmp); - pango_layout_get_pixel_extents(y1_layout, NULL, &y1_extent); + y1_layout = pango_cairo_create_layout(cr); + pango_layout_set_text(y1_layout, tmp, -1); + pango_layout_set_font_description(y1_layout, desc); + pango_layout_get_pixel_extents(y1_layout, NULL, &y1_extent); + + x0_layout = pango_cairo_create_layout(cr); + pango_layout_set_text(x0_layout, "0", -1); + pango_layout_set_font_description(x0_layout, desc); + pango_layout_get_pixel_extents(x0_layout, NULL, &x0_extent); - x0_layout = gtk_widget_create_pango_layout(graph, "0"); - pango_layout_get_pixel_extents(x0_layout, NULL, &x0_extent); - if ( vg->xmax < 1000 ) { - snprintf(tmp, 31, "%i", vg->xmax); + snprintf(tmp, 31, "%.0f", vg->xmax); } else { snprintf(tmp, 31, "%1.1e", (double)vg->xmax); } - x1_layout = gtk_widget_create_pango_layout(graph, tmp); - pango_layout_get_pixel_extents(x1_layout, NULL, &x1_extent); + x1_layout = pango_cairo_create_layout(cr); + pango_layout_set_text(x1_layout, tmp, -1); + pango_layout_set_font_description(x1_layout, desc); + pango_layout_get_pixel_extents(x1_layout, NULL, &x1_extent); /* Determine border widths */ bw_left = 1+((y1_extent.width > y0_extent.width) ? y1_extent.width : y0_extent.width); @@ -113,29 +133,40 @@ static gint gtk_value_graph_draw(GtkWidget *graph, GdkEventExpose *event, gpoint height = graph->allocation.height; /* Draw axis lines */ - gdk_draw_line(graph->window, graph->style->black_gc, bw_left, height-1-bw_bottom, bw_left, bw_top); - gdk_draw_line(graph->window, graph->style->black_gc, bw_left, height-1-bw_bottom, width-1-bw_right, height-1-bw_bottom); + cairo_new_path(cr); + cairo_move_to(cr, bw_left+0.5, height-1-bw_bottom+0.5); + cairo_line_to(cr, bw_left+0.5, bw_top+0.5); + cairo_move_to(cr, bw_left+0.5, height-1-bw_bottom+0.5); + cairo_line_to(cr, width-1-bw_right+0.5, height-1-bw_bottom+0.5); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + cairo_set_line_width(cr, 1.0); + cairo_stroke(cr); /* Label axes */ - gdk_draw_layout(graph->window, graph->style->black_gc, 1+bw_left-x0_extent.width/2, height-1-bw_bottom, x0_layout); - gdk_draw_layout(graph->window, graph->style->black_gc, width-bw_right-x1_extent.width/2, height-1-bw_bottom, x1_layout); - gdk_draw_layout(graph->window, graph->style->black_gc, bw_left-y0_extent.width-1, height-1-bw_bottom-y0_extent.height/2, y0_layout); - gdk_draw_layout(graph->window, graph->style->black_gc, bw_left-y1_extent.width-1, 1, y1_layout); + cairo_new_path(cr); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + cairo_move_to(cr, 1+bw_left-x0_extent.width/2, height-1-bw_bottom); + pango_cairo_layout_path(cr, x0_layout); + cairo_move_to(cr, width-bw_right-x1_extent.width/2, height-1-bw_bottom); + pango_cairo_layout_path(cr, x1_layout); + cairo_move_to(cr, bw_left-y0_extent.width-1, height-1-bw_bottom-y0_extent.height/2); + pango_cairo_layout_path(cr, y0_layout); + cairo_move_to(cr, bw_left-y1_extent.width-1, 1); + pango_cairo_layout_path(cr, y1_layout); + cairo_fill(cr); /* Plot data */ - for ( i=0; i<vg->n; i++ ) { - - unsigned int x, y; - double xd, yd; - - xd = (((double)width-bw_left-bw_right)/(double)vg->xmax)*(double)(i+1); /* Graph axes go from 1 */ - x = bw_left + xd; - yd = (((double)height-bw_top-bw_bottom)/(double)vg->ymax)*(double)vg->data[i]; - y = height-bw_bottom - yd; - - gdk_draw_point(graph->window, graph->style->black_gc, x, y); + cairo_new_path(cr); + scale = (height-bw_top-bw_bottom)/(vg->ymax-vg->ymin); + cairo_move_to(cr, bw_left, height-bw_bottom-1-scale*(vg->data[0]-vg->ymin)); + for ( i=1; i<vg->n; i++ ) { + cairo_line_to(cr, bw_left+((double)i/vg->xmax)*(width-bw_left-bw_right), height-bw_bottom-1-scale*(vg->data[i]-vg->ymin)); + } + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); + cairo_stroke(cr); return 0; @@ -186,45 +217,31 @@ static double gtk_value_graph_peak(double *data, unsigned int n) { } -/* Calculate the best range for a axis with maximum value n */ -static double gtk_value_graph_axis_max(double n) { +static double gtk_value_graph_min(double *data, unsigned int n) { - double mantissa, exponent, test; -return n; - if ( n == 0 ) return 1; - - /* Convert to standard form */ - exponent = rint(log(n)/log(10)); - mantissa = n / pow(10, exponent); - - /* Check if the value can be exactly represented */ - test = mantissa * 10; - test = rint(test); - test /= 10; - if ( fabs(test - mantissa) > 0.001 ) { - - /* Round the mantissa upwards */ - mantissa += 0.1; - mantissa *= 10; - mantissa = rint(mantissa); - mantissa /= 10; - - } /* Else don't touch it */ + unsigned int i; + double min; - return mantissa*pow(10, exponent); + if ( n == 0 ) return 0; + min = +HUGE_VAL; + for ( i=0; i<n; i++ ) { + if ( data[i] < min ) min = data[i]; + } + + return min; + } void gtk_value_graph_set_data(GtkValueGraph *vg, double *data, unsigned int n) { - double dmax; - - /* Recalculate axes */ - dmax = gtk_value_graph_peak(data, n); vg->data = data; vg->n = n; - vg->xmax = gtk_value_graph_axis_max(n); - vg->ymax = gtk_value_graph_axis_max(dmax); + + /* Recalculate axes */ + vg->xmax = n; + vg->ymax = gtk_value_graph_peak(data, n); + vg->ymin = gtk_value_graph_min(data, n); //printf("n=%i, dmax=%f => xmax=%i, ymax=%f\n", n, dmax, vg->xmax, vg->ymax); |