home *** CD-ROM | disk | FTP | other *** search
- /* draw.c -- Interactive drawing utilities used by the simple
- * paint program paint.c
- */
-
- #include <stdio.h>
- #include <graphics.h>
- #include <alloc.h>
- #include <stdlib.h>
- #include <time.h>
- #include "mouse.h" /* Function prototypes for mouse */
- #include "draw.h" /* Function prototypes for draw.c */
-
- /* The fill parameters, drawing colors, and so forth are all kept as global
- * variables. From time to time the current drawing, fill, and line
- * styles may be changed, so before calling any drawing function make sure
- * the various drawing parameters are reset to these global values.
- */
- int globalfillstyle; /* The fill style that should be used */
- int globalfillcolor; /* Holds the fill color that should be used */
- int globaldrawcolor; /* Holds the drawing color to use */
- int globallinestyle; /* Holds the line style that should be used */
- int wl, wt, wr, wb; /* Window bounds where drawing is to be done */
-
- /* This routine emulates a pencil. While the left mouse button is pressed
- * it will draw a trail of connected lines. When the mouse button is
- * released, no drawing occurs. To avoid unneccassary drawing, lines are
- * only drawn when the mouse's position changes.
- */
- void pencil(void)
- {
- int x, y, oldx, oldy;
-
- setviewport(wl,wt,wr,wb,1); /* Draw in this viewport location */
- setcolor(globaldrawcolor); /* Use the global drawing color */
- while (1) {
- while (!buttonstatus(PRESSED,LEFT_BUTTON)) ; /* Wait until button is */
- getmousecoords(&x,&y); /* pressed, Get coordinates. */
- if (x < wl || x > wr || y < wt || y > wb) { /* If mouse location outside */
- setviewport(0,0,getmaxx(),getmaxy(),1); /* of window */
- return; /* restore viewport to full screen */
- } /* and exit pencil routine */
- oldx = x; oldy = y;
- moveto(x-wl,y-wt); /* Set current position to */
- /* where drawing begins */
- /* As long as the mouse button is */
- mousestatus(HIDE_MOUSE); /* Erase the screen where the mouse */
- mousestatus(SHOW_MOUSE);
- while (!buttonstatus(RELEASED,LEFT_BUTTON)) { /* pressed, get its */
- getmousecoords(&x,&y); /* location. If location has */
- if (x != oldx || y != oldy) { /* has changed, draw a line */
- mousestatus(HIDE_MOUSE); /* to it. Make sure to */
- lineto(x-wl,y-wt); /* adjust mouse location */
- mousestatus(SHOW_MOUSE); /* to current viewport. */
- oldx = x; oldy = y; /* Save mouse location */
- }
- }
- }
- }
-
- /* This routine resets a small block of the screen to the background
- * color. The erasing is done by drawing a filled bar at the current
- * mouse location as long as the left mouse button is pressed.
- */
- void erase(void)
- {
- int x, y, oldx, oldy;
-
- setviewport(wl,wt,wr,wb,1); /* Set the viewport to the drawing */
- setcolor(getbkcolor()); /* window. Use the background color */
- setfillstyle(SOLID_FILL,getbkcolor()); /* to erase the screen. */
- while (1) {
- while (!buttonstatus(PRESSED,LEFT_BUTTON));/* Wait for button press */
- getmousecoords(&x,&y); /* Get mouse location */
- if (x < wl || x > wr || y < wt || y > wb) { /* If mouse outside of */
- setviewport(0,0,getmaxx(),getmaxy(),1); /* window, then*/
- return; /* restore viewport and return. */
- }
- oldx = x; oldy = y;
- mousestatus(HIDE_MOUSE); /* Erase the screen where the mouse */
- bar(x-wl,y-wt,x-wl+ERASERSIZE,y-wt+ERASERSIZE); /* is located */
- mousestatus(SHOW_MOUSE);
- while (!buttonstatus(RELEASED,LEFT_BUTTON)) { /* Continue to erase */
- getmousecoords(&x,&y); /* the screen as long */
- if (x != oldx || y != oldy) { /* as the mouse is at */
- mousestatus(HIDE_MOUSE); /* a new location and */
- bar(x-wl,y-wt,x-wl+ERASERSIZE,y-wt+ERASERSIZE);
- mousestatus(SHOW_MOUSE); /* the left button is */
- oldx = x; oldy = y; /* pressed */
- }
- }
- }
- }
-
- /* The spraycan routine randomly paints pixels in a square region
- * whenever the left mouse button is pressed.
- */
- void spraycan(void)
- {
- int i, x, y;
-
- randomize(); /* Begin random function used to */
- /* decide where to paint pixels */
- setviewport(wl,wt,wr,wb,1); /* Set window to drawing window */
- while (1) { /* Wait until the left */
- while (!buttonstatus(PRESSED,LEFT_BUTTON)); /* button is pressed */
- getmousecoords(&x,&y); /* If mouse is outside */
- if (x < wl || x > wr || y < wt || y > wb) { /* of draw window then */
- setviewport(0,0,getmaxx(),getmaxy(),1); /* restore window */
- return; /* to full screen and */
- } /* quit routine */
- while (!buttonstatus(RELEASED,LEFT_BUTTON)) {/* Continue spraying */
- getmousecoords(&x, &y); /* while the button is */
- mousestatus(HIDE_MOUSE); /* pressed */
- for (i=0; i<8; i++)
- putpixel(x-random(SPRAYSIZE)+5-wl,
- y-random(SPRAYSIZE)+5-wt, globaldrawcolor);
- for (i=0; i<8; i++)
- putpixel(x-random(SPRAYSIZE-2)+3-wl,
- y-random(SPRAYSIZE-2)+3-wt, globaldrawcolor);
- mousestatus(SHOW_MOUSE);
- }
- }
- }
-
- /* Draw a line while line left mouse button is pressed. Use
- * XOR_PUT to provide rubber-banding line feature. Once a line
- * is to be fixed it is redrawn with COPY_PUT so that the color
- * for the line will be drawn correctly, since XOR_PUT won't always
- * yield the correct colors.
- */
- void drawlines(void)
- {
- int x1, y1, x2, y2, oldx2, oldy2;
-
- setviewport(wl,wt,wr,wb,1); /* Use the drawing window */
- setlinestyle(globallinestyle,0,NORM_WIDTH); /* and the global */
- setcolor(globaldrawcolor); /* settings */
- while (1) {
- while (!buttonstatus(PRESSED,LEFT_BUTTON)) ;
- getmousecoords(&x1,&y1);
- if (x1 < wl || x1 > wr || y1 < wt || y1 > wb) {
- setviewport(0,0,getmaxx(),getmaxy(),1);
- setwritemode(COPY_PUT);
- return;
- }
- setwritemode(XOR_PUT); /* Use XOR_PUT to rubber-band lines */
- moveto(x1-wl,y1-wt);
- oldx2 = x1; oldy2 = y1;
- while (!buttonstatus(RELEASED,LEFT_BUTTON)) {
- getmousecoords(&x2,&y2);
- if (x2 != oldx2 || y2 != oldy2) {
- mousestatus(HIDE_MOUSE);
- line(x1-wl,y1-wt,oldx2-wl,oldy2-wt);
- line(x1-wl,y1-wt,x2-wl,y2-wt);
- mousestatus(SHOW_MOUSE);
- oldx2 = x2; oldy2 = y2;
- }
- }
- setwritemode(COPY_PUT); /* Redraw line when set */
- mousestatus(HIDE_MOUSE); /* so color will be */
- line(x1-wl,y1-wt,x2-wl,y2-wt); /* correct */
- mousestatus(SHOW_MOUSE);
- }
- }
-
- /* Interactively draw a circle */
- void drawcircle(void)
- {
- int cleft, ctop, cright, cbottom, absradius;
- unsigned char far *covered1, *covered2;
- int centerx, centery, oldleft, oldtop;
- int halfx, newx, newy, oldx;
-
- halfx = (wr + wl) / 2;
- covered1 = malloc(imagesize(wl, wt, halfx, wb));
- covered2 = malloc(imagesize(halfx+1, wt, wr, wb));
- if (covered1 == NULL || covered2 == NULL) {
- mallocerror();
- }
- setcolor(globaldrawcolor);
- setviewport(wl, wt, wr, wb, 1);
- while (1) {
- while (!buttonstatus(PRESSED,LEFT_BUTTON)) ;
- getmousecoords(¢erx, ¢ery);
- if (centerx < wl || centerx > wr || centery < wt || centery > wb) {
- setviewport(0, 0, getmaxx(), getmaxy(),1);
- free(covered2);
- free(covered1);
- return;
- }
- oldleft = centerx; oldtop = centery; oldx = centerx;
- mousestatus(HIDE_MOUSE);
- getimage(oldleft-wl, oldtop-wt, oldleft-wl, oldtop-wt, covered1);
- getimage(oldleft+1-wl, oldtop-wt, oldleft+1-wl, oldtop-wt, covered2);
- mousestatus(SHOW_MOUSE);
- while (!buttonstatus(RELEASED,LEFT_BUTTON)) {
- getmousecoords(&newx, &newy);
- absradius = abs(centerx - newx);
-
- /* Clip the region that must be saved below the circle
- * to the boundaries of the drawing window
- */
- if (centerx-absradius < wl) cleft = wl;
- else cleft = centerx - absradius;
- if (centerx+absradius > wr) cright = wr;
- else cright = centerx + absradius;
- if (centery-absradius < wt) ctop = wt;
- else ctop = centery - absradius;
- if (centery+absradius > wb) cbottom = wb;
- else cbottom = centery + absradius;
-
- /* If the size of the circle has changed, redraw it */
- if (newx != oldx) {
- mousestatus(HIDE_MOUSE);
- putimage(oldleft-wl, oldtop-wt, covered1, COPY_PUT);
- putimage(centerx+1-wl, oldtop-wt, covered2, COPY_PUT);
- getimage(cleft-wl, ctop-wt, centerx-wl, cbottom-wt, covered1);
- getimage(centerx+1-wl, ctop-wt, cright-wl, cbottom-wt, covered2);
- if (absradius != 0)
- circle(centerx-wl, centery-wt, absradius);
- mousestatus(SHOW_MOUSE);
- oldleft = cleft; oldtop = ctop; oldx = newx;
- }
- }
- }
- }
-
- /* This function is called if a malloc() fails. Place your
- * own error handler here.
- */
- void mallocerror(void)
- {
- closegraph();
- printf("Not enough memory");
- exit(1);
- }