diff --git a/solidify/overlap.c b/solidify/overlap.c index c0b92e2..996cabf 100644 --- a/solidify/overlap.c +++ b/solidify/overlap.c @@ -18,10 +18,24 @@ #include #include "face.h" +#include "solid.h" #include "overlap.h" #define UNDEF_F HUGE_VAL +#define BORDER 10 /* pixels around the minimum drawing area */ + + +static int sx(const struct solid *s) +{ + return (s->a->sx > s->b->sx ? s->a->sx : s->b->sx)+2*BORDER; +} + + +static int sy(const struct solid *s) +{ + return (s->a->sy > s->b->sy ? s->a->sy : s->b->sy)+2*BORDER; +} static double ramp(int z0, double w0, int z1, double w1) @@ -59,19 +73,20 @@ static double zmix(struct face *f, double x, double y) } -static void draw_image(GtkWidget *widget, struct face *f) +static void draw_image(GtkWidget *widget, struct solid *s) { guchar *rgbbuf, *p; int x, y; double z; + struct face *f = s->a; - rgbbuf = p = calloc(f->sx*f->sy, 3); + rgbbuf = p = calloc(sx(s)*sy(s), 3); if (!rgbbuf) { perror("calloc"); exit(1); } - for (y = f->sy-1; y >= 0; y--) - for (x = 0; x != f->sx ; x++) { + for (y = sy(s)-1; y >= 0; y--) + for (x = 0; x != sx(s) ; x++) { int xa = x+f->a->min_x; int ya = y+f->a->min_y; @@ -93,7 +108,7 @@ static void draw_image(GtkWidget *widget, struct face *f) } gdk_draw_rgb_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], - 0, 0, f->sx, f->sy, GDK_RGB_DITHER_MAX, rgbbuf, f->sx*3); + 0, 0, sx(s), sy(s), GDK_RGB_DITHER_MAX, rgbbuf, sx(s)*3); free(rgbbuf); } @@ -124,7 +139,8 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) { GtkWidget *da = gtk_bin_get_child(GTK_BIN(widget)); - struct face *f = data; + struct solid *s = data; + struct face *f = s->a; int dx = event->x-f->sx/2; int dy = event->y-f->sy/2; double r = hypot(dx, dy); @@ -134,11 +150,11 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, switch (event->direction) { case GDK_SCROLL_UP: rotate(&f->m, r); - draw_image(da, f); + draw_image(da, s); break; case GDK_SCROLL_DOWN: rotate(&f->m, -r); - draw_image(da, f); + draw_image(da, s); break; default: /* ignore */; @@ -156,22 +172,20 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, -void overlap(GtkWidget *canvas, struct face *f) +void overlap(GtkWidget *canvas, struct solid *s) { GtkWidget *evbox, *da; evbox = gtk_event_box_new(); da = gtk_drawing_area_new(); - gtk_widget_set_size_request(da, f->sx, f->sy); + gtk_widget_set_size_request(da, sx(s), sy(s)); gtk_container_add(GTK_CONTAINER(canvas), evbox); gtk_container_add(GTK_CONTAINER(evbox), da); - draw_image(da, f); + draw_image(da, s); g_signal_connect(G_OBJECT(evbox), "scroll-event", - G_CALLBACK(scroll_event), f); + G_CALLBACK(scroll_event), s); g_signal_connect(G_OBJECT(da), "expose-event", - G_CALLBACK(expose_event), f); - - return evbox; + G_CALLBACK(expose_event), s); } diff --git a/solidify/overlap.h b/solidify/overlap.h index b24b3e5..f21bd79 100644 --- a/solidify/overlap.h +++ b/solidify/overlap.h @@ -15,7 +15,9 @@ #include +#include "solid.h" -void overlap(GtkWidget *canvas, struct face *face); + +void overlap(GtkWidget *canvas, struct solid *solid); #endif /* !OVERLAP_H */ diff --git a/solidify/solid.h b/solidify/solid.h new file mode 100644 index 0000000..67097a0 --- /dev/null +++ b/solidify/solid.h @@ -0,0 +1,21 @@ +/* + * solid.h - Data structure and handling of a solid made of two opposing faces + * + * Written 2010 by Werner Almesberger + * Copyright 2010 by Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef SOLID_H +#define SOLID_H + +struct solid { + struct face *a, *b; + double dist; +}; + +#endif /* SOLID_H */ diff --git a/solidify/solidify.c b/solidify/solidify.c index c17b22f..5fc358b 100644 --- a/solidify/solidify.c +++ b/solidify/solidify.c @@ -17,11 +17,12 @@ #include #include "face.h" +#include "solid.h" #include "level.h" #include "overlap.h" -static struct face *face_a, *face_b; +static struct solid solid; static const struct face *active; static GtkWidget *canvas; @@ -38,7 +39,7 @@ static void clicked(GtkButton *button, gpointer user_data) if (face) level(canvas, face); else - overlap(canvas, face_a); + overlap(canvas, &solid); active = face; gtk_widget_show_all(canvas); @@ -54,12 +55,12 @@ static GtkWidget *gui_buttons(void) but = gtk_button_new_with_label("A"); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(but), "clicked", - G_CALLBACK(clicked), face_a); + G_CALLBACK(clicked), solid.a); but = gtk_button_new_with_label("B"); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(but), "clicked", - G_CALLBACK(clicked), face_b); + G_CALLBACK(clicked), solid.b); but = gtk_button_new_with_label("A+B"); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); @@ -98,8 +99,8 @@ static void gui(void) buttons = gui_buttons(); gtk_box_pack_start(GTK_BOX(hbox), buttons, FALSE, FALSE, 0); - level(canvas, face_a); - active = face_a; + level(canvas, solid.a); + active = solid.a; gtk_widget_show_all(root); @@ -129,8 +130,8 @@ int main(int argc, char **argv) usage(*argv); } setlocale(LC_ALL, "C"); /* damage control */ - face_a = read_face(argv[1]); - face_b = face_a; + solid.a = read_face(argv[1]); + solid.b = solid.a; gui(); return 0;