home *** CD-ROM | disk | FTP | other *** search
-
- /**************************************************************************
- Touchup a bitmap graphics editor for the Sun Workstation running SunView
- Copyright (c) 1988 by Raymond Kreisel
- 1/22/88 @ Suny Stony Brook
-
- This program may be redistributed without fee as long as this copyright
- notice is intact.
-
- ==> PLEASE send comments and bug reports to one of the following addresses:
-
- Ray Kreisel
- CS Dept., SUNY at Stony Brook, Stony Brook NY 11794
-
- UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk
- ARPA-Internet: rayk@sbcs.sunysb.edu
- CSnet: rayk@suny-sb
- (If nobody is home at any of the above addresses try:
- S72QKRE@TOWSONVX.BITNET )
-
- "If I get home before daylight, I just might get some sleep tonight...."
-
- **************************************************************************/
- /**************************************************************************
- file: touchup.c
- purpose: this file has misc functions that do different crap
- but mostly the event handler for the main drawing
- area
- modifications:
- date: Tue Mar 22 22:04:58 EST 1988
- author: rayk
- changes:add comments
- **************************************************************************/
-
- #include "header.h"
-
- unsigned char red[256],green[256],blue[256];
- int image_wid= DEFAULT_IMAGE_WID,image_hgt= DEFAULT_IMAGE_HGT,image_depth=1;
- int top_x=0,top_y=0,bottom_x=0,bottom_y=0;
- int cur_color=1,grid_size=0;
- int magnify_fac=8,fat_x,fat_y,fat_source_x=0-1,fat_source_y=0-1;
- int mouse_left=PAINT,undo_flag=TRUE;
- int select_pt_x=0-1,select_pt_y=0-1;
- int old_x=0; old_y=0;
- int start_x=0; start_y=0;
- char file_name[MAX_FILE_NAME];
- struct pixrect *cut_buffer_pr=NULL,
- *undo_pr=NULL;
-
- struct pixfont *main_font=NULL;
-
- /*
- * this is the event handler for the special cut/paste command menu
- */
- region_handle(item, event)
- Panel_item item;
- Event *event;
- {
- switch((int)panel_get_value(region_choice)) {
- case CUT:
- cut_region();
- break;
- case COPY:
- print_msg("Region copied to Cut/Paste buffer. Hold down the RIGHT mouse button to drag the object.");
- panel_set(region_choice,PANEL_VALUE,MOVE,0);
- copy_region();
- break;
- case FLIP_HOR:
- flip_hor_region();
- break;
- case FLIP_VER:
- flip_ver_region();
- break;
- case ROTATE:
- rotate_region();
- break;
- case INVERSE:
- inverse_region();
- break;
- case PASTE:
- paste_region();
- break;
- case MOVE:
- print_msg("Hold down the RIGHT mouse button and drag the object.");
- break;
- }
-
- }
-
-
- /*
- * this is the event handler for the main comand menu
- */
- command_handle(item, event)
- Panel_item item;
- Event *event;
- {
- hide_msg();
- if ((int)panel_get_value(command_choice) != GET_PT)
- {
- (void)window_set(region_panel, WIN_SHOW, FALSE, 0);
- panel_set(region_choice,PANEL_VALUE,5,0);
- }
- (void)window_set(brush_panel, WIN_SHOW, FALSE, 0);
- switch((int)panel_get_value(command_choice)) {
- case TEXT:
- draw_text();
- break;
- case LASO:
- print_msg("Hold down the LEFT mouse button and encircle a object.");
- mouse_parms();
- break;
- case CIRCLE:
- print_msg("Hold down the LEFT mouse button and extend to radius of the circle.");
- mouse_parms();
- break;
- case DRAW:
- print_msg("Press the LEFT mouse button to DRAW.");
- mouse_parms();
- break;
- case LINE:
- print_msg("Hold down the LEFT mouse button and extend to end of the line.");
- mouse_parms();
- break;
- case MAGNIFY:
- print_msg("Use LEFT button to draw, hold down MIDDLE button to move.");
- fat_mode();
- break;
- case FFILL:
- fill_mode(item, event);
- mouse_parms();
- break;
- case OVAL:
- print_msg("Hold down the LEFT mouse button and extend to edge of the oval.");
- mouse_parms();
- break;
- case POLY_F:
- case POLY_H:
- print_msg("Press the LEFT mouse button to select a vertex.");
- mouse_parms();
- break;
- case RECT_F:
- case RECT_H:
- print_msg("Hold down the LEFT mouse button and extend to the opposite corner.");
- mouse_parms();
- break;
- case PAINT:
- print_msg("Press the LEFT mouse button to PAINT.");
- mouse_parms();
- (void)window_set(brush_panel, WIN_SHOW, TRUE, 0);
- break;
- case SEL_REG:
- print_msg("Hold down the LEFT mouse button and extend to the opposite corner.");
- if (mouse_left == SEL_REG)
- {
- clean_region();
- top_x = 0;
- top_y = 0;
- bottom_x = image_wid;
- bottom_y = image_hgt;
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- }
- else
- {
- mouse_parms();
- }
- (void)window_set(region_panel, WIN_SHOW, TRUE, 0);
- break;
- case GET_PT:
- print_msg("Press the LEFT mouse button to select a point.");
- mouse_parms();
- break;
- case ERASE:
- print_msg("Press the LEFT MOUSE button to ERASE.");
- if ((mouse_left == ERASE) && (confirm("Erase entire drawing area ?")))
- {
- clear_screen();
- (void)window_set(canvas,
- CANVAS_WIDTH, DEFAULT_IMAGE_WID,
- CANVAS_HEIGHT, DEFAULT_IMAGE_HGT,
- 0);
- }
- else
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- region_fix();
- pw_rop(pw,top_x,top_y,bottom_x-top_x,bottom_y-top_y,PIX_SRC,0,0,0);
- reset_region();
- }
- mouse_parms();
- break;
-
- }
-
- }
-
-
-
- /*
- * save the screen to a temp bitmap for the undo command
- */
- save_screen()
- {
- if (undo_flag)
- {
- if (undo_pr == NULL)
- undo_pr =my_mem_create(image_wid,image_hgt,image_depth);
- pr_rop(undo_pr,0,0,image_wid,image_hgt,PIX_SRC,pw->pw_prretained,0,0);
- }
- }
-
-
- /*
- * go back to the last saved bitmap
- */
- undo_screen(item, event)
- Panel_item item;
- Event *event;
- {
- if (undo_flag)
- {
- clean_region();
- clean_point();
- clean_poly();
- fat_done();
- pw_write(pw,0,0, image_wid,image_hgt, PIX_SRC, undo_pr,0,0);
- }
- }
-
-
-
- /*
- * clear the drawing area
- */
- clear_screen(item, event)
- Panel_item item;
- Event *event;
- {
- clean_point();
- clean_region();
- save_screen();
- fat_done();
- pw_write( pw,0,0,1280,1280,PIX_SRC,0,0,0);
- pw_write( fat_pw,0,0,1280,1280,PIX_SRC,0,0,0);
- }
-
-
- /*
- * if there is a region that is select the deselect it
- */
- clean_region()
- {
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- reset_region();
- }
- }
-
-
- /*
- * if there is a point that is selected then deselecte it
- */
- clean_point()
- {
- if (select_pt_x != -1)
- {
- select_point(select_pt_x,select_pt_y);
- select_pt_x = -1;
- select_pt_y = -1;
- }
- }
-
-
- /*
- * deselect any points and regions and get the current command mode
- */
- mouse_parms(item, event)
- Panel_item item;
- Event *event;
- {
- clean_point();
- clean_region();
- fat_done();
- mouse_left = (int)panel_get_value(command_choice);
- }
-
-
- /*
- * set it to select a point mode
- */
- set_select_mode()
- {
- panel_set(command_choice,PANEL_VALUE, GET_PT,0);
- mouse_parms();
- }
-
-
-
- /*
- * this the main event handler that makes the whole thing go
- * this event handle is for that canvas that is the main drawing area
- */
- handle_event(canvas_local, event, arg)
- Canvas canvas_local;
- Event *event;
- caddr_t arg;
- {
- Pixwin *pw = canvas_pixwin(canvas_local);
-
- if (grid_size)
- {
- event_set_x(event,event_x(event) + grid_size/2 - (event_x(event)%grid_size));
- event_set_y(event,event_y(event) + grid_size/2 - (event_y(event)%grid_size));
- }
-
- if (event_is_up(event))
- {
- if (event_id(event) == MS_LEFT)
- {
- if ((mouse_left == RECT_H) || (mouse_left == RECT_F))
- draw_rectangle(start_x,start_y,event_x(event), event_y(event));
- if (mouse_left == LINE)
- draw_line(start_x,start_y,event_x(event), event_y(event),PIX_SRC,cur_color);
- if (mouse_left == ERASE)
- {
- select_region(pw,top_x,top_y,top_x+PATTERN_SIZE,top_y+PATTERN_SIZE);
- reset_region();
- }
-
- if (mouse_left == CIRCLE)
- {
- draw_line(start_x,start_y,old_x,old_y,PIX_XOR,1);
- draw_circle(pw,start_x,start_y,distance(old_x,old_y,start_x,start_y),1,PIX_SET);
- }
-
- if (mouse_left == OVAL)
- draw_oval(pw,start_x,start_y,old_x,old_y,TRUE);
-
- if (fat_source_x != -1)
- fat_update(0,0);
- if (mouse_left == GET_PT)
- {
- select_pt_x = event_x(event);
- select_pt_y = event_y(event);
- }
- if (mouse_left == LASO)
- {
- laso_cut_paste();
- panel_set(region_choice,PANEL_VALUE,MOVE,0);
- panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
- (void)window_set(brush_panel, WIN_SHOW,FALSE, 0);
- (void)window_set(region_panel, WIN_SHOW,TRUE, 0);
- print_msg("Object copied to Cut/Paste buffer. Hold down the RIGHT mouse button to drag the object.");
- mouse_parms();
- }
- }
- if (event_id(event) == MS_RIGHT)
- {
- if (((int)panel_get_value(region_choice) == MOVE) && (cut_buffer_pr != NULL))
- {
- pw_write(pw,old_x- cut_buffer_pr->pr_size.x/2,
- old_y- cut_buffer_pr->pr_size.y/2,
- cut_buffer_pr->pr_size.x,
- cut_buffer_pr->pr_size.y,
- PIX_XOR, cut_buffer_pr,0,0);
- pw_write(pw,event_x(event)-cut_buffer_pr->pr_size.x/2,
- event_y(event)-cut_buffer_pr->pr_size.y/2,
- cut_buffer_pr->pr_size.x,
- cut_buffer_pr->pr_size.y,
- PIX_SRC | PIX_DST, cut_buffer_pr,0,0);
- }
- }
- return;
- }
- switch (event_id(event)) {
- case MS_LEFT:
- if ((mouse_left != POLY_H) && (mouse_left != POLY_F) && (mouse_left != GET_PT) && (mouse_left != SEL_REG))
- save_screen();
- old_x = event_x(event);
- old_y = event_y(event);
- start_x = event_x(event);
- start_y = event_y(event);
- switch(mouse_left) {
-
- case LINE:
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- break;
- case POLY_F:
- case POLY_H:
- if (poly_points[0].x == -1)
- save_screen();
- poly_addpt(poly_points,start_x,start_y);
- print_msg("Press the LEFT button to select a vertex or press the RIGHT mouse button to end the polygon.");
- break;
- case DRAW:
- draw_point(pw,event_x(event), event_y(event));
- break;
- case PAINT:
- draw_brush(pw, event_x(event), event_y(event));
- break;
- case ERASE:
- top_x = event_x(event)-PATTERN_SIZE/2; top_y= event_y(event)-PATTERN_SIZE/2;
- select_region(pw,top_x,top_y,top_x+PATTERN_SIZE,top_y+PATTERN_SIZE);
- erase_brush(pw, event_x(event), event_y(event));
- break;
- case CIRCLE:
- draw_line(start_x,start_y,old_x,old_y,PIX_XOR,1);
- break;
- case OVAL:
- draw_oval(pw,start_x,start_y,old_x,old_y,FALSE);
- break;
- case GET_PT:
- if (select_pt_x != -1)
- select_point(select_pt_x,select_pt_y);
- old_x = event_x(event);
- old_y = event_y(event);
- select_point(old_x,old_y);
- break;
-
- case SEL_REG:
- if (top_x || top_y || bottom_x || bottom_y)
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- save_screen();
- top_x = event_x(event);
- top_y = event_y(event);
- bottom_x = event_x(event);
- bottom_y = event_y(event);
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- break;
- case LASO:
- ptlist[0].x = -1;
- ptlist[0].y = -1;
- laso_addpt(ptlist,start_x,start_y);
- break;
- }
-
- break;
-
- case MS_MIDDLE:
- switch(mouse_left) {
- case SEL_REG:
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- bottom_x = event_x(event);
- bottom_y = event_y(event);
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- }
- break;
- }
- break;
- case MS_RIGHT:
- if (((mouse_left==POLY_F) || (mouse_left ==POLY_H))
- && (poly_points[0].x != -1))
- {
- poly_addpt(poly_points,event_x(event),event_y(event));
- draw_poly(poly_points);
- }
- if (((int)panel_get_value(region_choice) == MOVE) && (cut_buffer_pr != NULL))
- {
- clean_region();
- clean_point();
- save_screen();
- old_x = event_x(event);
- old_y = event_y(event);
- start_x = old_x;
- start_y = old_y;
- pw_write(pw,old_x - cut_buffer_pr->pr_size.x/2,
- old_y - cut_buffer_pr->pr_size.y/2,
- cut_buffer_pr->pr_size.x,
- cut_buffer_pr->pr_size.y,
- PIX_XOR, cut_buffer_pr,0,0);
- }
- break;
- case LOC_DRAG:
- if (window_get(canvas_local, WIN_EVENT_STATE, MS_LEFT))
- {
- switch(mouse_left) {
- case PAINT:
- draw_brush(pw, event_x(event), event_y(event));
- break;
- case DRAW:
- draw_point(pw,event_x(event), event_y(event));
- break;
- case ERASE :
- erase_brush(pw, event_x(event), event_y(event));
- break;
- case LINE:
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- old_x = event_x(event);
- old_y = event_y(event);
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- break;
- case RECT_F :
- case RECT_H :
- select_region(pw,old_x,old_y,start_x,start_y);
- old_x = event_x(event);
- old_y = event_y(event);
- select_region(pw,old_x,old_y,start_x,start_y);
- break;
- case CIRCLE:
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- old_x = event_x(event);
- old_y = event_y(event);
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- break;
- case OVAL:
- draw_oval(pw,start_x,start_y,old_x,old_y,FALSE);
- old_x = event_x(event);
- old_y = event_y(event);
- draw_oval(pw,start_x,start_y,old_x,old_y,FALSE);
- break;
- case GET_PT:
- select_point(old_x,old_y);
- select_pt_x = event_x(event);
- select_pt_y = event_y(event);
- old_x = event_x(event);
- old_y = event_y(event);
- select_point(old_x,old_y);
- break;
- case SEL_REG:
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- bottom_x = event_x(event);
- bottom_y = event_y(event);
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- break;
- case LASO:
- laso_addpt(ptlist,event_x(event),event_y(event));
- }
- case POLY_F:
- case POLY_H:
- if (poly_points[0].x != -1)
- {
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- old_x = event_x(event);
- old_y = event_y(event);
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- }
- }
- if (window_get(canvas_local, WIN_EVENT_STATE, MS_RIGHT))
- {
- if ((int)panel_get_value(region_choice) == MOVE)
- {
- move_region(old_x,old_y,event_x(event),event_y(event));
- old_x = event_x(event);
- old_y = event_y(event);
- }
- }
- break;
- case LOC_MOVE:
- if (((mouse_left == POLY_F) || (mouse_left == POLY_H)) &&
- (poly_points[0].x != -1))
- {
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- old_x = event_x(event);
- old_y = event_y(event);
- draw_line(old_x,old_y,start_x,start_y,PIX_XOR,1);
- }
- break;
- }
- }
-
-
-
- /*
- * we got a "quit" button, say bye bye
- */
- quit(item, event)
- Panel_item item;
- Event *event;
-
- {
- window_done(base_frame);
- }
-
-
- /*
- * get all the current values for some stuff
- */
- change_parms(item, event)
- Panel_item item;
- Event *event;
- {
- if (image_depth == 1)
- cur_color = (int)panel_get_value(mono_cycle);
- magnify_fac = (int)panel_get_value(magnify_cycle) + 1;
- grid_size = (int)panel_get_value(grid_cycle)*5;
- }
-
-
-
- /*
- * this is the main that start the show and then goes into
- * window main loop
- */
- main(argc,argv) int argc; char *argv[];
- {
- char *s;
-
- /*
- * do some agr checking
- */
- while (--argc > 0 && (*++argv)[0] == '-')
- for (s = argv[0]+1;*s != '\0';s++)
- switch (*s) {
- case 'n':
- undo_flag = FALSE;
- break;
- case 'p':
- image_hgt = DEFAULT_IMAGE_WID;
- image_wid = DEFAULT_IMAGE_HGT;
- break;
- case 'y': ++argv; argc--;
- image_hgt = atoi(argv[0]);
- break;
- case 'x': ++argv; argc--;
- image_wid = atoi(argv[0]);
- break;
- default: printf("Usage: touchup [-x width] [-y height] [-n] [-p]\n");
- exit(0);
- }
- if (argc > 0)
- {
- printf("Usage: touchup [-x width] [-y height] [-n] [-p]\n");
- exit(0);
- }
-
- clean_poly();
-
- /*
- * get the font used in all of the panels
- */
- main_font = pf_open(MAIN_FONT);
- if (!main_font)
- {
- printf("ERROR loading the main font !!!!\n");
- exit(1);
- }
-
- init_font();
- getcwd(file_name,MAX_FILE_NAME-2);
- strcat(file_name,"/");
- init_windows(argc,argv);
- /*
- * are we on a color machine ????
- */
- image_depth = pw->pw_pixrect->pr_depth;
- if (image_depth == 8)
- {
- init_colortable();
- my_put_colormap();
- set_color();
- }
- else
- set_mono();
-
- if (undo_flag)
- undo_pr = my_mem_create(image_wid,image_hgt,image_depth);
- else
- panel_set(undo_button,PANEL_SHOW_ITEM, FALSE,0);
-
- init_mag();
- window_main_loop(base_frame);
- }
-
-
-
- /***************************************************************
- hide_msg
- purpose: To clear the masssage display area.
- parameter:
- returns:
- ***************************************************************/
- hide_msg()
- {
- panel_set(msg_string,PANEL_LABEL_STRING,"",0);
- }
-
-
- /***************************************************************
- print_msg
- purpose: To print a message on the window and center it
- parameter:
- string: The string to be printed.
- returns:
- ***************************************************************/
- print_msg(string)
- char *string;
- {
- char temp_space[132];
- char *temp_pt;
- int i;
-
- if (strlen(string) < 132)
- {
- for(i=0;i<132;i++)
- temp_space[i]= ' ';
- temp_pt = temp_space + (132-strlen(string))/2;
- strcpy(temp_pt,string);
- panel_set(msg_string,PANEL_LABEL_STRING,temp_space,0);
- }
- else
- panel_set(msg_string,PANEL_LABEL_STRING,string,0);
- }
-
- ERROR(msg)
- char *msg;
- {
- print_msg(msg);
- window_bell(panel);
- }
-
- ERRORstr(msg,str)
- char *msg,*str;
- {
- char temp[200];
- strcpy(temp,msg);
- print_msg(strcat(temp,str));
- window_bell(panel);
- }
-
-
-
- /***************************************************************
- sqrt_fast
- purpose: To do a fast integer square root
- parameter:
- n : the int to take the sqrt of
- returns:
- the integer square root of n
- ***************************************************************/
- int sqrt_fast(n)
- int n;
- {
- int a,b,c;
- a = n;
- b = n;
- if (n>1){
- while (a>0) {
- a = a >> 2;
- b = b >> 1;
- }
- do {
- a = b;
- c = n / b;
- b = (c + a) >> 1;
- } while ( (a-c)<-1 || (a-c)>1 );
- }
- return(b);
- }
-
- /*
- * find the distance between any two points
- */
- distance(x1,y1,x2,y2)
- int x1,y1,x2,y2;
- {
- return(sqrt_fast((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
- }
-
-
- /*
- * check if we have enough memory to create those LARGE bitmap
- */
- struct pixrect *my_mem_create(wid,hgt,dep)
- int wid,hgt,dep;
- {
- struct pixrect* temp_pr;
-
- temp_pr = mem_create(wid,hgt,dep);
- if (temp_pr== NULL)
- {
- printf("Not enough memory, memory allocation problems!!!\n");
- exit(0);
- }
- }
-