Newsgroups: comp.sources.unix Subject: v15i062: A bitmap editor for Suns, Part05/06 Approved: rsalz@uunet.UU.NET Submitted-by: Raymond T Kreisel Posting-number: Volume 15, Issue 62 Archive-name: touchup/part05 THIS IS A COMPLETE REPOSTING OF THE ENTIRE PACKAGE. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh brush.c <<'END_OF_brush.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X X#include X X/************************************************************************** X file: brush.c X purpose: This file contains all that differents brush styles. X Brushes can be created with iconedit, using the upper X righthand 32x32 bits. The 64x64 image from iconedit X is then stripped to 32x32 by strip_icon32x32 X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X Xstatic short brush1_data[] = { X#include "brush1.icon.pat" X}; Xstatic mpr_static(brush1_pr, 32, 32, 1, brush1_data); X Xstatic short brush2_data[] = { X#include "brush2.icon.pat" X}; Xstatic mpr_static(brush2_pr, 32, 32, 1, brush2_data); X Xstatic short brush3_data[] = { X#include "brush3.icon.pat" X}; Xstatic mpr_static(brush3_pr, 32, 32, 1, brush3_data); X Xstatic short brush4_data[] = { X#include "brush4.icon.pat" X}; Xstatic mpr_static(brush4_pr, 32, 32, 1, brush4_data); X Xstatic short brush5_data[] = { X#include "brush5.icon.pat" X}; Xstatic mpr_static(brush5_pr, 32, 32, 1, brush5_data); X Xstatic short brush6_data[] = { X#include "brush6.icon.pat" X}; Xstatic mpr_static(brush6_pr, 32, 32, 1, brush6_data); END_OF_brush.c if test 2058 -ne `wc -c circle.c <<'END_OF_circle.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X X/************************************************************************** X file: circle.c X purpose: This file contains that routines that draw circles X on the screen. A UNDOCUMENTED Sunview function "pw_polypoint" X is used to get the list of points that make the circle X on to the screen AMAZINGLY FAST. X The points that make up the circle are calculated with X bresenhams (sp?) incremental circle algorithm. X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include "header.h" X Xstruct pr_pos ptlist[MAX_PTS]; X Xdraw_circle(pw, center_x,center_y, radius,ROP) Xint center_x,center_y; XPixwin *pw; Xint radius,ROP; X{ Xstruct pr_pos center; X X int x,y, X error, numpts; X X if (radius==0) return(0); X center.x = center_x; X center.y = center_y; X X x = 0; y = radius; numpts = 0; X error = 3 - (radius << 1); X X while (x < y) X { X ptlist[numpts].x=center.x+x; ptlist[numpts++].y=center.y+y; X ptlist[numpts].x=center.x-x; ptlist[numpts++].y=center.y+y; X ptlist[numpts].x=center.x+x; ptlist[numpts++].y=center.y-y; X ptlist[numpts].x=center.x-x; ptlist[numpts++].y=center.y-y; X ptlist[numpts].x=center.x+y; ptlist[numpts++].y=center.y+x; X ptlist[numpts].x=center.x-y; ptlist[numpts++].y=center.y+x; X ptlist[numpts].x=center.x+y; ptlist[numpts++].y=center.y-x; X ptlist[numpts].x=center.x-y; ptlist[numpts++].y=center.y-x; X X if (error < 0) X error = error + (x << 2) + 6; X else X error = error + ((x-y--) << 2) + 10; X x++; X } /* end of while (x , y) */ X X if (x == y) X { X ptlist[numpts].x=center.x+x; ptlist[numpts++].y=center.y+y; X ptlist[numpts].x=center.x-x; ptlist[numpts++].y=center.y+y; X ptlist[numpts].x=center.x+x; ptlist[numpts++].y=center.y-y; X ptlist[numpts].x=center.x-x; ptlist[numpts++].y=center.y-y; X } X X my_pw_polypoint(pw,0,0,numpts,ptlist,PIX_SET); X} /* end of function draw_circle() */ X X X Xmy_pw_polypoint(temp_pw,off_x,off_y,count_pts,ptlist, ROP) XPixwin *temp_pw; Xint off_x,off_y,count_pts; Xstruct pr_pos ptlist[]; Xint ROP; X{ X X if (image_depth > 1) X { X while(--count_pts > 0) X { X pw_rop(temp_pw,off_x+ptlist[count_pts].x,off_y+ptlist[count_pts].y,1,1 X ,PIX_COLOR(cur_color) | PIX_SRC ,pattern[0],0,0); X } X } X else X { X pw_polypoint(temp_pw,off_x,off_y,count_pts,ptlist,ROP); X } X} END_OF_circle.c if test 3577 -ne `wc -c cms_rainbow.c <<'END_OF_cms_rainbow.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file: cms_rainbow.c X purpose: this file contains that funciton that initalizes the X the default color table for color sun usage X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X Xextern unsigned char red[256],green[256],blue[256]; X Xset_colorentry(i, r, g, b) X{ X red[i] =r; X green[i] =g; X blue[i]=b; X} X X X Xvoid init_colortable() X X{ X int i, red, green, blue; X set_colorentry(0, 255, 255, 255); /* white */ X set_colorentry(1, 0, 0, 0); /* black */ X red = blue = green = 0; X X for (i = 2; i < 30; i++) { X red += 9; X set_colorentry(i, red, green, blue); X } X set_colorentry(30, 255, 0, 0); /* red */ X red = 255; blue = green = 0; X for (i = 30; i < 62; i++) { X green += 6; X set_colorentry(i, red, green, blue); X } X set_colorentry(62, 255, 195, 0); /* orange */ /* note diff = 33 */ X red = 255; blue = 0; green = 195; X for (i = 63; i < 96; i++) { X green += 2; X set_colorentry(i, red, green, blue); X } X set_colorentry(96, 255, 255, 0); /* yellow */ X red = 255; blue = 0; green = 255; X for (i = 97; i < 133; i++) { X red -= 7; X set_colorentry(i, red, green, blue); X } X set_colorentry(133, 0, 255, 0); /* green */ X red = blue = 0; green = 255; X for (i = 134; i < 165; i++) { X green -= 8; X blue += 8; X set_colorentry(i, red, green, blue); X } X set_colorentry(165, 0, 0, 255); /* blue */ X red = green = 0; blue = 255; X for (i = 165; i < 202; i++) { X red += 7; X set_colorentry(i, red, green, blue); X } X set_colorentry(202, 255, 0, 255); /* violet */ X red = blue = 255; green = 0; X for (i = 203; i < 239; i++) { X green += 7; X set_colorentry(i, red, green, blue); X } X set_colorentry(239, 255, 255, 255); /* white */ X red = blue = green = 255; X for (i = 239; i <= 255; i++) { X green -= 9; X red -= 9; X blue -= 9; X set_colorentry(i, red, green, blue); X } X} X END_OF_cms_rainbow.c if test 2886 -ne `wc -c color_palet.c <<'END_OF_color_palet.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file:color_palet.c X purpose: This file contains that functions that handle the color X map for usage with color suns X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include "header.h" X#include X X/* X * Lets go into color mode, scotty X * X */ Xset_color() X{ X panel_set(mono_cycle,PANEL_SHOW_ITEM, FALSE,0); X panel_set(color_button,PANEL_SHOW_ITEM, TRUE,0); X} X X X/* X * Back to mono mode X * X */ Xset_mono() X{ X/* set the color map to mono ******** */ X cms_monochromeload(red,green,blue); X my_put_colormap(); X panel_set(color_button,PANEL_SHOW_ITEM, FALSE,0); X panel_set(mono_cycle,PANEL_SHOW_ITEM, TRUE,0); X} X X/* X * Set the colormap for all of the windows X */ Xunsigned char temp_red[256],temp_green[256],temp_blue[256]; X Xmy_put_colormap() X{ XPixwin *temp_pw; X X pw_setcmsname(pw, "ray kreisel"); X pw_putcolormap(pw, 0,256,red,green,blue); X pw_setcmsname(fat_pw, "ray kreisel"); X pw_putcolormap(fat_pw, 0,256,red,green,blue); X pw_setcmsname(color_pw, "ray kreisel"); X pw_putcolormap(color_pw, 0,256,red,green,blue); X X bcopy(red,temp_red,256); X bcopy(green,temp_green,256); X bcopy(blue,temp_blue,256); X temp_red[0] = -1; X temp_green[0] = -1; X temp_blue[0] = -1; X temp_red[1] = 0; X temp_green[1] = 0; X temp_blue[1] = 0; X X temp_pw = (Pixwin *)window_get(panel, WIN_PIXWIN); X pw_setcmsname(temp_pw, "ray kreisel"); X pw_putcolormap(temp_pw, 0,256,red,green,blue); X X temp_pw = (Pixwin *)window_get(command_panel, WIN_PIXWIN); X pw_setcmsname(temp_pw, "ray kreisel"); X pw_putcolormap(temp_pw, 0,256,red,green,blue); X X temp_pw = (Pixwin *)window_get(region_panel, WIN_PIXWIN); X pw_setcmsname(temp_pw, "ray kreisel"); X pw_putcolormap(temp_pw, 0,256,red,green,blue); X X temp_pw = (Pixwin *)window_get(pattern_panel, WIN_PIXWIN); X pw_setcmsname(temp_pw, "ray kreisel"); X pw_putcolormap(temp_pw, 0,256,red,green,blue); X X temp_pw = (Pixwin *)window_get(brush_panel, WIN_PIXWIN); X pw_setcmsname(temp_pw, "ray kreisel"); X pw_putcolormap(temp_pw, 0,256,red,green,blue); X X} X Xcolor_mode(item, event) XPanel_item item; XEvent *event; X{ X (void)window_set(color_frame, WIN_SHOW, TRUE, 0); X draw_colormap(); X} X X X/* X * Draw the colormap up on a canvas in the color palet window X */ Xdraw_colormap() X{ Xint i; X for (i=0;i<256;i++) X pw_write(color_pw,(i%16)*PALET_BLOCK,i/16*PALET_BLOCK,PALET_BLOCK,PALET_BLOCK,PIX_COLOR(i) | PIX_SRC,NILPR,0,0); X update_cur_color(0,0,cur_color); X} X X X X/* X * Get rid of the color palet X */ Xcolor_done(item, event) XPanel_item item; XEvent *event; X{ X (void)window_set(color_frame, WIN_SHOW, FALSE, 0); X} X X X/* X * Make an event handle for the mouse envent of the color palet X * Let the use pick a block on the color palet and set the current X * color a cordingly X */ Xcolor_handle_event(canvas_local, event, arg) XCanvas canvas_local; XEvent *event; Xcaddr_t arg; X{ X if (event_is_up(event)) X return; X switch (event_id(event)) { X case MS_LEFT: X update_cur_color(event_x(event),event_y(event),0); X break; X } X} X X X/* X * Redraw the currrent color at the bottom of the color palet X */ Xupdate_cur_color(x,y,value) X{ X if (value) X { X cur_color= value; X } X else X { X if ((x >= PALET_BLOCK*16) || (y >= PALET_BLOCK*16)) X return(0); X cur_color = x/PALET_BLOCK + y/PALET_BLOCK*16; X } X pw_write(color_pw,0,PALET_BLOCK*16+8,PALET_BLOCK*16,PALET_BLOCK*2,PIX_COLOR(cur_color) | PIX_SRC,NILPR,0,0); X} X END_OF_color_palet.c if test 4455 -ne `wc -c command.c <<'END_OF_command.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X X/************************************************************************** X file: command.c X purpose: This file contains the icon data for the command icons X in the command menu of the righthand side of the main window X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X#include X X Xstatic short command1_data[] = { X#include "laso.cicon.pat" X}; Xstatic mpr_static(command1_pr, 48, 48, 1, command1_data); X Xstatic short command2_data[] = { X#include "circle_h.cicon.pat" X}; Xstatic mpr_static(command2_pr, 48, 48, 1, command2_data); X Xstatic short command3_data[] = { X#include "draw.cicon.pat" X}; Xstatic mpr_static(command3_pr, 48, 48, 1, command3_data); X Xstatic short command4_data[] = { X#include "line.cicon.pat" X}; Xstatic mpr_static(command4_pr, 48, 48, 1, command4_data); X Xstatic short command5_data[] = { X#include "mag.cicon.pat" X}; Xstatic mpr_static(command5_pr, 48, 48, 1, command5_data); X Xstatic short command6_data[] = { X#include "ffill.cicon.pat" X}; Xstatic mpr_static(command6_pr, 48, 48, 1, command6_data); X Xstatic short command7_data[] = { X#include "oval_h.cicon.pat" X}; Xstatic mpr_static(command7_pr, 48, 48, 1, command7_data); X Xstatic short command8_data[] = { X#include "poly_f.cicon.pat" X}; Xstatic mpr_static(command8_pr, 48, 48, 1, command8_data); X Xstatic short command9_data[] = { X#include "poly_h.cicon.pat" X}; Xstatic mpr_static(command9_pr, 48, 48, 1, command9_data); X Xstatic short command10_data[] = { X#include "rectan_f.cicon.pat" X}; Xstatic mpr_static(command10_pr, 48, 48, 1, command10_data); X Xstatic short command11_data[] = { X#include "rectan_h.cicon.pat" X}; Xstatic mpr_static(command11_pr, 48, 48, 1, command11_data); X Xstatic short command12_data[] = { X#include "text.cicon.pat" X}; Xstatic mpr_static(command12_pr, 48, 48, 1, command12_data); X Xstatic short command13_data[] = { X#include "sel_reg.cicon.pat" X}; Xstatic mpr_static(command13_pr, 48, 48, 1, command13_data); X Xstatic short command14_data[] = { X#include "sel_point.cicon.pat" X}; Xstatic mpr_static(command14_pr, 48, 48, 1, command14_data); X Xstatic short command15_data[] = { X#include "paint.cicon.pat" X}; Xstatic mpr_static(command15_pr, 48, 48, 1, command15_data); X Xstatic short command16_data[] = { X#include "erase.cicon.pat" X}; Xstatic mpr_static(command16_pr, 48, 48, 1, command16_data); X X/* SELECTED REGION COMMANDS */ X Xstatic short reg_command1_data[] = { X#include "cut.cicon.pat" X}; Xstatic mpr_static(reg_command1_pr, 48, 48, 1, reg_command1_data); X Xstatic short reg_command2_data[] = { X#include "flip_hor.cicon.pat" X}; Xstatic mpr_static(reg_command2_pr, 48, 48, 1, reg_command2_data); X Xstatic short reg_command3_data[] = { X#include "flip_ver.cicon.pat" X}; Xstatic mpr_static(reg_command3_pr, 48, 48, 1, reg_command3_data); X Xstatic short reg_command4_data[] = { X#include "inverse.cicon.pat" X}; Xstatic mpr_static(reg_command4_pr, 48, 48, 1, reg_command4_data); X Xstatic short reg_command5_data[] = { X#include "copy.cicon.pat" X}; Xstatic mpr_static(reg_command5_pr, 48, 48, 1, reg_command5_data); X Xstatic short reg_command6_data[] = { X#include "paste.cicon.pat" X}; Xstatic mpr_static(reg_command6_pr, 48, 48, 1, reg_command6_data); X Xstatic short reg_command7_data[] = { X#include "rotate.cicon.pat" X}; Xstatic mpr_static(reg_command7_pr, 48, 48, 1, reg_command7_data); X X Xstatic short reg_command8_data[] = { X#include "move.cicon.pat" X}; Xstatic mpr_static(reg_command8_pr, 48, 48, 1, reg_command8_data); END_OF_command.c if test 4366 -ne `wc -c confirmer.c <<'END_OF_confirmer.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file: confirmer.c X purpose: This file contains a simple confirmer copied from the X Sunview manual that has been souped up a little X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include X#include X#include X#include X#include X#include X#include X#include X#include X Xextern Panel panel; X Xstatic Frame init_confirmer(); Xstatic void yes_no(); X X/*************************************************************** X confirm X purpose: To display a window on the base_frame Sunwindow X force the user to answer the question by selecting X either YES or NO X parameter: X message: The question to asked. X returns: X 1 : if the user answered YES X 0 : if the user answered NO X ***************************************************************/ Xint confirm(message) Xchar *message; X{ X Frame confirmer; X int answer; X X/* create the confirmer */ X confirmer = init_confirmer(message); X window_bell(panel); X/* make the user answer */ X answer = (int) window_loop(confirmer); X X/* destroy the confirmer */ X window_set(confirmer, FRAME_NO_CONFIRM, TRUE, 0); X window_destroy(confirmer); X X return answer; X} X Xstatic Frame Xinit_confirmer(message) Xchar *message; X{ Xextern Frame base_frame; XFrame confirmer; XPanel panel; XPanel_item message_item; Xint left, top, width, height; XRect *r; Xstruct pixrect *pr; X X/* create the confirmer base frame */ X confirmer = window_create(base_frame, FRAME, X FRAME_SHOW_LABEL, FALSE, X 0); X X/* create the single panel subwindow */ X panel = window_create(confirmer, PANEL, 0); X X/* put in the message */ X message_item = panel_create_item(panel, PANEL_MESSAGE, X PANEL_LABEL_STRING, message, X 0); X X pr = panel_button_image(panel, "NO", 3, 0); X width = 2 * pr->pr_width + 10; X X r = (Rect *) panel_get(message_item, PANEL_ITEM_RECT); X X/* center the yes/no buttons under the message */ X left = (r->r_width - width) / 2; X if (left < 0) X left = 0; X top = rect_bottom(r) + 5; X X panel_create_item(panel, PANEL_BUTTON, X PANEL_ITEM_X, left, X PANEL_ITEM_Y, top, X PANEL_LABEL_IMAGE, pr, X PANEL_CLIENT_DATA, FALSE, X PANEL_NOTIFY_PROC, yes_no, X 0); X X panel_create_item(panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, panel_button_image(panel, "YES", 3, 0), X PANEL_CLIENT_DATA, TRUE, X PANEL_NOTIFY_PROC, yes_no, X 0); X X X window_fit(panel); X window_fit(confirmer); X X/* center the confirmer frame in the base frame */ X r = (Rect *) window_get(base_frame, WIN_RECT); X X width = (int) window_get(confirmer, WIN_WIDTH); X height = (int) window_get(confirmer, WIN_HEIGHT); X X left = (r->r_width - width) / 2; X top = (r->r_height - height) / 3; X X if (left < 0) X left = 0; X if (top < 0) X top = 0; X X window_set(confirmer, WIN_X, left, WIN_Y, top, X 0); X X left = left + (width - width/3); X top = top + height / 2; X window_set(base_frame, WIN_MOUSE_XY, left, top, 0); X X return confirmer; X} X X/* yes/no notify proc */ Xstatic void Xyes_no(item, event) XPanel_item item; XEvent *event; X{ X window_return(panel_get(item, PANEL_CLIENT_DATA)); X} X END_OF_confirmer.c if test 4328 -ne `wc -c disk_io.c <<'END_OF_disk_io.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file: disk_io.c X purpose: This file handle most of the file I/O stuff X mostly load, save and file completion X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include "header.h" X X#include X#include X#include X#include X Xcolormap_t colormap; X X/* X * Let's do file completion on what we have in the file name prompt X */ Xmake_new_name(item, event) XPanel_item item; XEvent *event; X{ X strcpy(file_name,(char*)panel_get_value(file_panel)); X if (complete(file_name)) X window_bell(panel); X panel_set(file_panel,PANEL_VALUE,file_name,0); X} X X X/* This function, written by Marc J Newberger, X * will do both login name completion and file name completion, DAM fast. X * That means as fast as the csh does it. X */ Xint complete(template) X X char *template; X X{ X X char dirName[255]; X char *prefix; X int pref_len; X char *suffix; X char *p, *q; X char first; X char nonUnique; X char twiddleUserCompletion; X X extern int errno; X struct direct *nameEntry; X DIR *dirChan; X struct passwd *pwdEntry; X X /* X * First do a little parsing of the input. Separate the X * prefix template from the directory if there is one. X */ X twiddleUserCompletion= 0; X prefix= template+strlen(template); X while (*(--prefix) != '/' && prefix >= template); X X /* X * See if a directory was specified: X */ X if (prefix < template) { X /* X * No /'s, could be either a username completion or X * a completion in the current directory. X */ X if (template[0] == '~') { X prefix++; X twiddleUserCompletion= 1; X } X else { X strcpy(dirName, "."); X } X } X else if (prefix == template) { X /* X * Special case !! The directory excluding the trailing X * '/' is zero length. It's the root: X */ X strcpy(dirName, "/"); X } X else { X /* X * We're completing a file in a directory. X * The directory may be lead by a ~ abbreviation. X * If that's the case expand it. X */ X if (template[0] == '~') { X /* X * We need to do twiddle directory expansion. X * See if it's our directory: X */ X if (template[1] == '/') { X strcpy(dirName, getenv("HOME")); X if ( &template[1] != prefix ) X { X p= dirName+strlen(dirName); X q= &template[1]; X while (q < prefix) { X *p= *q; X p++, q++; X } X *p= 0; X } X } X else { X /* X * It's someone else's. Let our fingers X * do the walking. (Why the fuck do they call it X * the "yellow pages" anyway. They're white pages X * dammit ! If they were YELLOW pages, we could X * say ypmatch "Automobile, Dealers, Retail", and X * things like that !). X */ X for (p= dirName, q= &template[1]; X (*p= *q) != '/'; X p++, q++); X *p= 0; X if (!(pwdEntry= getpwnam(dirName))) { X return errno; X } X strcpy(dirName, pwdEntry->pw_dir); X p= dirName+strlen(dirName); X while (q < prefix) { X *p= *q; X p++, q++; X } X *p= 0; X } X } X else { X /* X * It's a vanilla directory. Strip it out. X */ X strncpy(dirName, template, prefix-template); X dirName[prefix-template]= 0; X } X } X /* X * Bump prefix past the '/'. X */ X prefix++; X X /* X * Get the prefix length and a pointer to the end of the X * prefix. X */ X pref_len= strlen(prefix); X suffix= template + strlen(template); X X /* X * See whether we're doing filename or username completion: X */ X if (!twiddleUserCompletion) { X X /* X * It's filename completion. Read through the directory: X */ X if ((dirChan= opendir(dirName)) == 0) { X return errno; X } X X first= 1; X nonUnique= 0; X for (;;) { X if (!(nameEntry= readdir(dirChan))) { X break; X } X if (!strncmp(prefix, nameEntry->d_name, pref_len)) { X /* X * We have a file that matches the template. X * If it's the first one, we fill the completion X * suffix with it. Otherwise we scan and pare down X * the suffix. X */ X if (first) { X first= 0 ; X strcpy(suffix, nameEntry->d_name+pref_len); X } X else { X nonUnique= 1; X p= suffix; X q= nameEntry->d_name+pref_len; X while (*p == *q) { X ++p; ++q; X } X *p= 0; X X /* X * A little optimization: If p == suffix, we X * were unable to do any extension of the name. X * We might as well quit here. X */ X if (p == suffix) { X break; X } X } X } X } X X closedir(dirChan); X } X else { X /* X * Do ~Username completion. Start by resetting the passwd file. X */ X setpwent(); X X first= 1; X nonUnique= 0; X for (;;) { X if (!(pwdEntry= getpwent())) { X break; X } X if (!strncmp(prefix, pwdEntry->pw_name, pref_len)) { X /* X * We have a user that matches the template. X * If it's the first one, we fill the completion X * suffix with it. Otherwise we scan and pare down X * the suffix. X */ X if (first) { X first= 0 ; X strcpy(suffix, pwdEntry->pw_name+pref_len); X } X else { X p= suffix; X q= pwdEntry->pw_name+pref_len; X while (*p == *q) { X ++p; ++q; X } X X /* X * Here there is a possibility of seeing the X * same username twice. For this reason, we X * only set nonUnique to 1 if we're shortening X * the suffix. This means that the new name is X * distinct from any name we've seen. X */ X if (*p) { X nonUnique= 1; X *p= 0; X } X X /* X * A little optimization: If p == suffix, we X * were unable to do any extension of the name. X * We might as well quit here. X */ X if (p == suffix) { X break; X } X } X } X } X } X X /* X * If nothing matched, return a -1, if there was non-uniqueness X * return -2. X */ X if (first) { X return -1; X } X else if (nonUnique) { X return -2; X } X else { X return 0; X } X X} X X X/* X * We just got a "load" button event and we want to load in the current X * filename. X */ Xload_file(item, event) XPanel_item item; XEvent *event; X{ XFILE *fp,*fopen(); Xint err=0; Xstruct rasterfile file_header; Xint load_area; Xchar temp_file[MAX_FILE_NAME]; X X /* X * Copy the current filename and expand the ~ if it is there X */ X strcpy(temp_file,(char*)panel_get_value(file_panel)); X get_full_path(temp_file,file_name); X load_area = (int)panel_get_value(load_cycle); X X fp = fopen(file_name,"r"); X if (fp == NULL) X { X ERRORstr("Cannot open file: ",file_name); X fclose(fp); X return(0); X } X X /* X * Try to read the header of the raster file and check if it is color X */ X err = pr_load_header(fp,&file_header); X if (file_header.ras_maplength > 3*256) err=1; X if (err) X { X ERROR("Cannot load the rasterfile header."); X fclose(fp); X return(0); X } X X if (load_area == LOAD_ALL) X { X clear_screen(); X colormap.map[0] = red; X colormap.map[1] = green; X colormap.map[2] = blue; X colormap.type = file_header.ras_maptype; X colormap.length = file_header.ras_maplength/3; X } X /* X * load in the colormap for the raster file X */ X if (pr_load_colormap(fp,&file_header,&colormap)) X { X ERROR("Cannot load the rasterfile colormap."); X fclose(fp); X return(0); X } X /* X * reset the memory pixrect and load the baby in X */ X MY_pr_destroy(undo_pr); X undo_pr = (struct pixrect *)pr_load_image(fp,&file_header,&colormap); X X if (undo_pr == NULL) X { X ERROR("Cannot allocate pixrect for loaded image file, not enough memory!"); X fclose(fp); X return(0); X } X X fclose(fp); X X X /* X * We are loading to the main drawing area so lets set all X * the color maps X */ X if (load_area == LOAD_ALL) X { X if (file_header.ras_depth > 1) X { X my_put_colormap(); X set_color(); X } X else X { X set_mono(); X (void)window_set(canvas, X CANVAS_WIDTH, file_header.ras_width, X CANVAS_HEIGHT, file_header.ras_height, X 0); X } X panel_set(save_cycle,PANEL_VALUE, SAVE_ALL,0); X image_wid = file_header.ras_width; X image_hgt = file_header.ras_height; X image_depth = file_header.ras_depth; X pw_write(pw,0,0, image_wid,image_hgt, PIX_SRC, undo_pr,0,0); X } X else X { X /* X * we load the image into the cut/paste buffer X */ X MY_pr_destroy(cut_buffer_pr); X cut_buffer_pr = my_mem_create(file_header.ras_width,file_header.ras_height,file_header.ras_depth); X pr_rop(cut_buffer_pr,0,0,file_header.ras_width,file_header.ras_height, X PIX_SRC,undo_pr,0,0); X MY_pr_destroy(undo_pr); X undo_pr = my_mem_create(image_wid,image_hgt,image_depth); X } X} X X X X/* X * Save a file out out to the current filename X * X */ Xsave_file(item, event) XPanel_item item; XEvent *event; X{ XFILE *fp,*fopen(); Xint type = RT_STANDARD; Xint copy_flag = TRUE; Xchar temp_file[MAX_FILE_NAME]; X X /* X * Is the raster file to be run-length encode or not X */ X if((int)panel_get_value(compress_cycle)) X type = RT_BYTE_ENCODED; X else X type = RT_STANDARD; X X /* X * Copy the current filename and expand the ~ if it is there X */ X strcpy(temp_file,(char*)panel_get_value(file_panel)); X get_full_path(temp_file,file_name); X if (file_exist(file_name)) X { X if (!confirm("Over write existing file ?")) X return(0); X } X /* X * dump standard SUN raster file with color table to disk file X */ X fp = fopen(file_name,"w"); X if (fp == NULL) X { X fclose(fp); X ERRORstr("Cannot write to file: ",file_name); X return(0); X } X /* X * Save the whole drawing are out to the disk file X */ X if (SAVE_ALL == (int)panel_get_value(save_cycle)) X { X clean_point(); X clean_region(); X fat_done(); X save_screen(); X X if (!undo_pr) X undo_pr = my_mem_create(image_wid,image_hgt,image_depth); X pr_rop(undo_pr,0,0,image_wid,image_hgt,PIX_SRC,pw->pw_prretained,0,0); X pr_dump(undo_pr,fp,&colormap,type,copy_flag); X } X else X { X /* X * just save the cut/Paste buffer out to the file X */ X if (cut_buffer_pr == NULL) X { X ERROR("The Cut/Paste buffer is empty"); X fclose(fp); X return(0); X } X pr_dump(cut_buffer_pr,fp,&colormap,type,copy_flag); X } X fclose(fp); X} X X X/* X * Check if a file exist or not X */ Xfile_exist(file_name) Xchar *file_name; X{ XFILE *fp; X fp = fopen(file_name,"r"); X fclose(fp); X if (fp != NULL) X return(TRUE); X else X return(FALSE); X} X X X/* X * Take a filename with a ~ character at the begining and return X * the full path name to that file X */ Xget_full_path(template,full_path) Xchar template[]; Xchar full_path[]; X{ X char *p, *q; X struct passwd *pwdEntry; X /* X * We're completing a file in a directory. X * The directory may be lead by a ~ abbreviation. X * If that's the case expand it. X */ X if (template[0] == '~') { X /* X * We need to do twiddle directory expansion. X * See if it's our directory: X */ X if (template[1] == '/') { X strcpy(full_path, getenv("HOME")); X strcat(full_path,&template[1]); X } X else { X /* X * It's someone else's. Let our fingers X * do the walking. (Why the fuck do they call it X * the "yellow pages" anyway. They're white pages X * dammit ! If they were YELLOW pages, we could X * say ypmatch "Automobile, Dealers, Retail", and X * things like that !). X */ X for (p= full_path, q= &template[1]; X (*p= *q) != '/'; X p++, q++); X *p= 0; X if (!(pwdEntry= getpwnam(full_path))) { X return errno; X } X strcpy(full_path, pwdEntry->pw_dir); X strcat(full_path,q); X } X } X else X strcpy(full_path,template); X} X END_OF_disk_io.c if test 14884 -ne `wc -c drawing.c <<'END_OF_drawing.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file: drawing.c X purpose: This file has most of the functions that draw stuff X on the screen. X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include"header.h" X Xstruct pr_pos poly_points[MAX_POLY]; X Xstruct pixrect *brush_temp_pr = NULL; X X/* X * What we do that someone selects a new pattern X */ Xselect_pattern(item, event) XPanel_item item; XEvent *event; X{ X panel_set(current_pattern,PANEL_LABEL_IMAGE,pattern[(int)panel_get_value(pattern_choice)],0); X X} X X X/* X * let the user define his own patterns to paint with X * works for color and mono X */ Xpattern_define(item, event) XPanel_item item; XEvent *event; X{ X X if (select_pt_x == -1) X { X ERROR("Select a point first, then select Define Pattern."); X set_select_mode(); X return(0); X } X select_point(select_pt_x,select_pt_y); X if (image_depth > 1) X { X pattern[39] = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,image_depth); X pattern40_pr = *(pattern[39]); X } X pr_rop(pattern[39],0,0,PATTERN_SIZE,PATTERN_SIZE, X PIX_SRC,pw->pw_prretained,select_pt_x-PATTERN_SIZE/2, X select_pt_y-PATTERN_SIZE/2); X X panel_paint(pattern_choice,PANEL_NO_CLEAR); X reset_point(); X print_msg("The user defined pattern is now stored in the last pattern element."); X} X X X/* X * Take the current text string and put that Baby up on the bitmap X * in the right font X */ Xdraw_text() X{ Xint x,y; X X if (select_pt_x != -1) X { X x = select_pt_x; X y = select_pt_y; X clean_point(); X save_screen(); X pw_text(pw,x,y,PIX_COLOR(cur_color) | PIX_SRC,font_array[(int)panel_get_value(text_size_item)], X (char*)panel_get_value(text_panel)); X } X else X { X ERROR("Select a point first, fill in TEXT STRING, then select ABC."); X window_set(panel,PANEL_CARET_ITEM,text_panel,0); X set_select_mode(); X } X} X X X/* X * draw a line on the bitmap X */ Xdraw_line(x1,y1,x2,y2,ROP,color) Xint x1,y1,x2,y2,ROP,color; X{ X pw_vector(pw,x1,y1,x2,y2,ROP,color); X} X X X/* X * draw a rectangle on the bitmap X */ Xdraw_rectangle(x1,y1,x2,y2) Xint x1,y1,x2,y2; X{ X top_x = x1; X top_y = y1; X bottom_x = x2; X bottom_y = y2; X if ((int)panel_get_value(command_choice)==RECT_F) X fill_region(); X else X reset_region(); X if ((int)panel_get_value(border_cycle)) X { X pw_vector(pw,x1,y1,x2,y1,PIX_SRC,cur_color); X pw_vector(pw,x2,y1,x2,y2,PIX_SRC,cur_color); X pw_vector(pw,x2,y2,x1,y2,PIX_SRC,cur_color); X pw_vector(pw,x1,y2,x1,y1,PIX_SRC,cur_color); X } X} X X X/* X * highlight the selected region on the drawing area by throwing up a X * XORed rectangle X */ Xselect_region(pw,x1,y1,x2,y2) Xstruct pixwin *pw; Xint x1,y1,x2,y2; X{ X pw_vector(pw,x1,y1,x2,y1,PIX_XOR,1); X pw_vector(pw,x2,y1,x2,y2,PIX_XOR,1); X pw_vector(pw,x2,y2,x1,y2,PIX_XOR,1); X pw_vector(pw,x1,y2,x1,y1,PIX_XOR,1); X} X X X/* X * reset the current REGION X */ Xreset_region() X{ X top_x=0; X top_y=0; X bottom_x=0; X bottom_y=0; X} X X X/* X * draw up a point, how stupid ??? X */ Xdraw_point(pw,x,y) Xstruct pixwin *pw; Xint x,y; X{ X pw_put(pw,x,y,cur_color); X} X X X/* X * Draw up the paint brush by copying the current pattern X * through a stencil of the current brush X */ Xdraw_brush(pw,x,y) Xstruct pixwin *pw; Xint x,y; X{ X if (brush_temp_pr == NULL) X brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,1); X X X if (((int)panel_get_value(pattern_choice) != 39) || (image_depth == 1)) X { X if (brush_temp_pr->pr_depth != 1) X { X MY_pr_destroy(brush_temp_pr); X brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,1); X } X pr_replrop(brush_temp_pr,0,0,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],x,y); X pw_stencil(pw,x-PATTERN_SIZE/2,y-PATTERN_SIZE/2,PATTERN_SIZE,PATTERN_SIZE,PIX_COLOR(cur_color) | PIX_SRC, X brushes[(int)panel_get_value(brush_choice)],0,0,brush_temp_pr,0,0); X } X else X { X if (brush_temp_pr->pr_depth != image_depth) X { X MY_pr_destroy(brush_temp_pr); X brush_temp_pr = my_mem_create(PATTERN_SIZE,PATTERN_SIZE,image_depth); X } X pr_replrop(brush_temp_pr,0,0,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,pattern[(int)panel_get_value(pattern_choice)],x,y); X pw_stencil(pw,x-PATTERN_SIZE/2,y-PATTERN_SIZE/2,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC, X brushes[(int)panel_get_value(brush_choice)],0,0,brush_temp_pr,0,0); X X } X X} X X X/* X * flip-flop two varibles (ints) X */ Xswap(x,y) Xint *x,*y; X{ Xint temp; X temp = *x; X *x = *y; X *y = temp; X} X X Xregion_fix() X{ X if (top_x > bottom_x) X swap(&top_x,&bottom_x); X if (top_y > bottom_y) X swap(&top_y,&bottom_y); X} X X X/* X * put the eraser on the drawing area X */ Xerase_brush(pw,x,y) Xstruct pixwin *pw; Xint x,y; X{ X select_region(pw,top_x,top_y,top_x+PATTERN_SIZE,top_y+PATTERN_SIZE); X pw_rop(pw,x-PATTERN_SIZE/2,y-PATTERN_SIZE/2,PATTERN_SIZE,PATTERN_SIZE, PIX_SRC,0,0,0); X top_x = x-PATTERN_SIZE/2; top_y= y-PATTERN_SIZE/2; X select_region(pw,top_x,top_y,top_x+PATTERN_SIZE,top_y+PATTERN_SIZE); X} X X X/* X * draw up some cross hairs to be used to select a point X */ X#define CROSS_HAIR 20 Xselect_point(x,y) Xint x,y; X{ X pw_vector(pw,x-CROSS_HAIR,y,x+CROSS_HAIR,y,PIX_XOR,1); X pw_vector(pw,x,y-CROSS_HAIR,x,y+CROSS_HAIR,PIX_XOR,1); X} X X X/* X * reset the currently selected point X */ Xreset_point() X{ X select_pt_x = 0-1; X select_pt_y = 0-1; X} X X X/* X * take a currently selected region and invert that baby ! FAST !!! X */ Xinverse_region() X{ X if (top_x || top_y || bottom_x || bottom_y) X { X select_region(pw,top_x,top_y,bottom_x,bottom_y); X region_fix(); X pw_replrop(pw,top_x,top_y,bottom_x-top_x,bottom_y-top_y, PIX_XOR, pattern[0],0,0); X select_region(pw,top_x,top_y,bottom_x,bottom_y); X } X else X { X ERROR("Select a region first, then select INVERSE."); X panel_set(command_choice,PANEL_VALUE,SEL_REG,0); X mouse_parms(); X } X} X X X X/* X * take a currently selected region and rotate around the center X * point. SLOW !! X */ Xrotate_region() X{ Xregister i,j,t1,t2; X X if (top_x || top_y || bottom_x || bottom_y) X { X select_region(pw,top_x,top_y,bottom_x,bottom_y); X region_fix(); X MY_pr_destroy(cut_buffer_pr); X cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth); X pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y, X PIX_SRC,pw->pw_prretained,top_x,top_y); X t1 = top_x + cut_buffer_pr->pr_size.x/2+ cut_buffer_pr->pr_size.y/2; X t2 = top_y - cut_buffer_pr->pr_size.x/2+ cut_buffer_pr->pr_size.y/2; X for (j = 0; j < cut_buffer_pr->pr_size.y; j++) X for (i = 0; i < cut_buffer_pr->pr_size.x; i++) X pw_rop(pw, t1-j, t2+i, 1,1, PIX_SRC, cut_buffer_pr,i,j); X X top_x = top_x + cut_buffer_pr->pr_size.x/2 - cut_buffer_pr->pr_size.y/2; X top_y = top_y - cut_buffer_pr->pr_size.x/2 + cut_buffer_pr->pr_size.y/2; X bottom_x = top_x + cut_buffer_pr->pr_size.y; X bottom_y = top_y + cut_buffer_pr->pr_size.x; X select_region(pw,top_x,top_y,bottom_x,bottom_y); X } X else X { X ERROR("Select a region first, then select ROTATE."); X panel_set(command_choice,PANEL_VALUE,SEL_REG,0); X mouse_parms(); X } X} X X X X/* X * take a currently selected region and make a mirror image of it X */ Xflip_hor_region() X{ Xregister i; X if (top_x || top_y || bottom_x || bottom_y) X { X select_region(pw,top_x,top_y,bottom_x,bottom_y); X region_fix(); X MY_pr_destroy(cut_buffer_pr); X cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth); X pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y, X PIX_SRC,pw->pw_prretained,top_x,top_y); X for (i = 0; i < cut_buffer_pr->pr_size.x; i++) { X pw_rop(pw, top_x+(cut_buffer_pr->pr_size.x - i)-1,top_y, X 1,cut_buffer_pr->pr_size.y, PIX_SRC, cut_buffer_pr,i,0); X } X select_region(pw,top_x,top_y,bottom_x,bottom_y); X } X else X { X ERROR("Select a region first, then select MIRROR."); X panel_set(command_choice,PANEL_VALUE,SEL_REG,0); X mouse_parms(); X } X} X X X/* X * take a currently selected region and turn it upside down X */ Xflip_ver_region() X{ Xregister i; X if (top_x || top_y || bottom_x || bottom_y) X { X select_region(pw,top_x,top_y,bottom_x,bottom_y); X region_fix(); X MY_pr_destroy(cut_buffer_pr); X cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth); X pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y, X PIX_SRC,pw->pw_prretained,top_x,top_y); X for (i = 0; i < cut_buffer_pr->pr_size.y; i++) { X pw_rop(pw, top_x, top_y+(cut_buffer_pr->pr_size.y - i)-1, X cut_buffer_pr->pr_size.x, 1, PIX_SRC, cut_buffer_pr, 0, i); X } X select_region(pw,top_x,top_y,bottom_x,bottom_y); X } X else X { X ERROR("Select a region first, then select FLIP VERTICAL."); X panel_set(command_choice,PANEL_VALUE,SEL_REG,0); X mouse_parms(); X } X} X X X X/* X * grab what is in the Cut/Paste buffer and put it up on the drawing area X */ Xpaste_region() X{ Xint ROP=PIX_SRC; X X if (select_pt_x == -1) X { X ERROR("Select a point first, then select PASTE."); X set_select_mode(); X return(0); X } X if (cut_buffer_pr) X { X select_point(select_pt_x,select_pt_y); X save_screen(); X 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); X reset_point(); X } X else X ERROR("The Cut/Paste buffer is empty."); X} X X X/* X * grab the currently selected region on the drawing area and stuff X * it into the cut/paste buffer AND destroy the source area by X * filling in with the current paint pattern X */ Xcut_region() X{ Xint t1,t2,t3,t4; X if (top_x || top_y || bottom_x || bottom_y) X { X t1 = top_x; X t2 = top_y; X t3 = bottom_x; X t4 = bottom_y; X copy_region(); X top_x = t1; X top_y = t2; X bottom_x = t3; X bottom_y = t4; X select_region(pw,top_x,top_y,bottom_x,bottom_y); X fill_region(); X set_select_mode(); X print_msg("Region copied to Cut/Paste buffer, select a point and then press PASTE."); X } X else X { X ERROR("Select a region first, then select CUT."); X panel_set(command_choice,PANEL_VALUE,SEL_REG,0); X mouse_parms(); X } X} X X X/* X * grab the currently selected region on the drawing area and stuff X * it into the cut/paste buffer X */ Xcopy_region() X{ X if (top_x || top_y || bottom_x || bottom_y) X { X select_region(pw,top_x,top_y,bottom_x,bottom_y); X region_fix(); X MY_pr_destroy(cut_buffer_pr); X cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth); X pr_rop(cut_buffer_pr,0,0,bottom_x-top_x,bottom_y-top_y, X PIX_SRC,pw->pw_prretained,top_x,top_y); X reset_region(); X } X else X { X ERROR("Select a region first, then select COPY."); X panel_set(command_choice,PANEL_VALUE,SEL_REG,0); X mouse_parms(); X } X} X X X/* X * take the cut/paste buffer and XOR it that stuff on to the drawing area X * so that I can move that sucker around FAST X */ Xmove_region(old_x,old_y,new_x,new_y) Xint old_x,old_y,new_x,new_y; X{ X if (cut_buffer_pr) X { X pw_write(pw,old_x-cut_buffer_pr->pr_size.x/2, X old_y-cut_buffer_pr->pr_size.y/2, X cut_buffer_pr->pr_size.x, X cut_buffer_pr->pr_size.y, X PIX_XOR, cut_buffer_pr,0,0); X X pw_write(pw,new_x-cut_buffer_pr->pr_size.x/2, X new_y-cut_buffer_pr->pr_size.y/2, X cut_buffer_pr->pr_size.x, X cut_buffer_pr->pr_size.y, X PIX_XOR, cut_buffer_pr,0,0); X } X else X { X ERROR("CUT or COPY a region first, then select MOVE."); X } X} X X X/* X * fill in a rectanglar region with the current paint pattern X */ Xfill_region(item, event) XPanel_item item; XEvent *event; X{ X if (top_x || top_y || bottom_x || bottom_y) X { X select_region(pw,top_x,top_y,bottom_x,bottom_y); X region_fix(); X 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); X reset_region(); X } X} X X X/* X * let the user lasso any free form region on the drawing area X * and stuff that into the cut/paste buffer X */ Xlaso_cut_paste() X{ Xint found; Xint i,no_points; Xint npts[1]; X X top_x = image_wid; X top_y = image_hgt; X bottom_x = 0; X bottom_y = 0; X X i=0; X while ((i0) X pw_vector(pw,ptlist[i].x,ptlist[i].y, X ptlist[i-1].x,ptlist[i-1].y,PIX_XOR,1); X } X for (i=0;i < no_points;i++) X { X ptlist[i].x -=top_x; X ptlist[i].y -=top_y; X } X MY_pr_destroy(cut_buffer_pr); X cut_buffer_pr = my_mem_create(bottom_x-top_x,bottom_y-top_y,image_depth); X pr_polygon_2(cut_buffer_pr,0,0,1,npts,ptlist,PIX_SRC,pw->pw_prretained,top_x,top_y); X reset_region(); X print_msg("The selected area is now in the Cut/Paste buffer."); X} X X X/* X * the user can lasso any area on the screen by just encircling the X * object on the bitmap X * we do this by remembering all of the points the mouse moved to X * and make a polygon stencil from these points X */ Xlaso_addpt(py_pts,x,y) Xstruct pr_pos py_pts[]; Xint x,y; X{ Xint found; Xint i; Xint npts[1]; X X found =0; X i=0; X while (i0) X pw_vector(pw,py_pts[i].x,py_pts[i].y,py_pts[i-1].x,py_pts[i-1].y,PIX_XOR,1); X i++; X py_pts[i].x = 0-1; X py_pts[i].y = 0-1; X} X X X/* X * add a point to the list of vetexs in the current polygon X */ Xpoly_addpt(py_pts,x,y) Xstruct pr_pos py_pts[]; Xint x,y; X{ Xint found; Xint i; X X found =0; X i=0; X while (ifat.c <<'END_OF_fat.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file: fat.c X purpose: This file contains the functions that handle the X magnifing class command. X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include "header.h" X Xint old_cur_color=0-1; X X/* X * Let's go into magnify mode !! X */ Xfat_mode(item, event) XPanel_item item; XEvent *event; X{ X if (image_depth==1) X old_cur_color = cur_color; X if (select_pt_x == -1) X { X ERROR("Select point first then select Magnify"); X set_select_mode(); X return(0); X } X X if (fat_source_x != -1) X select_fat_region(); X fat_source_x = select_pt_x- (int)window_get(fat_canvas, CANVAS_WIDTH)/magnify_fac/2; X fat_source_y = select_pt_y- (int)window_get(fat_canvas, CANVAS_HEIGHT)/magnify_fac/2; X clean_point(); X (void)window_set(fat_frame, WIN_SHOW, TRUE, 0); X select_fat_region(); X fat_update(0,0); X} X X X/* X * kill off the magnify window X */ Xfat_done(item, event) XPanel_item item; XEvent *event; X{ X if ((image_depth==1) && (old_cur_color != -1)) X { X cur_color = old_cur_color; X old_cur_color = 0-1; X } X if (fat_source_x != -1) X select_fat_region(); X (void)window_set(fat_frame, WIN_SHOW, FALSE, 0); X fat_source_x = 0-1; X fat_source_y = 0-1; X} X X X X/* X * The event handler for the canvas of the magnifying class window X * You can do 3 things. X * left: inverse the bit the mouse is on top of and continue X * to draw in that color X * middle: use this to draw the magnified view X * right: use to set the current color to the color of the pixel X * under the cursor X */ Xfat_handle_event(canvas_local, event) XCanvas canvas_local; XEvent *event; X{ X if (event_is_up(event)) X return; X switch (event_id(event)) { X case MS_LEFT: X if (image_depth ==1) X { X cur_color = 1^pw_get(pw,fat_source_x + (int)event_x(event)/magnify_fac,fat_source_y + (int)event_y(event)/magnify_fac); X } X fat_draw(fat_pw,pw, event_x(event), event_y(event)); X break; X case MS_MIDDLE: X fat_x = event_x(event); X fat_y = event_y(event); X break; X case MS_RIGHT: X fat_match_color(event_x(event), event_y(event)); X break; X case LOC_DRAG: X if (window_get(canvas_local, WIN_EVENT_STATE, MS_LEFT)) X fat_draw(fat_pw,pw, event_x(event), event_y(event)); X else if (window_get(canvas_local, WIN_EVENT_STATE, MS_MIDDLE)) X { X fat_update(fat_x-event_x(event),fat_y-event_y(event)); X fat_x = event_x(event); X fat_y = event_y(event); X } X break; X X } X} X X X/* X * Find out the color of the pixel under the cursor X */ Xfat_match_color(x,y) Xint x,y; X{ X x = fat_source_x + x/magnify_fac; X y = fat_source_y + y/magnify_fac; X update_cur_color(0,0,pw_get(pw,x,y)); X} X X X/* X * This is the function that updates the display of the magnifyied view X * This function is called when the middle but is used to draw this window X */ Xfat_update(offset_x,offset_y) Xint offset_x,offset_y; X{ Xint w,h; X X w = (int) window_get(fat_canvas, CANVAS_WIDTH); X h = (int) window_get(fat_canvas, CANVAS_HEIGHT); X select_fat_region(); X fat_source_x += offset_x/magnify_fac; X fat_source_y += offset_y/magnify_fac; X if (w >= SCREEN_MAX_X) X w=SCREEN_MAX_X-1; X if (h >= SCREEN_MAX_Y) X h=SCREEN_MAX_Y-1; X X/* X * check if you are within the pixrect X */ X#ifdef NO_FASTAN X if (fat_source_x < 0) X fat_source_x = 0; X if (fat_source_y < 0) X fat_source_y = 0; X if (fat_source_x+w/magnify_fac > image_wid) X fat_source_x = image_wid - w/magnify_fac; X if (fat_source_y+h/magnify_fac > image_hgt) X fat_source_y = image_hgt - h/magnify_fac; X#endif X X pw_mag(fat_pw, 0, 0, w, h, magnify_fac, pw->pw_prretained, X fat_source_x, fat_source_y); X select_fat_region(); X} X X X/* X * get the current magnification level X */ Xfat_parms(item, event) XPanel_item item; XEvent *event; X{ X select_fat_region(); X magnify_fac = (int)panel_get_value(magnify_cycle) + 1; X select_fat_region(); X fat_update(0,0); X} X X X/* X * show which region of the drawing area bitmap is being magnified X */ Xselect_fat_region() X{ Xint w,h; X w = (int) window_get(fat_canvas, CANVAS_WIDTH); X h = (int) window_get(fat_canvas, CANVAS_HEIGHT); X select_region(pw,fat_source_x-1,fat_source_y-1, X fat_source_x+w/magnify_fac+1,fat_source_y+h/magnify_fac+1); X} X X X X/* X * handle the drawing inside of the magnified view window X */ Xfat_draw(fat_pw,pw,x,y) Xstruct pixwin *fat_pw,*pw; Xint x,y; X{ X x = x/magnify_fac*magnify_fac; X y = y/magnify_fac*magnify_fac; X pw_write(fat_pw,x,y,magnify_fac,magnify_fac,PIX_COLOR(cur_color) | PIX_SRC,NILPR,0,0); X x = fat_source_x + x/magnify_fac; X y = fat_source_y + y/magnify_fac; X pw_put(pw,x,y,cur_color); X} X END_OF_fat.c if test 5661 -ne `wc -c ffill.c <<'END_OF_ffill.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file: ffill.c X purpose: this file has the functions that do flood fill X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include "header.h" X X X/* X * let's go into flood fill mode because we got a button click on flood fill X */ Xfill_mode(item, event) XPanel_item item; XEvent *event; X{ Xint x,y; X X X if (select_pt_x != -1) X { X print_msg("Hold down the RIGHT mouse button to cancel flood fill."); X x = select_pt_x; X y = select_pt_y; X clean_point(); X save_screen(); X pw_put(pw,x,y,cur_color^1); X if (ffill(x,y,cur_color)) X ERROR("Flood fill cancelled !!"); X else X hide_msg(); X } X else X { X ERROR("Select point first, then select flood fill"); X set_select_mode(); X } X} X X X#define FILL_CANCEL 1 X X/* X * this is a simple recursive flood fill that will work X * on mono bitmaps X * call it will the start x,y coordinates and the color X * to fill with, which is also the bounary color X */ Xffill(x,y,n) Xint x,y,n; X{ Xint flag; Xregister i,j,k,bx; X X if (window_get(canvas, WIN_EVENT_STATE, MS_RIGHT)) X return(FILL_CANCEL); X X if (x<0 || x>=image_wid || y<0 || y>=image_hgt || pw_get(pw,x,y)==n) X return(0); X pw_put(pw,x,y,n); X bx = x-1; X for (i=x-1;i>=0;i--) { X if (pw_get(pw,i,y)!=n) X bx = i; X else X { X pw_vector(pw,bx,y,x,y, PIX_SRC,n); X break; X } X } X bx = x+1; X for (j=x+1;j0 && pw_get(pw,k,y-1)!=n) X flag = ffill(k,y-1,n); X if (yfonts.c <<'END_OF_fonts.c' X X/************************************************************************** X Touchup a bitmap graphics editor for the Sun Workstation running SunView X Copyright (c) 1988 by Raymond Kreisel X 1/22/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X/************************************************************************** X file: fonts X purpose: the get most of the good system fixed width fonts X from the sys dirs and set them up in memory X X modifications: X date: Tue Mar 22 22:04:58 EST 1988 X author: rayk X changes:add comments X**************************************************************************/ X X#include X X X X#define cour_b_10F "/usr/lib/fonts/fixedwidthfonts/cour.b.10" X#define cour_b_12F "/usr/lib/fonts/fixedwidthfonts/cour.b.12" X#define cour_b_16F "/usr/lib/fonts/fixedwidthfonts/cour.b.16" X#define cour_b_24F "/usr/lib/fonts/fixedwidthfonts/cour.b.24" X X#define cour_r_10F "/usr/lib/fonts/fixedwidthfonts/cour.r.10" X#define cour_r_12F "/usr/lib/fonts/fixedwidthfonts/cour.r.12" X#define cour_r_16F "/usr/lib/fonts/fixedwidthfonts/cour.r.16" X#define cour_r_24F "/usr/lib/fonts/fixedwidthfonts/cour.r.24" X X#define screen_r_7F "/usr/lib/fonts/fixedwidthfonts/screen.r.7" X#define screen_r_11F "/usr/lib/fonts/fixedwidthfonts/screen.r.11" X#define screen_r_12F "/usr/lib/fonts/fixedwidthfonts/screen.r.12" X#define screen_r_14F "/usr/lib/fonts/fixedwidthfonts/screen.r.14" X#define screen_b_12F "/usr/lib/fonts/fixedwidthfonts/screen.b.12" X#define screen_b_14F "/usr/lib/fonts/fixedwidthfonts/screen.b.14" X X#define pcfont_b_14F "/usr/lib/fonts/fixedwidthfonts/pcfont.b.14" X#define pcfont_r_14F "/usr/lib/fonts/fixedwidthfonts/pcfont.r.14" X X#define serif_r_10F "/usr/lib/fonts/fixedwidthfonts/serif.r.10" X#define serif_r_11F "/usr/lib/fonts/fixedwidthfonts/serif.r.11" X#define serif_r_16F "/usr/lib/fonts/fixedwidthfonts/serif.r.16" X Xstruct pixfont *screen_r_7; Xstruct pixfont *screen_r_11; Xstruct pixfont *screen_r_12; Xstruct pixfont *screen_r_14; Xstruct pixfont *screen_b_12; Xstruct pixfont *screen_b_14; X Xstruct pixfont *pcfont_b_14; Xstruct pixfont *pcfont_r_14; X Xstruct pixfont *cour_b_10; Xstruct pixfont *cour_b_12; Xstruct pixfont *cour_b_16; Xstruct pixfont *cour_b_24; X Xstruct pixfont *cour_r_10; Xstruct pixfont *cour_r_12; Xstruct pixfont *cour_r_14; Xstruct pixfont *cour_r_16; Xstruct pixfont *cour_r_18; Xstruct pixfont *cour_r_24; X Xstruct pixfont *serif_r_10; Xstruct pixfont *serif_r_11; Xstruct pixfont *serif_r_16; X X X#define FONT_NO 19 X X Xstruct pixfont *font_array[FONT_NO]; X Xinit_font() X{ X X screen_r_7 = pf_open(screen_r_7F); X screen_r_11 = pf_open(screen_r_11F); X screen_r_12 = pf_open(screen_r_12F); X screen_r_14 = pf_open(screen_r_14F); X screen_b_12 = pf_open(screen_b_12F); X screen_b_14 = pf_open(screen_b_14F); X X pcfont_b_14 = pf_open(pcfont_b_14F); X pcfont_r_14 = pf_open(pcfont_r_14F); X X cour_b_10 = pf_open(cour_b_10F); X cour_b_12 = pf_open(cour_b_12F); X cour_b_16 = pf_open(cour_b_16F); X cour_b_24 = pf_open(cour_b_24F); X X cour_r_10 = pf_open(cour_r_10F); X cour_r_12 = pf_open(cour_r_12F); X cour_r_16 = pf_open(cour_r_16F); X cour_r_24 = pf_open(cour_r_24F); X X serif_r_10 = pf_open(serif_r_10F); X serif_r_11 = pf_open(serif_r_11F); X serif_r_16 = pf_open(serif_r_16F); X X font_array[0] = cour_r_10; X font_array[1] = cour_r_12; X font_array[2] = cour_r_16; X font_array[3] = cour_r_24; X X font_array[4] = cour_b_10; X font_array[5] = cour_b_12; X font_array[6] = cour_b_16; X font_array[7] = cour_b_24; X X font_array[8] = serif_r_10; X font_array[9] = serif_r_11; X font_array[10] = serif_r_16; X X font_array[11] = screen_r_7; X font_array[12] = screen_r_11; X font_array[13] = screen_r_12; X font_array[14] = screen_r_14; X font_array[15] = screen_b_12; X font_array[16] = screen_b_14; X X font_array[17] = pcfont_b_14; X font_array[18] = pcfont_r_14; X} X END_OF_fonts.c if test 4529 -ne `wc -c