aboutsummaryrefslogtreecommitdiff
path: root/src/gtk-valuegraph.c
diff options
context:
space:
mode:
authortaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-10-28 22:59:55 +0000
committertaw27 <taw27@bf6ca9ba-c028-0410-8290-897cf20841d1>2007-10-28 22:59:55 +0000
commit7363aac90000245b866d85fea61f1928c755d813 (patch)
treea512439aa949786a0de08d3fbfb72962e327028a /src/gtk-valuegraph.c
parent58a5004f61bb54162675a99804bf274a0ae212ec (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.c145
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);