From 189da15810deabd739d7c11c6e95fea55739fe60 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 1 Aug 2020 15:13:49 +0200 Subject: Initial import from archive --- src/model-display.c | 411 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 src/model-display.c (limited to 'src/model-display.c') diff --git a/src/model-display.c b/src/model-display.c new file mode 100644 index 0000000..4eeb83a --- /dev/null +++ b/src/model-display.c @@ -0,0 +1,411 @@ +/* + * model-display.c + * + * Display atomic models + * + * (c) 2006-2007 Thomas White + * + * synth2d - Two-Dimensional Crystallographic Fourier Synthesis + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#if HAVE_CAIRO +#include +#include +#endif + +#include "model.h" +#include "elements.h" +#include "symmetry.h" + +#if HAVE_CAIRO +static double model_oblique_x(double x, double y, int height, double gamma, int ny) { + + double offs; + + if ( gamma <= M_PI_2 ) { + offs = 0; + } else { + offs = (height*ny)*(-cos(gamma)); + } + + return 20.0 + offs + x + (y*cos(gamma)); + +} + +static double model_oblique_y(double x, double y, double gamma) { + + return 20.0 + y * sin(gamma); + +} + +static void model_display_draw_atoms(cairo_t *dctx, AtomicModel *model, int width, int height, double gamma, int nx, int ny, double h, int names, int heights) { + + cairo_surface_t *surface; + size_t i; + cairo_font_extents_t ext; + + surface = cairo_get_target(dctx); + + for ( i=0; in_atoms; i++ ) { + + AtomicModel *equivalents; + size_t j; + double x, y; + + if ( !model->atoms[i].active ) continue; + + equivalents = symmetry_generate_equivalent_atoms(model, i, MODEL_TARGET_DISPLAY); + + for ( j=0; jn_atoms; j++ ) { + + double R; + int xp, yp; + + x = width*(double)equivalents->atoms[j].x; + y = height*(double)equivalents->atoms[j].y; + R = sqrt(elements[equivalents->atoms[j].ref].z); + + for ( xp=0; xpatoms[i].occ < 1.0 ) { + cairo_set_source_rgb(dctx, 0.4, 0.4, 0.4); + } else if ( model->atoms[i].occ > 1.0 ) { + cairo_set_source_rgb(dctx, 0.4, 0, 0); + } else { + cairo_set_source_rgb(dctx, 0, 0, 0); + } + + cairo_arc(dctx, model_oblique_x(x+(width*xp), y+(height*yp), height, gamma, ny), + h-model_oblique_y(x+(width*xp), y+(height*yp), gamma), + R, 0, 2*M_PI); + cairo_fill(dctx); + } + } + + } + + model_free(equivalents); + + cairo_set_source_rgb(dctx, 0, 0, 1); + cairo_select_font_face(dctx, "Sans", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL); + cairo_font_extents(dctx, &ext); + + /* Only the unique atoms are labelled */ + x = 5 + width*(double)model->atoms[i].x + sqrt(elements[model->atoms[i].ref].z); + y = height*(double)model->atoms[i].y; + cairo_move_to(dctx, model_oblique_x(x,y,height,gamma, ny), h-model_oblique_y(x,y,gamma)); + if ( names ) { + cairo_show_text(dctx, elements[model->atoms[i].ref].element_name); + y -= ext.height; + } + x = 5 + width*(double)model->atoms[i].x + sqrt(elements[model->atoms[i].ref].z); + if ( heights ) { + + char tmp[32]; + + cairo_move_to(dctx, model_oblique_x(x,y,height,gamma, ny), h-model_oblique_y(x,y,gamma)); + cairo_show_text(dctx, "z="); + snprintf(tmp, 31, "%.3f", model->atoms[i].z); + cairo_show_text(dctx, tmp); + y -= ext.height; + + } + if ( model->atoms[i].occ != 1.0 ) { + + char tmp[32]; + + cairo_move_to(dctx, model_oblique_x(x,y,height,gamma, ny), h-model_oblique_y(x,y,gamma)); + cairo_show_text(dctx, "occ: "); + snprintf(tmp, 31, "%.2f", model->atoms[i].occ); + cairo_show_text(dctx, tmp); + y -= ext.height; + + } + + } + +} + +static void model_display_draw_diad(cairo_t *dctx, double x, double y) { + + cairo_matrix_t matrix; + + cairo_get_matrix(dctx, &matrix); + cairo_new_path(dctx); + cairo_set_source_rgb(dctx, 1, 0, 0); + cairo_translate(dctx, x, y); + cairo_scale(dctx, 1.0, 2.0); + cairo_arc(dctx, 0.0, 0.0, 3, 0, 2*M_PI); + cairo_fill(dctx); + cairo_set_matrix(dctx, &matrix); + +} + +static void model_display_draw_glide(cairo_t *dctx, double x1, double y1, double x2, double y2, int height, double gamma, int ny, double h) { + + double dash; + + cairo_new_path(dctx); + cairo_set_source_rgb(dctx, 1, 0, 0); + cairo_set_line_width(dctx, 1.0); + dash = 3.0; cairo_set_dash(dctx, &dash, 1, 0); + cairo_move_to(dctx, model_oblique_x(x1, y1, height, gamma, ny), h-model_oblique_y(x1, y1, gamma)); + cairo_line_to(dctx, model_oblique_x(x2, y2, height, gamma, ny), h-model_oblique_y(x2, y2, gamma)); + cairo_stroke(dctx); + dash = 0.0; cairo_set_dash(dctx, &dash, 0, 0); + +} + +static void model_display_draw_mirror(cairo_t *dctx, double x1, double y1, double x2, double y2, int height, double gamma, int ny, double h) { + + cairo_new_path(dctx); + cairo_set_source_rgb(dctx, 1, 0, 0); + cairo_set_line_width(dctx, 1.0); + cairo_move_to(dctx, model_oblique_x(x1, y1, height, gamma, ny), h-model_oblique_y(x1, y1, gamma)); + cairo_line_to(dctx, model_oblique_x(x2, y2, height, gamma, ny), h-model_oblique_y(x2, y2, gamma)); + cairo_stroke(dctx); + +} + +static void model_display_draw_symmetry(cairo_t *dctx, Symmetry sym, int width, int height, double gamma, int nx, int ny, double h) { + + cairo_surface_t *surface; + + surface = cairo_get_target(dctx); + + if ( sym & SYMMETRY_CENTRE ) { + int x, y; + for ( x=0; xsym, width, height, gamma, nx, ny, h); + + return dctx; + +} + +static void model_display_free_data(guchar *image_data, cairo_t *dctx) { + cairo_surface_finish(cairo_get_target(dctx)); + cairo_destroy(dctx); +} +#endif + +GdkPixbuf *model_display_render_pixbuf(AtomicModel *model, int width, int height, double gamma, int names, int heights, int nx, int ny) { + +#if HAVE_CAIRO + cairo_surface_t *surface; + cairo_t *dctx; + GdkPixbuf *pixbuf; + unsigned char *data; + + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, model_display_surface_width(nx*width, ny*height, gamma), + model_display_surface_height(nx*width, ny*height, gamma)); + + if ( cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS ) { + fprintf(stderr, "Couldn't create Cairo surface\n"); + cairo_surface_destroy(surface); + return NULL; + } + + dctx = cairo_create(surface); + model_display_do_cairo(dctx, model, width, height, gamma, nx, ny, cairo_image_surface_get_height(surface), names, heights); + + cairo_surface_flush(surface); + + data = cairo_image_surface_get_data(surface); + model_display_swizzle_data(data, cairo_image_surface_get_width(surface) * cairo_image_surface_get_height(surface)); + pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, 8, + cairo_image_surface_get_width(surface), + cairo_image_surface_get_height(surface), + cairo_image_surface_get_stride(surface), + (GdkPixbufDestroyNotify)model_display_free_data, dctx); + + return pixbuf; +#else + return NULL; +#endif + +} + +int model_display_render_pdf(AtomicModel *model, int width, int height, double gamma, const char *filename, int names, int heights, int nx, int ny) { + +#if HAVE_CAIRO + cairo_surface_t *surface; + cairo_t *dctx; + + surface = cairo_pdf_surface_create(filename, model_display_surface_width(nx*width, ny*height, gamma), + model_display_surface_height(nx*width, ny*height, gamma)); + + if ( cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS ) { + fprintf(stderr, "Couldn't create Cairo surface\n"); + cairo_surface_destroy(surface); + return -1; + } + + dctx = cairo_create(surface); + + model_display_do_cairo(dctx, model, width, height, gamma, nx, ny, model_display_surface_height(nx*width, ny*height, gamma), names, heights); + + cairo_surface_finish(surface); + cairo_destroy(dctx); +#endif + + return 0; + +} + -- cgit v1.2.3