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: drawing.c
- purpose: This file has most of the functions that draw stuff
- on the screen.
-
- modifications:
- date: Tue Mar 22 22:04:58 EST 1988
- author: rayk
- changes:add comments
- **************************************************************************/
-
- #include"header.h"
-
- struct pr_pos poly_points[MAX_POLY];
-
- struct pixrect *brush_temp_pr = NULL;
-
- /*
- * What we do that someone selects a new pattern
- */
- select_pattern(item, event)
- Panel_item item;
- Event *event;
- {
- panel_set(current_pattern,PANEL_LABEL_IMAGE,pattern[(int)panel_get_value(pattern_choice)],0);
-
- }
-
-
- /*
- * let the user define his own patterns to paint with
- * works for color and mono
- */
- pattern_define(item, event)
- Panel_item item;
- Event *event;
- {
-
- if (select_pt_x == -1)
- {
- ERROR("Select a point first, then select Define Pattern.");
- set_select_mode();
- return(0);
- }
- select_point(select_pt_x,select_pt_y);
- if (image_depth > 1)
- {
- pattern[39] = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,image_depth);
- pattern40_pr = *(pattern[39]);
- }
- pr_rop(pattern[39],0,0,PATTERN_SIZE,PATTERN_SIZE,
- PIX_SRC,pw->pw_prretained,select_pt_x-PATTERN_SIZE/2,
- select_pt_y-PATTERN_SIZE/2);
-
- panel_paint(pattern_choice,PANEL_NO_CLEAR);
- reset_point();
- print_msg("The user defined pattern is now stored in the last pattern element.");
- }
-
-
- /*
- * Take the current text string and put that Baby up on the bitmap
- * in the right font
- */
- draw_text()
- {
- int x,y;
-
- if (select_pt_x != -1)
- {
- x = select_pt_x;
- y = select_pt_y;
- clean_point();
- save_screen();
- pw_text(pw,x,y,PIX_COLOR(cur_color) | PIX_SRC,font_array[(int)panel_get_value(text_size_item)],
- (char*)panel_get_value(text_panel));
- }
- else
- {
- ERROR("Select a point first, fill in TEXT STRING, then select ABC.");
- window_set(panel,PANEL_CARET_ITEM,text_panel,0);
- set_select_mode();
- }
- }
-
-
- /*
- * draw a line on the bitmap
- */
- draw_line(x1,y1,x2,y2,ROP,color)
- int x1,y1,x2,y2,ROP,color;
- {
- pw_vector(pw,x1,y1,x2,y2,ROP,color);
- }
-
-
- /*
- * draw a rectangle on the bitmap
- */
- draw_rectangle(x1,y1,x2,y2)
- int x1,y1,x2,y2;
- {
- top_x = x1;
- top_y = y1;
- bottom_x = x2;
- bottom_y = y2;
- if ((int)panel_get_value(command_choice)==RECT_F)
- fill_region();
- else
- reset_region();
- if ((int)panel_get_value(border_cycle))
- {
- pw_vector(pw,x1,y1,x2,y1,PIX_SRC,cur_color);
- pw_vector(pw,x2,y1,x2,y2,PIX_SRC,cur_color);
- pw_vector(pw,x2,y2,x1,y2,PIX_SRC,cur_color);
- pw_vector(pw,x1,y2,x1,y1,PIX_SRC,cur_color);
- }
- }
-
-
- /*
- * highlight the selected region on the drawing area by throwing up a
- * XORed rectangle
- */
- select_region(pw,x1,y1,x2,y2)
- struct pixwin *pw;
- int x1,y1,x2,y2;
- {
- pw_vector(pw,x1,y1,x2,y1,PIX_XOR,1);
- pw_vector(pw,x2,y1,x2,y2,PIX_XOR,1);
- pw_vector(pw,x2,y2,x1,y2,PIX_XOR,1);
- pw_vector(pw,x1,y2,x1,y1,PIX_XOR,1);
- }
-
-
- /*
- * reset the current REGION
- */
- reset_region()
- {
- top_x=0;
- top_y=0;
- bottom_x=0;
- bottom_y=0;
- }
-
-
- /*
- * draw up a point, how stupid ???
- */
- draw_point(pw,x,y)
- struct pixwin *pw;
- int x,y;
- {
- pw_put(pw,x,y,cur_color);
- }
-
-
- /*
- * Draw up the paint brush by copying the current pattern
- * through a stencil of the current brush
- */
- draw_brush(pw,x,y)
- struct pixwin *pw;
- int x,y;
- {
- if (brush_temp_pr == NULL)
- brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,1);
-
-
- if (((int)panel_get_value(pattern_choice) != 39) || (image_depth == 1))
- {
- if (brush_temp_pr->pr_depth != 1)
- {
- MY_pr_destroy(brush_temp_pr);
- brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,1);
- }
- pr_replrop(brush_temp_pr,0,0,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],x,y);
- pw_stencil(pw,x-PATTERN_SIZE/2,y-PATTERN_SIZE/2,PATTERN_SIZE,PATTERN_SIZE,PIX_COLOR(cur_color) | PIX_SRC,
- brushes[(int)panel_get_value(brush_choice)],0,0,brush_temp_pr,0,0);
- }
- else
- {
- if (brush_temp_pr->pr_depth != image_depth)
- {
- MY_pr_destroy(brush_temp_pr);
- brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,image_depth);
- }
- pr_replrop(brush_temp_pr,0,0,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],x,y);
- pw_stencil(pw,x-PATTERN_SIZE/2,y-PATTERN_SIZE/2,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,
- brushes[(int)panel_get_value(brush_choice)],0,0,brush_temp_pr,0,0);
-
- }
-
- }
-
-
- /*
- * flip-flop two varibles (ints)
- */
- swap(x,y)
- int *x,*y;
- {
- int temp;
- temp = *x;
- *x = *y;
- *y = temp;
- }
-
-
- region_fix()
- {
- if (top_x > bottom_x)
- swap(&top_x,&bottom_x);
- if (top_y > bottom_y)
- swap(&top_y,&bottom_y);
- }
-
-
- /*
- * put the eraser on the drawing area
- */
- erase_brush(pw,x,y)
- struct pixwin *pw;
- int x,y;
- {
- select_region(pw,top_x,top_y,top_x+PATTERN_SIZE,top_y+PATTERN_SIZE);
- pw_rop(pw,x-PATTERN_SIZE/2,y-PATTERN_SIZE/2,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,0,0,0);
- top_x = x-PATTERN_SIZE/2; top_y= y-PATTERN_SIZE/2;
- select_region(pw,top_x,top_y,top_x+PATTERN_SIZE,top_y+PATTERN_SIZE);
- }
-
-
- /*
- * draw up some cross hairs to be used to select a point
- */
- #define CROSS_HAIR 20
- select_point(x,y)
- int x,y;
- {
- pw_vector(pw,x-CROSS_HAIR,y,x+CROSS_HAIR,y,PIX_XOR,1);
- pw_vector(pw,x,y-CROSS_HAIR,x,y+CROSS_HAIR,PIX_XOR,1);
- }
-
-
- /*
- * reset the currently selected point
- */
- reset_point()
- {
- select_pt_x = 0-1;
- select_pt_y = 0-1;
- }
-
-
- /*
- * take a currently selected region and invert that baby ! FAST !!!
- */
- inverse_region()
- {
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- region_fix();
- pw_replrop(pw,top_x,top_y,bottom_x-top_x,bottom_y-top_y, PIX_XOR, pattern[0],0,0);
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- }
- else
- {
- ERROR("Select a region first, then select INVERSE.");
- panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
- mouse_parms();
- }
- }
-
-
-
- /*
- * take a currently selected region and rotate around the center
- * point. SLOW !!
- */
- rotate_region()
- {
- register i,j,t1,t2;
-
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- region_fix();
- MY_pr_destroy(cut_buffer_pr);
- cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
- pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y,
- PIX_SRC,pw->pw_prretained,top_x,top_y);
- t1 = top_x + cut_buffer_pr->pr_size.x/2+ cut_buffer_pr->pr_size.y/2;
- t2 = top_y - cut_buffer_pr->pr_size.x/2+ cut_buffer_pr->pr_size.y/2;
- for (j = 0; j < cut_buffer_pr->pr_size.y; j++)
- for (i = 0; i < cut_buffer_pr->pr_size.x; i++)
- pw_rop(pw, t1-j, t2+i, 1,1, PIX_SRC, cut_buffer_pr,i,j);
-
- top_x = top_x + cut_buffer_pr->pr_size.x/2 - cut_buffer_pr->pr_size.y/2;
- top_y = top_y - cut_buffer_pr->pr_size.x/2 + cut_buffer_pr->pr_size.y/2;
- bottom_x = top_x + cut_buffer_pr->pr_size.y;
- bottom_y = top_y + cut_buffer_pr->pr_size.x;
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- }
- else
- {
- ERROR("Select a region first, then select ROTATE.");
- panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
- mouse_parms();
- }
- }
-
-
-
- /*
- * take a currently selected region and make a mirror image of it
- */
- flip_hor_region()
- {
- register i;
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- region_fix();
- MY_pr_destroy(cut_buffer_pr);
- cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
- pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y,
- PIX_SRC,pw->pw_prretained,top_x,top_y);
- for (i = 0; i < cut_buffer_pr->pr_size.x; i++) {
- pw_rop(pw, top_x+(cut_buffer_pr->pr_size.x - i)-1,top_y,
- 1,cut_buffer_pr->pr_size.y, PIX_SRC, cut_buffer_pr,i,0);
- }
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- }
- else
- {
- ERROR("Select a region first, then select MIRROR.");
- panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
- mouse_parms();
- }
- }
-
-
- /*
- * take a currently selected region and turn it upside down
- */
- flip_ver_region()
- {
- register i;
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- region_fix();
- MY_pr_destroy(cut_buffer_pr);
- cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
- pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y,
- PIX_SRC,pw->pw_prretained,top_x,top_y);
- for (i = 0; i < cut_buffer_pr->pr_size.y; i++) {
- pw_rop(pw, top_x, top_y+(cut_buffer_pr->pr_size.y - i)-1,
- cut_buffer_pr->pr_size.x, 1, PIX_SRC, cut_buffer_pr, 0, i);
- }
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- }
- else
- {
- ERROR("Select a region first, then select FLIP VERTICAL.");
- panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
- mouse_parms();
- }
- }
-
-
-
- /*
- * grab what is in the Cut/Paste buffer and put it up on the drawing area
- */
- paste_region()
- {
- int ROP=PIX_SRC;
-
- if (select_pt_x == -1)
- {
- ERROR("Select a point first, then select PASTE.");
- set_select_mode();
- return(0);
- }
- if (cut_buffer_pr)
- {
- select_point(select_pt_x,select_pt_y);
- save_screen();
- pw_write(pw,select_pt_x,select_pt_y,cut_buffer_pr->pr_size.x,cut_buffer_pr->pr_size.y, ROP, cut_buffer_pr,0,0);
- reset_point();
- }
- else
- ERROR("The Cut/Paste buffer is empty.");
- }
-
-
- /*
- * grab the currently selected region on the drawing area and stuff
- * it into the cut/paste buffer AND destroy the source area by
- * filling in with the current paint pattern
- */
- cut_region()
- {
- int t1,t2,t3,t4;
- if (top_x || top_y || bottom_x || bottom_y)
- {
- t1 = top_x;
- t2 = top_y;
- t3 = bottom_x;
- t4 = bottom_y;
- copy_region();
- top_x = t1;
- top_y = t2;
- bottom_x = t3;
- bottom_y = t4;
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- fill_region();
- set_select_mode();
- print_msg("Region copied to Cut/Paste buffer, select a point and then press PASTE.");
- }
- else
- {
- ERROR("Select a region first, then select CUT.");
- panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
- mouse_parms();
- }
- }
-
-
- /*
- * grab the currently selected region on the drawing area and stuff
- * it into the cut/paste buffer
- */
- copy_region()
- {
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- region_fix();
- MY_pr_destroy(cut_buffer_pr);
- cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
- pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y,
- PIX_SRC,pw->pw_prretained,top_x,top_y);
- reset_region();
- }
- else
- {
- ERROR("Select a region first, then select COPY.");
- panel_set(command_choice,PANEL_VALUE,SEL_REG,0);
- mouse_parms();
- }
- }
-
-
- /*
- * take the cut/paste buffer and XOR it that stuff on to the drawing area
- * so that I can move that sucker around FAST
- */
- move_region(old_x,old_y,new_x,new_y)
- int old_x,old_y,new_x,new_y;
- {
- if (cut_buffer_pr)
- {
- 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,new_x-cut_buffer_pr->pr_size.x/2,
- new_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);
- }
- else
- {
- ERROR("CUT or COPY a region first, then select MOVE.");
- }
- }
-
-
- /*
- * fill in a rectanglar region with the current paint pattern
- */
- fill_region(item, event)
- Panel_item item;
- Event *event;
- {
- if (top_x || top_y || bottom_x || bottom_y)
- {
- select_region(pw,top_x,top_y,bottom_x,bottom_y);
- region_fix();
- pw_replrop(pw,top_x,top_y,bottom_x-top_x,bottom_y-top_y,PIX_COLOR(cur_color) | PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],0,0);
- reset_region();
- }
- }
-
-
- /*
- * let the user lasso any free form region on the drawing area
- * and stuff that into the cut/paste buffer
- */
- laso_cut_paste()
- {
- int found;
- int i,no_points;
- int npts[1];
-
- top_x = image_wid;
- top_y = image_hgt;
- bottom_x = 0;
- bottom_y = 0;
-
- i=0;
- while ((i<MAX_PTS) && (ptlist[i++].x != -1));
- no_points = --i;
- npts[0] = no_points;
- pw_polygon_2(pw,0,0,1,npts,ptlist,PIX_XOR,pattern[0],0,0);
- pw_polygon_2(pw,0,0,1,npts,ptlist,PIX_XOR,pattern[0],0,0);
-
- for (i=0;i < no_points;i++)
- {
- top_x = MIN(top_x,ptlist[i].x);
- top_y = MIN(top_y,ptlist[i].y);
- bottom_x = MAX(bottom_x,ptlist[i].x);
- bottom_y = MAX(bottom_y,ptlist[i].y);
- if (i>0)
- pw_vector(pw,ptlist[i].x,ptlist[i].y,
- ptlist[i-1].x,ptlist[i-1].y,PIX_XOR,1);
- }
- for (i=0;i < no_points;i++)
- {
- ptlist[i].x -=top_x;
- ptlist[i].y -=top_y;
- }
- MY_pr_destroy(cut_buffer_pr);
- cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth);
- pr_polygon_2(cut_buffer_pr,0,0,1,npts,ptlist,PIX_SRC,pw->pw_prretained,top_x,top_y);
- reset_region();
- print_msg("The selected area is now in the Cut/Paste buffer.");
- }
-
-
- /*
- * the user can lasso any area on the screen by just encircling the
- * object on the bitmap
- * we do this by remembering all of the points the mouse moved to
- * and make a polygon stencil from these points
- */
- laso_addpt(py_pts,x,y)
- struct pr_pos py_pts[];
- int x,y;
- {
- int found;
- int i;
- int npts[1];
-
- found =0;
- i=0;
- while (i<MAX_PTS && !found)
- {
- if (py_pts[i++].x == -1)
- found=TRUE;
- }
- i--;
- npts[0] =i;
-
- py_pts[i].x = x;
- py_pts[i].y = y;
- if (i>0)
- pw_vector(pw,py_pts[i].x,py_pts[i].y,py_pts[i-1].x,py_pts[i-1].y,PIX_XOR,1);
- i++;
- py_pts[i].x = 0-1;
- py_pts[i].y = 0-1;
- }
-
-
- /*
- * add a point to the list of vetexs in the current polygon
- */
- poly_addpt(py_pts,x,y)
- struct pr_pos py_pts[];
- int x,y;
- {
- int found;
- int i;
-
- found =0;
- i=0;
- while (i<MAX_POLY && !found)
- {
- if (py_pts[i++].x == -1)
- found=TRUE;
- }
- i--;
- {
- py_pts[i].x = x;
- py_pts[i].y = y;
- i++;
- py_pts[i].x = 0-1;
- py_pts[i].y = 0-1;
- }
- }
-
-
- /*
- * take the list of currnet vertexs and draw up the
- * the polygon and fill it with the current paint pattern
- */
- draw_poly(py_pts)
- struct pr_pos py_pts[];
- {
- int npts[1];
- int found;
- int i;
-
- if (py_pts[0].x == 0-1)
- return(0);
-
- found =0;
- i=0;
- while (i<MAX_POLY && !found)
- {
- if (py_pts[i++].x == -1)
- found=TRUE;
- }
- i--;
-
- npts[0] =i;
-
- /*
- * do we want this baby filled ????
- */
- if ((int)panel_get_value(command_choice)==POLY_F)
- pw_polygon_2(pw,0,0,1,npts,py_pts,PIX_COLOR(cur_color) | PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],0,0);
-
- /*
- * do we want to wrap the polygon up in a vector border
- */
- if ((int)panel_get_value(border_cycle))
- {
- i=1;
- while (i<MAX_POLY && (py_pts[i].x != -1))
- {
- pw_vector(pw,py_pts[i].x,py_pts[i].y,
- py_pts[i-1].x,py_pts[i-1].y,PIX_SRC,cur_color);
- i++;
- }
- i--;
- pw_vector(pw,py_pts[i].x,py_pts[i].y,
- py_pts[0].x,py_pts[0].y,PIX_SRC,cur_color);
- }
- clean_poly();
- }
-
-
- /*
- * reset the vertex list for the current polygon
- */
- clean_poly()
- {
- poly_points[0].x = 0-1;
- poly_points[0].y = 0-1;
- }
-