bvs%carlisle@Sun.COM (Bruce Schwartz) (12/17/88)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # draw.c # item.c # eh.c # font.c # go.c # file.c # prop.c # stretch.c # This archive created: Fri Dec 16 15:05:54 1988 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'draw.c' then echo shar: "will not over-write existing file 'draw.c'" else cat << \SHAR_EOF > 'draw.c' /* $Header: draw.c,v 1.6 88/12/02 10:43:13 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ /* % % This file is a product of Sun Microsystems, Inc. and is provided for % unrestricted use provided that this legend is included on all tape % media and as a part of the software program in whole or part. % Users may copy, modify or distribute this file at will. % % THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE % WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR % PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. % % This file is provided with no support and without any obligation on the % part of Sun Microsystems, Inc. to assist in its use, correction, % modification or enhancement. % % SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE % INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE % OR ANY PART THEREOF. % % In no event will Sun Microsystems, Inc. be liable for any lost revenue % or profits or other special, indirect and consequential damages, even % if Sun has been advised of the possibility of such damages. % % Sun Microsystems, Inc. % 2550 Garcia Avenue % Mountain View, California 94043 % % Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #include "psio.h" #include "psint.h" #include "draw.h" main() { int mode, newmode; int key; int x0, y0, x1, y1; int dx0, dy0, dx1, dy1; /* damage events */ float angle; char buf[256]; if (ps_open_PostScript() == 0 ) { fprintf(stderr,"Cannot connect to NeWS server\n"); exit(1); } getwd(buf); ps_init(buf); EHInit(); GOInit(); FontInit(); PropInit(); mode = STRETCH; ps_setcanvas(); while (!psio_error(PostScriptInput)) { if(0) ; else if(ps_getmode(&newmode)) { if(mode != newmode) { ehprocs[mode].handleend(); mode = newmode; ehprocs[newmode].handlebegin(); } } else if(ps_getselect(&x0, &y0)) ehprocs[mode].handleselect(x0, y0); else if(ps_getadjust(&x0, &y0)) ehprocs[mode].handleadjust(x0, y0); else if(ps_getkey(&key)) ehprocs[mode].handlekey(key); else if(ps_getcreatepoint(&x1, &y1)) { ehprocs[mode].handlereply(x0, y0, x1, y1); } else if(ps_getcreateangle(&angle)) { ehprocs[mode].handlereply(angle); } else if(ps_getdamage(&dx0, &dy0, &dx1, &dy1)) { ps_setcanvas(); ehprocs[mode].handledamage(dx0, dy0, dx1, dy1); } else if(ps_getprop(&key)) { ehprocs[mode].handleprop(key); } else { fprintf(stderr, "End of program or illegal tag!\n"); break; } } ps_close_PostScript(); exit(0); } SHAR_EOF fi if test -f 'item.c' then echo shar: "will not over-write existing file 'item.c'" else cat << \SHAR_EOF > 'item.c' /* $Header: item.c,v 1.4 88/12/02 10:43:32 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #include <math.h> #include "go.h" #include "gopvt.h" extern PROP *GOItemProp(); extern ITEM *GOItemRotatedBounds(); static ITEM *plist; int GOItemType(pitem) ITEM *pitem; { return(pitem->type); } GOItemInit() { plist = (ITEM *)malloc(sizeof(ITEM)); plist->pnext = plist; plist->pprev = plist; } GOItemReInit() { GOItemInit(); } ITEM *GOItemAddToTop(pitem) ITEM *pitem; { pitem->pprev = plist; pitem->pnext = plist->pnext; plist->pnext->pprev = pitem; plist->pnext = pitem; return(pitem); } ITEM *GOItemAddToBottom(pitem) ITEM *pitem; { pitem->pprev = plist->pprev; pitem->pnext = plist; plist->pprev->pnext = pitem; plist->pprev = pitem; return(pitem); } ITEM *GOItemDelete(pitem) ITEM *pitem; { pitem->pprev->pnext = pitem->pnext; pitem->pnext->pprev = pitem->pprev; pitem->pnext = (ITEM *)0; pitem->pprev = (ITEM *)0; return(pitem); } ITEM *GODrawItem(pitem) ITEM *pitem; { int x = (X0 + X1)/2; int y = (Y0 + Y1)/2; ps_dorotate(x, y, pitem->rotation); goprocs[pitem->type].draw(pitem); ps_unrotate(); return(pitem); } int GOPointInItem(pitem, x, y) ITEM *pitem; int x; int y; { int x0 = X0; int x1 = X1; int y0 = Y0; int y1 = Y1; int xpt = x; int ypt = y; /* make sure we're at least 5 units wide! */ if((x1 - x0) < 5) { x0--; x1++; } if((x1 - x0) < 5) { x0--; x1++; } if((x1 - x0) < 5) { x0--; x1++; } if((y1 - y0) < 5) { y0--; y1++; } if((y1 - y0) < 5) { y0--; y1++; } if((y1 - y0) < 5) { y0--; y1++; } if(pitem->rotation != 0.0) { int xc = (x0 + x1)/2; int yc = (y0 + y1)/2; double fcos, fsin; sincos((double)(-pitem->rotation) / 180.0 * M_PI, &fsin, &fcos); xpt = ((x - xc) * fcos) - ((y - yc) * fsin) + xc; ypt = ((x - xc) * fsin) + ((y - yc) * fcos) + yc; } if((x0 <= xpt) && (x1 >= xpt) && (y0 <= ypt) && (y1 >= ypt)) { /* More detailed check... */ return(1); } else return(0); } int GOItemInRect(pitem, x0, y0, x1, y1) ITEM *pitem; int x0, y0, x1, y1; { int xmin = MIN(X0, X1); int xmax = MAX(X0, X1); int ymin = MIN(Y0, Y1); int ymax = MAX(Y0, Y1); if(pitem->rotation != 0.0) { GOItemRotatedBounds(pitem, &xmin, &ymin, &xmax, &ymax); } if( (x0 > xmax) || (x1 < xmin) || (y0 > ymax) || (y1 < ymin) ) { return(0); } else return(1); } ITEM *GOPrintItem(pitem, pfile) ITEM *pitem; FILE *pfile; { if(pitem->rotation != 0.0) { fprintf(pfile, "matrix currentmatrix "); fprintf(pfile, "%d %d translate ", X, Y); fprintf(pfile, "%f rotate ", pitem->rotation); fprintf(pfile, "%d %d translate\n", -X, -Y); goprocs[pitem->type].print(pitem, pfile); fprintf(pfile, "setmatrix\n"); } else goprocs[pitem->type].print(pitem, pfile); return(pitem); } ITEM *GOWriteItem(pitem, pfile) ITEM *pitem; FILE *pfile; { fprintf(pfile, "type %d\n", pitem->type); PropWrite(GOItemProp(pitem), pfile); fprintf(pfile, "%d %d %d %d %f %d %d\n", pitem->x0, pitem->y0, pitem->x1, pitem->y1, pitem->rotation, pitem->xscale, pitem->yscale ); goprocs[pitem->type].write(pitem, pfile); return(pitem); } ITEM *GOReadItem(pfile) FILE *pfile; { int ret; int type; ITEM *pitem; if(feof(pfile)) return((ITEM *)0); if(1 != fscanf(pfile, "type %d\n", &type)) { fprintf(stderr, "Bad read of item\n"); return((ITEM *)0); } if(type == -1) return((ITEM *)0); pitem = (ITEM *)goprocs[type].holder(); pitem->type = type; pitem->prop = PropRead(pfile); if(pitem->prop == 0) { return((ITEM *)0); } /* fprintf(stderr, "reading item type: %d\n", type); */ ret = fscanf(pfile, "%d %d %d %d %f %d %d\n", &pitem->x0, &pitem->y0, &pitem->x1, &pitem->y1, &pitem->rotation, &pitem->xscale, &pitem->yscale ); if(ret != 7) { fprintf(stderr, "Bad item type %d read...\n", type); return((ITEM *)0); } goprocs[type].read(pitem, pfile); return(pitem); } PROP * GOItemProp(pitem) ITEM *pitem; { return(pitem->prop); } ITEM * GOItemSetProp(pitem, prop) ITEM *pitem; PROP *prop; { pitem->prop = prop; return(pitem); } ITEM *GOItemMove(pitem, dx, dy) ITEM *pitem; int dx, dy; { pitem->x0 += dx; pitem->x1 += dx; pitem->y0 += dy; pitem->y1 += dy; return(pitem); } ITEM *GOItemSetRotation(pitem, angle) ITEM *pitem; float angle; { pitem->rotation = angle; return(pitem); } float GOItemGetRotation(pitem) ITEM *pitem; { return (float)pitem->rotation; } minmax4(pmin, pmax, in1, in2, in3, in4) int *pmin, *pmax; int in1, in2, in3, in4; { *pmin = MIN( MIN(in1, in2), MIN(in3, in4)); *pmax = MAX( MAX(in1, in2), MAX(in3, in4)); } ITEM *GOItemUnrotatedBounds(pitem, px0, py0, px1, py1) ITEM *pitem; int *px0, *py0, *px1, *py1; { int width = PropLineWidth(pitem->prop); *px0 = MIN(X0, X1) - width; *py0 = MIN(Y0, Y1) - width; *px1 = MAX(X0, X1) + width; *py1 = MAX(Y0, Y1) + width; return(pitem); } ITEM *GOItemRotatedBounds(pitem, px0, py0, px1, py1) ITEM *pitem; int *px0, *py0, *px1, *py1; { if(pitem->rotation != 0.0) { int width = PropLineWidth(pitem->prop); int xc = (X0 + X1 + 1)/2; int yc = (Y0 + Y1 + 1)/2; double fsin, fcos; int dx1, dy1, dx2, dy2; sincos((double)(pitem->rotation) / 180.0 * M_PI, &fsin, &fcos); dx1 = ((X1 - xc) * fcos) - ((Y0 - yc) * fsin); dx2 = ((X1 - xc) * fcos) - ((Y1 - yc) * fsin); dy1 = ((X1 - xc) * fsin) + ((Y0 - yc) * fcos); dy2 = ((X1 - xc) * fsin) + ((Y1 - yc) * fcos); *px0 = xc - MAX( ABS(dx1), ABS(dx2) ) - width; *py0 = yc - MAX( ABS(dy1), ABS(dy2) ) - width; *px1 = xc + MAX( ABS(dx1), ABS(dx2) ) + width; *py1 = yc + MAX( ABS(dy1), ABS(dy2) ) + width; } else GOItemUnrotatedBounds(pitem, px0, py0, px1, py1); return(pitem); } ITEM *GOItemMaxBounds(pitem, px0, py0, px1, py1) ITEM *pitem; int *px0, *py0, *px1, *py1; { /* just do a rough calculation */ int width = PropLineWidth(pitem->prop); int xc = (X0 + X1 + 1)/2; int yc = (Y0 + Y1 + 1)/2; int radius = (int)((MAX( ABS(X0 - X1), ABS(Y0 - Y1) ) + 1) * .75); radius += width; /* this should really be the linewidth */ *px0 = xc - radius; *px1 = xc + radius; *py0 = yc - radius; *py1 = yc + radius; return(pitem); } ITEM *GOFindItem(x, y) int x, y; { ITEM *pitem; for(pitem = plist->pnext; pitem != plist; pitem = pitem->pnext) { if(GOPointInItem(pitem, x, y)) return(pitem); } return((ITEM *)0); } GORepairItems(x0, y0, x1, y1) { ITEM *pitem; ps_pushclip(x0, y0, x1, y1); ps_setgray(1.0); ps_drawrect(x0, y0, x1, y1); ps_fill(); for(pitem = plist->pprev; pitem != plist; pitem = pitem->pprev) { if(GOItemInRect(pitem, x0, y0, x1, y1)) GODrawItem(pitem); } ps_popclip(); } GODrawItems() { ITEM *pitem; for(pitem = plist->pprev; pitem != plist; pitem = pitem->pprev) GODrawItem(pitem); } GOBoundsItems(px0, py0, px1, py1) int *px0, *py0, *px1, *py1; { ITEM *pitem = plist->pprev; int x0 = X0; int y0 = Y0; int x1 = X1; int y1 = Y1; for(pitem = plist->pprev; pitem != plist; pitem = pitem->pprev) { x0 = MIN(x0, X0); y0 = MIN(y0, Y0); x1 = MAX(x1, X1); y1 = MAX(y1, Y1); } *px0 = x0; *py0 = y0; *px1 = x1; *py1 = y1; } GOPrintItems(pfile) FILE *pfile; { ITEM *pitem; for(pitem = plist->pprev; pitem != plist; pitem = pitem->pprev) GOPrintItem(pitem, pfile); } GOWriteItems(pfile) FILE *pfile; { ITEM *pitem; for(pitem = plist->pprev; pitem != plist; pitem = pitem->pprev) { GOWriteItem(pitem, pfile); } fprintf(pfile, "type %d\n", -1); } GOReadItems(pfile) FILE *pfile; { ITEM *pitem; GOItemReInit(); while(pitem = GOReadItem(pfile)) { GOItemAddToTop(pitem); } GORepairItems(-1000, -1000, 1000, 1000); } SHAR_EOF fi if test -f 'eh.c' then echo shar: "will not over-write existing file 'eh.c'" else cat << \SHAR_EOF > 'eh.c' /* $Header: eh.c,v 1.5 88/12/02 10:43:19 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #include "draw.h" #include "go.h" #include "psio.h" #include "psint.h" static void *nullproc() { } static void *nullselect(x, y) int x, y; { fprintf(stderr, "Select not implemented for current mode\n"); } static void *nulladjust(x, y) int x, y; { fprintf(stderr, "Adjust not implemented for current mode\n"); } static void *nullkey(c) int c; { fprintf(stderr, "Keystroke not implemented for current mode\n"); } static void *nullreply(c) int c; { fprintf(stderr, "Reply not implemented for current mode\n"); } static void *handleprop(c) int c; { if(PropHandle(c) == FALSE) fprintf(stderr, "Unable to handle action/property %d\n", c); } static void *handledamage(x0, y0, x1, y1) int x0, y0, x1, y1; { GORepairItems(x0, y0, x1, y1); } static void *nullbegin() { } static void *nullend() { } EHInit() { int k; for(k=0; k < MODEMAX; k++) { ehprocs[k].handleselect = nullselect; ehprocs[k].handleadjust = nulladjust; ehprocs[k].handlekey = nullkey; ehprocs[k].handlereply = nullreply; ehprocs[k].handledamage = handledamage; ehprocs[k].handlebegin = nullbegin; ehprocs[k].handleend = nullend; ehprocs[k].handleprop = handleprop; } EHLineInit(&ehprocs[LINE]); EHPolyInit(&ehprocs[POLY]); EHBrushInit(&ehprocs[BRUSH]); EHRectInit(&ehprocs[RECT]); EHOvalInit(&ehprocs[OVAL]); EHCircInit(&ehprocs[CIRC]); EHTextInit(&ehprocs[TEXT]); EHStretchInit(&ehprocs[STRETCH]); EHRotateInit(&ehprocs[ROTATE]); } SHAR_EOF fi if test -f 'font.c' then echo shar: "will not over-write existing file 'font.c'" else cat << \SHAR_EOF > 'font.c' /* $Header: font.c,v 1.2 88/12/02 10:43:43 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #include "psint.h" typedef struct { char *name; /* family name */ int id; /* id token */ int size; /* point size */ int height; /* heighest ascender to lowest descender */ int descent; /* lowest descender to baseline */ int count; /* chars in font */ int *awidths; /* array of char width info */ } FONT; FONT *SetFont(); static FONT font; FontInit() { SetFont("Times-Roman", 48); } FONT *FontDefault() { return(&font); } FONT *SetFont(name, size) char *name; int size; { int count, height, descent; int index = ps_next_user_token++; int i; FONT *pf = &font; ps_fontsetup(name, size, index, &count, &height, &descent); pf->size = size; pf->id = index; pf->count = count >> 1; pf->height = height; pf->descent = descent < 0 ? -descent : descent; pf->name = (char *)malloc(strlen(name)); strcpy(pf->name, name); printf("font %s: id %d, count %d, height %d, descent %d\n", pf->name, pf->id, pf->count, pf->height, pf->descent); pf->awidths = (int *)malloc(pf->count * sizeof(int)); for(i = pf->count - 1; i >= 0; --i) { ps_getint(&pf->awidths[i]); /* printf("char %c (%x), width %d\n", i, i, pf->awidths[i]); */ } return pf; } FontDescent(pfont) FONT *pfont; { return(pfont->descent); } FontHeight(pfont) FONT *pfont; { return(pfont->height); } FontAscent(pfont) FONT *pfont; { return(pfont->height - pfont->descent); } int FontTextWidth(pfont, ptext) FONT *pfont; char *ptext; { int w = 0; char *pc; for(pc = ptext; *pc; pc++) { w += pfont->awidths[*pc]; } return(w); } SHAR_EOF fi if test -f 'go.c' then echo shar: "will not over-write existing file 'go.c'" else cat << \SHAR_EOF > 'go.c' /* $Header: go.c,v 1.3 88/12/02 10:43:21 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #include "draw.h" #include "go.h" #include "psio.h" #include "psint.h" static void *nullreadwrite(pitem, pfile) ITEM *pitem; FILE *pfile; { } static void *nullproc() { } static void *errorproc() { fprintf(stderr, "No object/method for current mode\n"); } GOInit() { int k; for(k=0; k < MODEMAX; k++) { goprocs[k].holder = errorproc; goprocs[k].new = errorproc; goprocs[k].move = errorproc; goprocs[k].rotate = errorproc; goprocs[k].scale = errorproc; goprocs[k].setpath = errorproc; goprocs[k].draw = errorproc; goprocs[k].print = errorproc; goprocs[k].write = nullreadwrite; goprocs[k].read = nullreadwrite; } GOItemInit(); GOLineInit(&goprocs[LINE]); GORectInit(&goprocs[RECT]); GOOvalInit(&goprocs[OVAL]); GOCircInit(&goprocs[CIRC]); GOTextInit(&goprocs[TEXT]); GOPolyInit(&goprocs[POLY]); GOBrushInit(&goprocs[BRUSH]); } SHAR_EOF fi if test -f 'file.c' then echo shar: "will not over-write existing file 'file.c'" else cat << \SHAR_EOF > 'file.c' /* $Header: file.c,v 1.4 88/12/02 10:43:11 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #define PRINTFILE "file.ps" Print() { FILE *pfile = fopen("newsdraw.ps", "w"); fprintf(pfile, "%%!\n"); fprintf(pfile, "%%%%!PS-Adobe-1.0\n"); fprintf(pfile, "%%%%Creator: NewsDraw\n"); fprintf(pfile, "%%%%Title: \n"); fprintf(pfile, "%%%%CreationDate: \n"); fprintf(pfile, "%%%%DocumentFonts: Times-Roman\n"); fprintf(pfile, "%%%%Pages: (atend)\n"); fprintf(pfile, "%%%%EndComments\n"); fprintf(pfile, "%%\n%%\n%%\n"); fprintf(pfile, "/Times-Roman findfont 36 scalefont setfont\n"); fprintf(pfile, "/rect {dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath } def\n"); fprintf(pfile, "/rectpath { 4 2 roll moveto rect } def\n"); fprintf(pfile, "/linepath { moveto lineto } def\n"); fprintf(pfile, "/circpath { 0 360 arc } def\n"); fprintf(pfile, "/ovalpath { matrix currentmatrix 5 1 roll 4 2 roll translate scale .5 .5 translate 0 0 .5 0 360 arc closepath setmatrix } def\n"); fprintf(pfile, "%%%%EndProlog\n"); fprintf(pfile, "%%%%Page: ? 1\n"); GOPrintItems(pfile); fprintf(pfile, "showpage\n"); fprintf(pfile, "%%%%Pages: 1\n"); fclose(pfile); /* system("lpr .drawprint"); */ } #define WRITEFILE "file.nd" Write() { FILE *pfile = fopen(WRITEFILE, "w"); GOWriteItems(pfile); fclose(pfile); } Read() { FILE *pfile = fopen(WRITEFILE, "r"); GOReadItems(pfile); fclose(pfile); } SHAR_EOF fi if test -f 'prop.c' then echo shar: "will not over-write existing file 'prop.c'" else cat << \SHAR_EOF > 'prop.c' /* $Header: prop.c,v 1.4 88/12/02 10:43:45 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #include "psint.h" #include "go.h" #include "comm.h" typedef struct prop { int linewidth; float strokecolor; float fillcolor; float textcolor; FONT *pfont; }; static PROP *propcurrent; static PROP *proplast; PROP *PropNew(); PropInit() { proplast = (PROP *)0; propcurrent = PropNew(); propcurrent->linewidth = 1; propcurrent->strokecolor = 0.0; propcurrent->fillcolor = .75; propcurrent->textcolor = 0.0; propcurrent->pfont = FontDefault(); } PROP *PropCopyOf(prop) PROP *prop; { PROP *propNew = PropNew(); *propNew = *prop; return(propNew); } PROP *PropNew() { return((PROP *)malloc(sizeof(PROP))); } PROP *PropSetCurrent(prop) PROP *prop; { *propcurrent = *prop; return(prop); } PROP *PropCurrent() { return(propcurrent); } int PropHandle(id) /* actually returns boolean */ int id; { int handled = TRUE; switch(id) { default: handled = FALSE; break; /* properties */ case FILL_KEY: ps_getfloat(&propcurrent->fillcolor); break; case STROKE_KEY: ps_getfloat(&propcurrent->strokecolor); break; case TEXT_KEY: ps_getfloat(&propcurrent->textcolor); break; case WIDTH_KEY: ps_getint(&propcurrent->linewidth); break; case PRINT_KEY: Print(); break; case WRITE_KEY: Write(); break; case READ_KEY: Read(); break; case REDRAW_KEY: GODrawItems(); break; } return(handled); } float PropStrokeColor(prop) PROP *prop; { return(prop->strokecolor); } float PropFillColor(prop) PROP *prop; { return(prop->fillcolor); } float PropTextColor(prop) PROP *prop; { return(prop->textcolor); } int PropLineWidth(prop) PROP *prop; { return(prop->linewidth); } FONT *PropFont(prop) PROP *prop; { return(prop->pfont); } PropWrite(prop, pfile) PROP *prop; FILE *pfile; { fprintf(pfile, "PROPS %d %f %f %f\n", prop->linewidth, prop->strokecolor, prop->fillcolor, prop->textcolor); } PROP *PropRead(pfile) FILE *pfile; { PROP *prop = PropNew(); int ret = fscanf(pfile, "PROPS %d %f %f %f\n", &prop->linewidth, &prop->strokecolor, &prop->fillcolor, &prop->textcolor); prop->pfont = FontDefault(); if(ret != 4) { fprintf("bad prop read...\n"); } return(prop); } SHAR_EOF fi if test -f 'stretch.c' then echo shar: "will not over-write existing file 'stretch.c'" else cat << \SHAR_EOF > 'stretch.c' /* $Header: stretch.c,v 1.5 88/12/02 10:43:46 bvs Exp $ */ /* Copyright (C) 1988 by Sun Microsystems. All rights reserved. */ #include <stdio.h> #include "draw.h" #include "go.h" #include "psio.h" #include "psint.h" #include "comm.h" static ITEM *pcurrent = (ITEM *)0; static ITEM *SRSelectItem(); static ITEM *SRDeselectItem(); static void *StretchMoveReply(); #define B 3 /* selection border */ #define B1 2 /* selection border inner */ /* shared stretch/rotate stuff */ static void *SRBegin() { ps_stdcursor(); } static void *SREnd() { if(pcurrent) SRDeselectItem(pcurrent); pcurrent = (ITEM *)0; } static void *SRProp(c) int c; { ITEM *pitem = pcurrent; if(pitem) SRDeselectItem(pitem); PropHandle(c); /* this should be in action handle! */ if(pitem) { if(c == TOTOP_KEY) { GOItemDelete(pitem); GOItemAddToTop(pitem); } if(c == TOBOT_KEY) { GOItemDelete(pitem); GOItemAddToBottom(pitem); } } /* set property on selected item */ if(pitem) { int x0, x1, y0, y1; GOItemSetProp(pitem, PropCopyOf(PropCurrent())); GOItemRotatedBounds(pitem, &x0, &y0, &x1, &y1); GORepairItems(x0 - 10, y0 - 10, x1 + 10, y1 + 10); /* 10 hack */ SRSelectItem(pitem); } } static void *SRAdjust(x, y) int x,y; { } static void *SRKey(key) int key; { int x0, x1, y0, y1; if(pcurrent) { if((key == 0177) || (key = 10)) /* delete or BS key */ { GOItemDelete(pcurrent); GOItemRotatedBounds(pcurrent, &x0, &y0, &x1, &y1); GORepairItems(x0 - B, y0 - B, x1 + B, y1 + B); /* GOFreeItem(pcurrent); */ pcurrent = (ITEM *)0; } } } /* stretch selection */ static void *StretchSelect(x, y) int x,y; { ITEM *pfound = (ITEM *)GOFindItem(x, y); if((pcurrent) && (pcurrent == pfound)) { /* move or stretch */ int x0, y0, x1, y1; int bL, bT, bB, bR; int type = GOItemType(pcurrent); GOItemUnrotatedBounds(pcurrent, &x0, &y0, &x1, &y1); bT = bB = bL = bR = 0; if(x < (x0 + B)) bL = 1; if(y < (y0 + B)) bB = 1; if(x > (x1 - B)) bR = 1; if(y > (y1 - B)) bT = 1; if (bL && bT) ehprocs[type].handleselect(x1, y0); else if(bL && bB) ehprocs[type].handleselect(x1, y1); else if(bR && bT) ehprocs[type].handleselect(x0, y0); else if(bR && bB) ehprocs[type].handleselect(x0, y1); else { ehprocs[STRETCH].handlereply = StretchMoveReply; ps_moveinteractive(x, y, GOItemGetRotation(pcurrent), x0, y0, x1, y1); } } else { if(pcurrent) SRDeselectItem(pcurrent); pcurrent = pfound; if(pcurrent) SRSelectItem(pcurrent); } } static void *StretchMoveReply(xstart, ystart, xend, yend) int xstart, ystart, xend, yend; { int x0, y0, x1, y1; int s0, t0, s1, t1; GOItemRotatedBounds(pcurrent, &x0, &y0, &x1, &y1); GOItemMove(pcurrent, xend - xstart, yend - ystart); GOItemRotatedBounds(pcurrent, &s0, &t0, &s1, &t1); if((x0 > s1) || (x1 < s0) || (y0 > t1) || (y1 < t0)) { /* no intersection */ /* printf("no intersect\n"); */ GORepairItems(x0 - B, y0 - B, x1 + B, y1 + B); GORepairItems(s0, t0, s1, t1); } else { /* the regions intersect */ /* printf("intersection\n"); */ GORepairItems( MIN(s0, x0 - B), MIN(t0, y0 - B), MAX(s1, x1 + B), MAX(t1, y1 + B) ); } saveareaunderitem(pcurrent); GOItemUnrotatedBounds(pcurrent, &x0, &y0, &x1, &y1); drawselection(GOItemGetRotation(pcurrent), x0, y0, x1, y1); } EHStretchInit(pprocs) EHPROCS *pprocs; { pprocs->handlebegin = SRBegin; pprocs->handleend = SREnd; pprocs->handleprop = SRProp; pprocs->handleselect = StretchSelect; pprocs->handleadjust = SRAdjust; pprocs->handlekey = SRKey; } /* rotate selection */ static void *RotateSelect(x, y) int x,y; { ITEM *pfound = (ITEM *)GOFindItem(x, y); if(pcurrent == pfound) { /* rotate */ int x0, y0, x1, y1; GOItemUnrotatedBounds(pcurrent, &x0, &y0, &x1, &y1); ps_rotateInteractive( GOItemGetRotation(pcurrent), x, y, (x0 + x1)/2, (y0 + y1)/2, x0, y0, x1, y1); } else { if(pcurrent) SRDeselectItem(pcurrent); pcurrent = pfound; if(pcurrent) SRSelectItem(pcurrent); } } static void *RotateReply(angle) float angle; { int x0, y0, x1, y1; int s0, t0, s1, t1; GOItemRotatedBounds(pcurrent, &x0, &y0, &x1, &y1); GOItemSetRotation(pcurrent, angle); GOItemRotatedBounds(pcurrent, &s0, &t0, &s1, &t1); GORepairItems( MIN(x0, s0) - B, MIN(y0, t0) - B, MAX(x1, s1) + B, MAX(y1, t1) + B); saveareaunderitem(pcurrent); GOItemUnrotatedBounds(pcurrent, &x0, &y0, &x1, &y1); drawselection(angle, x0, y0, x1, y1); } EHRotateInit(pprocs) EHPROCS *pprocs; { pprocs->handlebegin = SRBegin; pprocs->handleend = SREnd; pprocs->handleprop = SRProp; pprocs->handlekey = SRKey; pprocs->handleselect = RotateSelect; pprocs->handleadjust = SRAdjust; pprocs->handlereply = RotateReply; } /* private stuff */ static ITEM *SRSelectItem(pitem) ITEM *pitem; { if(pcurrent) { fprintf("GOSelectItem: Internal error\n"); } if(pitem) { int x0, y0, x1, y1; float angle; pcurrent = pitem; saveareaunderitem(pitem); angle = GOItemGetRotation(pitem); GOItemUnrotatedBounds(pitem, &x0, &y0, &x1, &y1); drawselection(angle, x0, y0, x1, y1); PropSetCurrent(GOItemProp(pitem)); } return(pitem); } static ITEM *SRDeselectItem(pitem) ITEM *pitem; { if(!pcurrent) { fprintf(stderr, "SRDeselectItem: Internal error\n"); return(pitem); } else { ps_restorearea(); } pcurrent = (ITEM *)0; return(pitem); } static drawselection(angle, x0, y0, x1, y1) float angle; int x0, y0, x1, y1; { int x2 = (x0 + x1)/2; int y2 = (y0 + y1)/2; ps_flush_PostScript(); ps_dorotate(x2, y2, angle); ps_setgray(1.0); ps_drawrect(x0 - B, y0 - B, x0 + B, y0 + B); ps_drawrect(x1 - B, y0 - B, x1 + B, y0 + B); ps_drawrect(x1 - B, y1 - B, x1 + B, y1 + B); ps_drawrect(x0 - B, y1 - B, x0 + B, y1 + B); ps_drawrect(x0 - B, y2 - B, x0 + B, y2 + B); ps_drawrect(x1 - B, y2 - B, x1 + B, y2 + B); ps_drawrect(x2 - B, y0 - B, x2 + B, y0 + B); ps_drawrect(x2 - B, y1 - B, x2 + B, y1 + B); ps_drawrect(x2 - B, y2 - B, x2 + B, y2 + B); ps_fill(); ps_setgray(0.0); ps_drawrect(x0 - B1, y0 - B1, x0 + B1, y0 + B1); ps_drawrect(x1 - B1, y0 - B1, x1 + B1, y0 + B1); ps_drawrect(x1 - B1, y1 - B1, x1 + B1, y1 + B1); ps_drawrect(x0 - B1, y1 - B1, x0 + B1, y1 + B1); ps_drawrect(x0 - B1, y2 - B1, x0 + B1, y2 + B1); ps_drawrect(x1 - B1, y2 - B1, x1 + B1, y2 + B1); ps_drawrect(x2 - B1, y0 - B1, x2 + B1, y0 + B1); ps_drawrect(x2 - B1, y1 - B1, x2 + B1, y1 + B1); ps_drawrect(x2 - B1, y2 - B1, x2 + B1, y2 + B1); ps_fill(); ps_unrotate(); ps_flush_PostScript(); } saveareaunderitem(pitem) ITEM *pitem; { int x0, y0, x1, y1; GOItemRotatedBounds(pitem, &x0, &y0, &x1, &y1); ps_savearea(x0 - B, y0 - B, x1 + B, y1 + B); /*printf("save area (%d,%d), (%d,%d)\n", x0 - B, y0 - B, x1 + B, y1 + B);*/ } SHAR_EOF fi exit 0 # End of shell archive