From 7363aac90000245b866d85fea61f1928c755d813 Mon Sep 17 00:00:00 2001 From: taw27 Date: Sun, 28 Oct 2007 22:59:55 +0000 Subject: Make GtkValueGraph use Cairo git-svn-id: svn://cook.msm.cam.ac.uk:745/diff-tomo/dtr@182 bf6ca9ba-c028-0410-8290-897cf20841d1 --- config.h.in | 3 ++ configure | 18 +++++++ configure.ac | 11 ++++ src/gtk-valuegraph.c | 145 ++++++++++++++++++++++++++++----------------------- src/gtk-valuegraph.h | 3 +- src/refine.c | 10 ++-- 6 files changed, 122 insertions(+), 68 deletions(-) diff --git a/config.h.in b/config.h.in index b7637ff..e036cb1 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,8 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* Define to 1 if Cairo is available */ +#undef HAVE_CAIRO + /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H diff --git a/configure b/configure index 6cba618..0f0f677 100755 --- a/configure +++ b/configure @@ -6612,6 +6612,24 @@ echo "$as_me: error: rm -f conf.gtkgltest +{ echo "$as_me:$LINENO: checking Cairo version 1.2.0" >&5 +echo $ECHO_N "checking Cairo version 1.2.0... $ECHO_C" >&6; } +if $PKG_CONFIG --atleast-version 1.2.0 cairo ; then + CAIRO_VERSION=`$PKG_CONFIG --modversion cairo` + CAIRO_CFLAGS=`$PKG_CONFIG --cflags cairo` + CAIRO_LIBS=`$PKG_CONFIG --libs cairo` + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CAIRO 1 +_ACEOF + + { echo "$as_me:$LINENO: result: $CAIRO_VERSION" >&5 +echo "${ECHO_T}$CAIRO_VERSION" >&6; } +else + { echo "$as_me:$LINENO: result: not found. Some functions will be unavailable." >&5 +echo "${ECHO_T}not found. Some functions will be unavailable." >&6; } +fi + ac_config_files="$ac_config_files Makefile src/Makefile data/Makefile" cat >confcache <<\_ACEOF diff --git a/configure.ac b/configure.ac index 43849f0..1345495 100644 --- a/configure.ac +++ b/configure.ac @@ -39,5 +39,16 @@ AM_PATH_GTKGLEXT_1_0(1.0.0,[echo "$GTKGLEXT_LIBS"],AC_MSG_ERROR([ *** gtkglext is required to build dtr; please make sure you have the *** gtkglext development headers installed.])) +AC_MSG_CHECKING([Cairo version 1.2.0]) +if $PKG_CONFIG --atleast-version 1.2.0 cairo ; then + CAIRO_VERSION=`$PKG_CONFIG --modversion cairo` + CAIRO_CFLAGS=`$PKG_CONFIG --cflags cairo` + CAIRO_LIBS=`$PKG_CONFIG --libs cairo` + AC_DEFINE([HAVE_CAIRO], [1], [Define to 1 if Cairo is available]) + AC_MSG_RESULT($CAIRO_VERSION) +else + AC_MSG_RESULT([not found. Some functions will be unavailable.]) +fi + AC_OUTPUT(Makefile src/Makefile data/Makefile) 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; in; 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; in; 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; idata = 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); diff --git a/src/gtk-valuegraph.h b/src/gtk-valuegraph.h index b976ef7..845d34f 100644 --- a/src/gtk-valuegraph.h +++ b/src/gtk-valuegraph.h @@ -20,8 +20,9 @@ typedef struct { double *data; /* Data to be graphed */ unsigned int n; /* Number of data points */ - unsigned int xmax; /* Maximum value on x (index) axis */ + double xmax; /* Maximum value on x (index) axis */ double ymax; /* Maximum value on y (data) axis */ + double ymin; } GtkValueGraph; diff --git a/src/refine.c b/src/refine.c index a0b00e0..ede96cb 100644 --- a/src/refine.c +++ b/src/refine.c @@ -15,6 +15,8 @@ #include #include +#include +#include #include "displaywindow.h" #include "gtk-valuegraph.h" @@ -60,24 +62,26 @@ void refine_open(DisplayWindow *dw) { GtkWidget *graph; double old_tilt; int n; - double values[401]; + double *values; size_t idx; double tilt; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size(GTK_WINDOW(window), 640, 256); + gtk_window_set_title(GTK_WINDOW(window), "Refinement Graph"); graph = gtk_value_graph_new(); dw->ctx->cell_lattice = reflection_list_from_cell(dw->ctx->cell); n = 0; idx = 0; old_tilt = dw->ctx->images->images[n].tilt; + values = malloc(401*sizeof(double)); for ( tilt=old_tilt-0.2; tilt<=old_tilt+0.2; tilt+=0.001 ) { dw->ctx->images->images[n].tilt = tilt; values[idx++] = refine_image_deviation(&dw->ctx->images->images[n], dw->ctx->cell_lattice); - printf("%f %f\n", tilt, values[idx-1]); fflush(stdout); } dw->ctx->images->images[n].tilt = old_tilt; - gtk_value_graph_set_data(GTK_VALUE_GRAPH(graph), values, 41); + gtk_value_graph_set_data(GTK_VALUE_GRAPH(graph), values, idx); gtk_container_add(GTK_CONTAINER(window), graph); gtk_widget_show_all(window); -- cgit v1.2.3