1
0
mirror of git://projects.qi-hardware.com/ben-scans.git synced 2024-11-22 03:14:39 +02:00

Introduce a solid data type and use it, mainly in overlap()

- solidify/solid.h: definition of a solid made from two opposing faces
- solidify/overlap.h (overlap), solidify/overlap.c (draw_image,
  scroll_event, overlap): operate on solid instead of face
- solidify/overlap.c (sx, sy, draw_image, overlap): helper functions sx()
  and sy() to determine canvas size
- solidify/overlap.c (BORDER, sx, sy): added a border around the piece,
  to help with positioning
- solidify/solidify.c (clicked, gui_buttons, gui, main): use solid instead
  of faces
This commit is contained in:
Werner Almesberger 2010-09-23 23:41:35 -03:00
parent b8bba1d3ab
commit 1fa23c574e
4 changed files with 62 additions and 24 deletions

View File

@ -18,10 +18,24 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "face.h" #include "face.h"
#include "solid.h"
#include "overlap.h" #include "overlap.h"
#define UNDEF_F HUGE_VAL #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) 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; guchar *rgbbuf, *p;
int x, y; int x, y;
double z; 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) { if (!rgbbuf) {
perror("calloc"); perror("calloc");
exit(1); exit(1);
} }
for (y = f->sy-1; y >= 0; y--) for (y = sy(s)-1; y >= 0; y--)
for (x = 0; x != f->sx ; x++) { for (x = 0; x != sx(s) ; x++) {
int xa = x+f->a->min_x; int xa = x+f->a->min_x;
int ya = y+f->a->min_y; 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, gdk_draw_rgb_image(widget->window,
widget->style->fg_gc[GTK_STATE_NORMAL], 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); free(rgbbuf);
} }
@ -124,7 +139,8 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
gpointer data) gpointer data)
{ {
GtkWidget *da = gtk_bin_get_child(GTK_BIN(widget)); 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 dx = event->x-f->sx/2;
int dy = event->y-f->sy/2; int dy = event->y-f->sy/2;
double r = hypot(dx, dy); double r = hypot(dx, dy);
@ -134,11 +150,11 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
switch (event->direction) { switch (event->direction) {
case GDK_SCROLL_UP: case GDK_SCROLL_UP:
rotate(&f->m, r); rotate(&f->m, r);
draw_image(da, f); draw_image(da, s);
break; break;
case GDK_SCROLL_DOWN: case GDK_SCROLL_DOWN:
rotate(&f->m, -r); rotate(&f->m, -r);
draw_image(da, f); draw_image(da, s);
break; break;
default: default:
/* ignore */; /* 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; GtkWidget *evbox, *da;
evbox = gtk_event_box_new(); evbox = gtk_event_box_new();
da = gtk_drawing_area_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(canvas), evbox);
gtk_container_add(GTK_CONTAINER(evbox), da); gtk_container_add(GTK_CONTAINER(evbox), da);
draw_image(da, f); draw_image(da, s);
g_signal_connect(G_OBJECT(evbox), "scroll-event", 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_signal_connect(G_OBJECT(da), "expose-event",
G_CALLBACK(expose_event), f); G_CALLBACK(expose_event), s);
return evbox;
} }

View File

@ -15,7 +15,9 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "solid.h"
void overlap(GtkWidget *canvas, struct face *face);
void overlap(GtkWidget *canvas, struct solid *solid);
#endif /* !OVERLAP_H */ #endif /* !OVERLAP_H */

21
solidify/solid.h Normal file
View File

@ -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 */

View File

@ -17,11 +17,12 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "face.h" #include "face.h"
#include "solid.h"
#include "level.h" #include "level.h"
#include "overlap.h" #include "overlap.h"
static struct face *face_a, *face_b; static struct solid solid;
static const struct face *active; static const struct face *active;
static GtkWidget *canvas; static GtkWidget *canvas;
@ -38,7 +39,7 @@ static void clicked(GtkButton *button, gpointer user_data)
if (face) if (face)
level(canvas, face); level(canvas, face);
else else
overlap(canvas, face_a); overlap(canvas, &solid);
active = face; active = face;
gtk_widget_show_all(canvas); gtk_widget_show_all(canvas);
@ -54,12 +55,12 @@ static GtkWidget *gui_buttons(void)
but = gtk_button_new_with_label("A"); but = gtk_button_new_with_label("A");
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(but), "clicked", g_signal_connect(G_OBJECT(but), "clicked",
G_CALLBACK(clicked), face_a); G_CALLBACK(clicked), solid.a);
but = gtk_button_new_with_label("B"); but = gtk_button_new_with_label("B");
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(but), "clicked", 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"); but = gtk_button_new_with_label("A+B");
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
@ -98,8 +99,8 @@ static void gui(void)
buttons = gui_buttons(); buttons = gui_buttons();
gtk_box_pack_start(GTK_BOX(hbox), buttons, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), buttons, FALSE, FALSE, 0);
level(canvas, face_a); level(canvas, solid.a);
active = face_a; active = solid.a;
gtk_widget_show_all(root); gtk_widget_show_all(root);
@ -129,8 +130,8 @@ int main(int argc, char **argv)
usage(*argv); usage(*argv);
} }
setlocale(LC_ALL, "C"); /* damage control */ setlocale(LC_ALL, "C"); /* damage control */
face_a = read_face(argv[1]); solid.a = read_face(argv[1]);
face_b = face_a; solid.b = solid.a;
gui(); gui();
return 0; return 0;