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:
parent
b8bba1d3ab
commit
1fa23c574e
@ -18,10 +18,24 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
@ -15,7 +15,9 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "solid.h"
|
||||
|
||||
void overlap(GtkWidget *canvas, struct face *face);
|
||||
|
||||
void overlap(GtkWidget *canvas, struct solid *solid);
|
||||
|
||||
#endif /* !OVERLAP_H */
|
||||
|
21
solidify/solid.h
Normal file
21
solidify/solid.h
Normal 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 */
|
@ -17,11 +17,12 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#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;
|
||||
|
Loading…
Reference in New Issue
Block a user