/* * intersect.c --- Find intersections of curve segments * Author: Masatake YAMATO * Derived from sample.c. */ #include #include #include #include #include #include "gtkDPS.h" GdkDPSPoint points[8]; int p_index = 0; static void release_callback(GtkDPSArea *area, GdkEventButton *event, GdkDPSPoint *dps_point) { GdkDPSSegment segment[2]; GList * list, * tmp; int i; points[p_index] = *dps_point; if (p_index == 7) { g_message ("---"); for (i = 0; i < 8; i++) g_message ("%f %f", points[i].x, points[i].y); gtk_dps_widget_begin(area); DPSmoveto (raw_ctxt, points[4].x, points[4].y); DPScurveto (raw_ctxt, points[5].x, points[5].y, points[6].x, points[6].y, points[7].x, points[7].y); DPSsetrgbcolor (raw_ctxt, 0.0, 0.0, 0.0); DPSstroke (raw_ctxt); gtk_dps_widget_end(); segment[0] = gdk_dps_segment_by_points (&points[0], &points[1], &points[2], &points[3]); segment[1] = gdk_dps_segment_by_points (&points[4], &points[5], &points[6], &points[7]); tmp = list = gdk_dps_segment_intersect (&segment[0], &segment[1]); g_message ("%% Found %d intersection(s)", g_list_length(tmp)); while (tmp) { gpointer p; float d; GdkDPSPoint intersection; p = tmp->data; d = ((float *)p)[0]; intersection = gdk_dps_segment_get_point (&(segment[0]), d); g_message ("%% %f %f", intersection.x, intersection.y); gtk_dps_widget_begin(area); DPSsetrgbcolor (raw_ctxt, 0.0, 0.0, 1.0); DPSrectfill(raw_ctxt, intersection.x - 2.0, intersection.y - 2.0, 4.0, 4.0); gtk_dps_widget_end(); g_free(tmp->data); tmp->data = NULL; tmp = g_list_next (tmp); } g_list_free (list); p_index = 0; } else if (p_index == 3) { gtk_dps_widget_begin(area); DPSmoveto (raw_ctxt, points[0].x, points[0].y); DPScurveto (raw_ctxt, points[1].x, points[1].y, points[2].x, points[2].y, points[3].x, points[3].y); DPSsetrgbcolor (raw_ctxt, 0.0, 0.0, 0.0); DPSstroke (raw_ctxt); gtk_dps_widget_end(); p_index++; } else if (p_index == 0) { gtk_dps_widget_begin(area); DPSerasepage(raw_ctxt); gtk_dps_widget_end(); p_index++; } else p_index++; gtk_dps_widget_begin(area); if (p_index > 4 || p_index == 0) DPSsetrgbcolor (raw_ctxt, 0.0, 1.0, 0.0); else DPSsetrgbcolor (raw_ctxt, 1.0, 0.0, 0.0); DPSrectfill(raw_ctxt, dps_point->x - 0.5, dps_point->y - 0.5, 1.0, 1.0); gtk_dps_widget_end(); } static void draw_ready_callback (GtkDPSArea *area) { int i; for (i = 0; i < 8 ; i++) release_callback (area, NULL, &(points[i])); } static void dialog_close_callback (GtkWidget *widget, gpointer data) { gtk_main_quit(); } static gboolean read_points (char * fname) { int i; int n; gboolean reslut; FILE * fp; g_return_val_if_fail (fname, FALSE); fp = fopen (fname, "r"); if (fp == NULL) { g_warning ("Fail to open file: %s", fname); return FALSE; } reslut = TRUE; for (i = 0; i < 8; i++) { n = fscanf (fp, "%f %f", &(points[i].x), &(points[i].y)); if (n != 2) { reslut = FALSE; g_warning ("Wrong data formats in line: %d", i); break; } } if (reslut == TRUE) { g_message ("Reading data from file..."); for (i = 0; i < 8; i++) g_message ("%f %f", points[i].x, points[i].y); } fclose (fp); return reslut; } int main(int argc, char **argv) { /* GtkWidget is the storage type for widgets */ GtkWidget *dialog; GtkWidget *close_button; GtkWidget *DPS_area; gboolean data_is_given = FALSE; /* * This is called in all GTK applications. Arguments are parsed from * the command line and are returned to the application. */ gtk_init(&argc, &argv); gtk_dps_init(&argc, &argv); /* * If a file is given read points from the file. */ if (argc > 1) data_is_given = read_points(argv[1]); /* create a new dialog */ dialog = gtk_dialog_new(); /* create a new dps area */ DPS_area = gtk_dps_area_new(0); gtk_signal_connect(GTK_OBJECT(DPS_area), "button_release_event_dps", (GtkSignalFunc)release_callback, NULL); if (data_is_given == TRUE) gtk_signal_connect(GTK_OBJECT(DPS_area), "draw_ready", (GtkSignalFunc)draw_ready_callback, NULL); /* set the DPS_area size */ gtk_dps_area_size(GTK_DPS_AREA(DPS_area), 500, 500); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), DPS_area, TRUE, TRUE, 0); /* display DPS_area */ gtk_widget_show(DPS_area); /* create a new button with the label "Close". */ close_button = gtk_button_new_with_label("Close"); /* * Instead of gtk_container_add, we pack this close_button into the * invisible box, which has been packed into the dialog. */ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), close_button, TRUE, TRUE, 0); /* * When the button receives the "clicked" signal, it will call the * function dialog_close_callback() passing it NULL as it's argument. * The dialog_close_callback() function is defined above. */ gtk_signal_connect(GTK_OBJECT(close_button), "clicked", (GtkSignalFunc)dialog_close_callback, NULL); /* display close_button */ gtk_widget_show(close_button); /* display the dialog */ gtk_widget_show(dialog); /* * All GTK applications must have a gtk_main(). Control ends here * and waits for an event to occur (like a key press or mouse event). */ gtk_main(); return 0; }