aboutsummaryrefslogtreecommitdiff
path: root/src/render_hkl.c
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2011-03-25 18:40:56 +0100
committerThomas White <taw@physics.org>2012-02-22 15:27:21 +0100
commit0de53f22863af2bb3c8db3d1cf5e015f0a9b9f87 (patch)
treefa8c690542f8de0932183c89c43d6aba8f096f8a /src/render_hkl.c
parentdad9cc7fe622e2b55f5294892d9c95a0c580b3be (diff)
render_hkl: Multiple improvements
Diffstat (limited to 'src/render_hkl.c')
-rw-r--r--src/render_hkl.c125
1 files changed, 108 insertions, 17 deletions
diff --git a/src/render_hkl.c b/src/render_hkl.c
index 44ec23fe..8ac73a72 100644
--- a/src/render_hkl.c
+++ b/src/render_hkl.c
@@ -143,7 +143,7 @@ static void draw_circles(signed int xh, signed int xk, signed int xl,
if ( dctx != NULL ) {
- float r, g, b;
+ double r, g, b;
cairo_arc(dctx, ((double)cx)+u*scale,
((double)cy)+v*scale,
@@ -238,7 +238,7 @@ static void render_za(UnitCell *cell, RefList *list,
double boost, const char *sym, int wght, int colscale,
signed int xh, signed int xk, signed int xl,
signed int yh, signed int yk, signed int yl,
- const char *outfile)
+ const char *outfile, double scale_top)
{
cairo_surface_t *surface;
cairo_t *dctx;
@@ -259,6 +259,7 @@ static void render_za(UnitCell *cell, RefList *list,
cairo_text_extents_t size;
double cx, cy;
const double border = 200.0;
+ int png;
/* Vector product to determine the zone axis. */
zh = xk*yl - xl*yk;
@@ -302,6 +303,11 @@ static void render_za(UnitCell *cell, RefList *list,
return;
}
+ /* Use manual scale top if specified */
+ if ( scale_top > 0.0 ) {
+ max_val = scale_top;
+ }
+
/* Choose whichever scaling factor gives the smallest value */
scale_u = ((double)wh-border) / (2.0*max_u);
scale_v = ((double)ht-border) / (2.0*max_v);
@@ -318,7 +324,15 @@ static void render_za(UnitCell *cell, RefList *list,
}
if ( outfile == NULL ) outfile = "za.pdf";
- surface = cairo_pdf_surface_create(outfile, wh, ht);
+
+ if ( strcmp(outfile+strlen(outfile)-4, ".png") == 0 ) {
+ png = 1;
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ wh, ht);
+ } else {
+ png = 0;
+ surface = cairo_pdf_surface_create(outfile, wh, ht);
+ }
if ( cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS ) {
ERROR("Couldn't create Cairo surface\n");
@@ -390,20 +404,34 @@ static void render_za(UnitCell *cell, RefList *list,
render_overlined_indices(dctx, yh, yk, yl);
cairo_fill(dctx);
+ if ( png ) {
+ int r = cairo_surface_write_to_png(surface, outfile);
+ if ( r != CAIRO_STATUS_SUCCESS ) {
+ ERROR("Failed to write PNG to '%s'\n", outfile);
+ }
+ }
+
cairo_surface_finish(surface);
cairo_destroy(dctx);
}
-static int render_key(int colscale)
+static int render_key(int colscale, double scale_top)
{
cairo_surface_t *surface;
cairo_t *dctx;
- float wh, ht;
- float y;
+ double top, wh, ht, y;
+ double slice;
- wh = 128;
- ht = 1024;
+ wh = 128.0;
+ ht = 1024.0;
+ slice = 1.0;
+
+ if ( scale_top > 0.0 ) {
+ top = scale_top;
+ } else {
+ top = 1.0;
+ }
surface = cairo_pdf_surface_create("key.pdf", wh, ht);
@@ -415,19 +443,61 @@ static int render_key(int colscale)
dctx = cairo_create(surface);
- for ( y=0; y<ht; y++ ) {
+ for ( y=0.0; y<ht; y+=slice ) {
- float r, g, b;
+ double r, g, b;
+ double val;
+ double v = y;
- cairo_rectangle(dctx, 0.0, y, wh, y+1.0);
+ cairo_rectangle(dctx, 0.0, ht-y, wh/2.0, slice);
+
+ if ( colscale == SCALE_RATIO ) {
+ if ( v < ht/2.0 ) {
+ val = v/(ht/2.0);
+ } else {
+ val = (((v-ht/2.0)/(ht/2.0))*(top-1.0))+1.0;
+ }
+ } else {
+ val = v/ht;
+ }
- render_scale(ht-y, ht, colscale, &r, &g, &b);
+ render_scale(val, top, colscale, &r, &g, &b);
cairo_set_source_rgb(dctx, r, g, b);
+ cairo_stroke_preserve(dctx);
cairo_fill(dctx);
}
+ if ( colscale == SCALE_RATIO ) {
+
+ cairo_text_extents_t size;
+ char tmp[32];
+
+ cairo_rectangle(dctx, 0.0, ht/2.0-2.0, wh/2.0, 4.0);
+ cairo_set_source_rgb(dctx, 0.0, 0.0, 0.0);
+ cairo_stroke_preserve(dctx);
+ cairo_fill(dctx);
+
+ cairo_set_font_size(dctx, 20.0);
+ cairo_text_extents(dctx, "1.0", &size);
+ cairo_move_to(dctx, wh/2.0+5.0, ht/2.0+size.height/2.0);
+ cairo_show_text(dctx, "1.0");
+
+ cairo_set_font_size(dctx, 20.0);
+ cairo_text_extents(dctx, "0.0", &size);
+ cairo_move_to(dctx, wh/2.0+5.0, ht-5.0);
+ cairo_show_text(dctx, "0.0");
+
+ cairo_set_font_size(dctx, 20.0);
+ snprintf(tmp, 31, "%.1f", top);
+ cairo_text_extents(dctx, tmp, &size);
+ cairo_move_to(dctx, wh/2.0+5.0, size.height+5.0);
+ cairo_show_text(dctx, tmp);
+
+ }
+
+
cairo_surface_finish(surface);
cairo_destroy(dctx);
@@ -487,6 +557,8 @@ int main(int argc, char *argv[])
char *down = NULL;
char *right = NULL;
char *outfile = NULL;
+ double scale_top = -1.0;
+ char *endptr;
/* Long options */
const struct option longopts[] = {
@@ -503,6 +575,7 @@ int main(int argc, char *argv[])
{"right", 1, NULL, 'r'},
{"counts", 0, &config_sqrt, 1},
{"colour-key", 0, &config_colkey, 1},
+ {"scale-top", 1, NULL, 2},
{0, 0, NULL, 0}
};
@@ -551,6 +624,21 @@ int main(int argc, char *argv[])
outfile = strdup(optarg);
break;
+ case 2 :
+ errno = 0;
+ scale_top = strtod(optarg, &endptr);
+ if ( !( (optarg[0] != '\0') && (endptr[0] == '\0') )
+ || (errno != 0) )
+ {
+ ERROR("Invalid scale top('%s')\n", optarg);
+ return 1;
+ }
+ if ( scale_top < 0.0 ) {
+ ERROR("Scale top must be positive.\n");
+ return 1;
+ }
+ break;
+
case 0 :
break;
@@ -560,8 +648,9 @@ int main(int argc, char *argv[])
}
- if ( pdb == NULL ) {
- pdb = strdup("molecule.pdb");
+ if ( (pdb == NULL) && !config_colkey ) {
+ ERROR("You must specify the PDB containing the unit cell.\n");
+ return 1;
}
if ( sym == NULL ) {
@@ -604,6 +693,8 @@ int main(int argc, char *argv[])
colscale = SCALE_COLOUR;
} else if ( strcmp(cscale, "color") == 0 ) {
colscale = SCALE_COLOUR;
+ } else if ( strcmp(cscale, "ratio") == 0 ) {
+ colscale = SCALE_RATIO;
} else {
ERROR("Unrecognised colour scale '%s'\n", cscale);
return 1;
@@ -611,7 +702,7 @@ int main(int argc, char *argv[])
free(cscale);
if ( config_colkey ) {
- return render_key(colscale);
+ return render_key(colscale, scale_top);
}
if ( config_zoneaxis ) {
@@ -659,10 +750,10 @@ int main(int argc, char *argv[])
if ( config_povray ) {
r = povray_render_animation(cell, list,
- nproc, sym, wght, boost);
+ nproc, sym, wght, boost, scale_top);
} else if ( config_zoneaxis ) {
render_za(cell, list, boost, sym, wght, colscale,
- rh, rk, rl, dh, dk, dl, outfile);
+ rh, rk, rl, dh, dk, dl, outfile, scale_top);
} else {
ERROR("Try again with either --povray or --zone-axis.\n");
}