117279Sopcode /*
2*17644Sopcode  * @(#)display.c	1.2	01/03/85
317279Sopcode  *
417279Sopcode  * This file contains routines to implement the higher level display
517279Sopcode  * driver routines for the SUN Gremlin picture editor.
617279Sopcode  *
717279Sopcode  * Mark Opperman (opcode@monet.BERKELEY)
817279Sopcode  *
917279Sopcode  */
1017279Sopcode 
1117279Sopcode #include <suntool/tool_hs.h>
1217279Sopcode #include "gremlin.h"
1317279Sopcode 
1417279Sopcode /* imports from graphics.c */
1517279Sopcode 
1617279Sopcode extern GRArc();
1717279Sopcode extern GRClear();
1817279Sopcode extern GRCurve();
1917279Sopcode extern GRCurrentSetOn();		/* force display of current set */
2017279Sopcode extern GRDisplayJustify();
2117279Sopcode extern GRNewElement();
2217279Sopcode extern GRPutText();
2317279Sopcode extern GRSetCurve();
2417279Sopcode extern GRSetLineStyle();
2517279Sopcode extern GRSetStippleStyle();
2617279Sopcode extern GRSetTextPos();
2717279Sopcode extern GRStippleFill();
2817279Sopcode extern GRVector();
2917279Sopcode 
3017279Sopcode extern curve_set;			/* true if spline pre-computed */
3117279Sopcode 
3217279Sopcode /* imports from main.c */
3317279Sopcode 
3417279Sopcode extern struct pixwin *pix_pw;
3517279Sopcode extern struct rect pix_size;
3617279Sopcode extern struct pixrect *cset_pr;
3717279Sopcode extern struct pixrect *scratch_pr;
3817279Sopcode extern ELT *cset;
3917279Sopcode extern SHOWPOINTS;
4017279Sopcode extern SUN_XORIGIN;
4117279Sopcode extern SUN_YORIGIN;
4217279Sopcode 
4317279Sopcode /* imports from long*.c */
4417279Sopcode 
4517279Sopcode extern LGShowPoints();
4617279Sopcode 
4717279Sopcode /* locals */
4817279Sopcode 
4917279Sopcode int minsunx, maxsunx, minsuny, maxsuny;
5017279Sopcode 
5117279Sopcode 
5217279Sopcode /*
5317279Sopcode  * This routine displays an arbitrary element type
5417279Sopcode  * using the parameters stored with the element.
5517279Sopcode  * Elements are drawn by Exclusive Oring the screen.
5617279Sopcode  */
DISScreenAdd(element,mask)5717279Sopcode DISScreenAdd(element, mask)
5817279Sopcode register ELT *element;
5917279Sopcode int mask;
6017279Sopcode {
6117279Sopcode     register POINT *p0, *p1, *p2;
6217279Sopcode     POINT point;
6317279Sopcode     register x, y, width, height;
6417279Sopcode 
6517279Sopcode     if (DBNullelt(element))
6617279Sopcode 	return;
6717279Sopcode 
6817279Sopcode     /* clear scratch_pr */
6917279Sopcode     pr_rop(scratch_pr, 0, 0, pix_size.r_width, pix_size.r_height,
7017279Sopcode 						PIX_SRC, NULL, 0, 0);
7117279Sopcode 
72*17644Sopcode     /* determine bounds for this element */
73*17644Sopcode     minsunx = maxsunx = dbx_to_win(element->ptlist->x);
74*17644Sopcode     minsuny = maxsuny = dby_to_win(element->ptlist->y);
7517279Sopcode 
7617279Sopcode     if (TEXT(element->type)) {
7717279Sopcode 	GRSetTextPos(element->textpt, element->type, element->brushf,
7817279Sopcode 			element->size, element->ptlist, &point);
7917279Sopcode 	GRPutText(element->textpt, element->brushf, element->size,
8017279Sopcode 			&point);
8117279Sopcode 	if (mask & csetmask)	/* display justification marker */
8217279Sopcode 	    GRDisplayJustify(element);
8317279Sopcode     }
8417279Sopcode     else {
8517279Sopcode 	switch (element->type) {
8617279Sopcode 	     case ARC:
8717279Sopcode 		p1 = element->ptlist;
8817279Sopcode 		p2 = PTNextPoint(p1);
8917279Sopcode 		/* angle is stored in size */
9017279Sopcode 		GRArc(p1, p2, (float) element->size, element->brushf);
9117279Sopcode 		break;
9217279Sopcode 	    case CURVE:
9317279Sopcode 		if (!curve_set)
9417279Sopcode 		    GRSetCurve(element->ptlist);
9517279Sopcode 		GRCurve(element->brushf);
9617279Sopcode 		curve_set = 0;
9717279Sopcode 		break;
9817279Sopcode 	    case POLYGON:
9917279Sopcode 		if (element->brushf != 0) {	/* bordered polygon */
10017279Sopcode 		    p0 = p1 = element->ptlist;
10117279Sopcode 		    p2 = PTNextPoint(p1);
10217279Sopcode 		    GRSetLineStyle(element->brushf);
10317279Sopcode 
10417279Sopcode 		    while (!Nullpoint(p2)) {
10517279Sopcode 			GRVector(p1->x, p1->y, p2->x, p2->y);
10617279Sopcode 			p1 = p2;
10717279Sopcode 			p2 = PTNextPoint(p2);
10817279Sopcode 		    }
10917279Sopcode 
11017279Sopcode 		    /* if last point not specified, join end points */
11117279Sopcode 		    if ((p0->x != p1->x) || (p0->y != p1->y))
11217279Sopcode 			    GRVector(p1->x, p1->y, p0->x, p0->y);
11317279Sopcode 		}
11417279Sopcode 		else {		/* unbordered: find min/max */
11517279Sopcode 		    p0 = element->ptlist;
11617279Sopcode 
11717279Sopcode 		    while (!Nullpoint(p0)) {
11817279Sopcode 			MINMAX(minsunx, maxsunx, dbx_to_win(p0->x));
11917279Sopcode 			MINMAX(minsuny, maxsuny, dby_to_win(p0->y));
12017279Sopcode 			p0 = PTNextPoint(p0);
12117279Sopcode 		    }
12217279Sopcode 		}
12317279Sopcode 
12417279Sopcode 		GRSetStippleStyle(element->size);
12517279Sopcode 		GRStippleFill(element->ptlist);
12617279Sopcode 		break;
12717279Sopcode 	    case VECTOR:
12817279Sopcode 		p1 = element->ptlist;
12917279Sopcode 		p2 = PTNextPoint(p1);
13017279Sopcode 		GRSetLineStyle(element->brushf);
13117279Sopcode 
13217279Sopcode 		while (!Nullpoint(p2)) {
13317279Sopcode 		    GRVector(p1->x, p1->y, p2->x, p2->y);
13417279Sopcode 		    p1 = p2;
13517279Sopcode 		    p2 = PTNextPoint(p2);
13617279Sopcode 		}
13717279Sopcode 		break;
13817279Sopcode 	}
13917279Sopcode     }
14017279Sopcode 
14117279Sopcode     x = minsunx - 8;
142*17644Sopcode     y = minsuny - 8;
14317279Sopcode     width = maxsunx + 8 - x;
14417279Sopcode     height = maxsuny + 8 - y;
14517279Sopcode 
14617279Sopcode     if (mask & pixmask)
14717279Sopcode 	pw_write(pix_pw, x, y, width, height, PIX_SRC ^ PIX_DST,
14817279Sopcode 						    scratch_pr, x, y);
14917279Sopcode 
15017279Sopcode     if (mask & csetmask)
15117279Sopcode 	pr_rop(cset_pr, x, y, width, height, PIX_SRC ^ PIX_DST,
15217279Sopcode 						    scratch_pr, x, y);
15317279Sopcode }  /* end DISScreenAdd */
15417279Sopcode 
15517279Sopcode 
15617279Sopcode /*
15717279Sopcode  * This routine erases an arbitrary element type by redrawing the
15817279Sopcode  * element with XOR.  This is the same as drawing the element.
15917279Sopcode  */
DISScreenErase(element,mask)16017279Sopcode DISScreenErase(element, mask)
16117279Sopcode register ELT *element;
16217279Sopcode register mask;
16317279Sopcode {
16417279Sopcode     DISScreenAdd(element, mask);
16517279Sopcode }  /* end ScreenErase */
16617279Sopcode 
16717279Sopcode 
16817279Sopcode /*
16917279Sopcode  * This routine clears the current set pixrect.
17017279Sopcode  */
DISClearSetDisplay()17117279Sopcode DISClearSetDisplay()
17217279Sopcode {
17317279Sopcode     register ELT *elist;
17417279Sopcode 
17517279Sopcode     GRCurrentSetOn();
17617279Sopcode 
17717279Sopcode     if (SHOWPOINTS)
17817279Sopcode 	LGShowPoints();
17917279Sopcode 
18017279Sopcode     elist = cset;
18117279Sopcode     while (!DBNullelt(elist)) {
18217279Sopcode 	if (TEXT(elist->type))		/* turn off text handle */
18317279Sopcode 	    GRDisplayJustify(elist);
18417279Sopcode 	elist = DBNextofSet(elist);
18517279Sopcode     }
18617279Sopcode 
18717279Sopcode     GRClear(csetmask);
18817279Sopcode }  /* end DISClearSetDisplay */
189