home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* Line drawing routine valid for all bitmap devices with only */
- /* some macro changes. Line is drawn and clipped using standard */
- /* routines with address optimization used for speed. */
- /* */
- /* REQUIRED MACROS: */
- /* CALC_ADDR( x, y) */
- /* X_INCREMENT_CALC() */
- /* Y_INCREMENT_CALC() */
- /* Y_DECREMENT_CALC() */
- /* XOR_POINT( colour) */
- /* POINT( colour) */
- /* */
- /* V 1.00 20/05/90 Robert Adsett Release version. Clean out site */
- /* specific header files. */
- /************************************************************************/
-
- #define TRUE 1 /* TRUE/FALSE */
- #define FALSE 0
-
- static int l_clip( /* Clip line. */
- int *x1,
- int *y1,
- int *x2,
- int *y2
- );
- static void outcodes(
- int x, /* Point. */
- int y,
- int out[4] /* Boundary flags. */
- );
- static int rej_chk(
- int out1[4], /* Outcodes. */
- int out2[4]
- );
- static int acc_chk(
- int out1[4], /* Outcodes. */
- int out2[4]
- );
- static void sw_out( /* swap ends. */
- int out1[4],
- int out2[4],
- int *x1,
- int *y1,
- int *x2,
- int *y2
- );
-
- int line( int X, int Y, int X1, int Y1)
- {
- int delta_x, delta_y, incr1, incr2, d, i = 0;
- int x3, x4, y3, y4, x5, y5;
-
- if( !l_clip( &X, &Y, &X1, &Y1)) /* clip line to limits */
- { /* if outside limits return */
- return( OUT_OF_RANGE); /* without drawing. */
- }
-
-
- if( X < X1)
- {
- x3 = X;
- x4 = X1;
- y3 = Y;
- y4 = Y1;
- }
- else
- {
- x4 = X;
- x3 = X1;
- y3 = Y1;
- y4 = Y;
- }
-
- delta_x = x4 - x3;
- delta_y = y4 - y3;
-
- if( delta_y > 0)
- { /* positive slope */
- if( delta_y < delta_x )
- { /* slope < 1 */
- incr1 = 2 * delta_y;
- d = 2 * delta_y - delta_x;
- incr2 = 2 * (delta_y - delta_x);
- x5 = x3;
- y5 = y3;
- CALC_ADDR( x5, y5);
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
-
- while( x3 < x4)
- {
- x3++;
- X_INCREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
-
- if( d < 0)
- {
- d += incr1;
- }
- else
- {
- d += incr2;
- Y_INCREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
- }
- } /* end while x3 > x4 */
- }
- else /* slope >= 1 */
- {
- incr1 = 2 * delta_x;
- d = 2 * delta_x - delta_y;
- incr2 = 2 * (delta_x - delta_y);
- x5 = x3;
- y5 = y3;
- CALC_ADDR( x5, y5);
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
-
- while( y3 < y4)
- {
- y3++;
- Y_INCREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
- if( d < 0)
- {
- d += incr1;
- }
- else
- {
- d += incr2;
- X_INCREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
- }
- } /* end while y3 < y4 */
- } /* Done slope > 1 */
- } /* Done positive slope. */
- else
- { /* negative slope */
- if( -delta_y < delta_x) /* slope > -1 */
- {
- incr1 = -2 * delta_y;
- d = -2 * delta_y - delta_x;
- incr2 = -2 * (delta_x + delta_y);
- x5 = x3;
- y5 = y3;
- CALC_ADDR( x5, y5);
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
-
- while( x3 < x4)
- {
- x3++;
- X_INCREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
- if( d < 0)
- {
- d += incr1;
- }
- else
- {
- d += incr2;
- Y_DECREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
- }
- } /* end while x3 < x4 */
- }
- else
- { /* slope <= -1 */
- d = 2 * delta_x + delta_y;
- incr1 = 2 * delta_x;
- incr2 = 2 * (delta_x + delta_y);
- x5 = x3;
- y5 = y3;
- CALC_ADDR( x5, y5);
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
-
- while( y3 > y4)
- {
- y3--;
- Y_DECREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
- if( d < 0)
- {
- d += incr1;
- }
- else
- {
- d += incr2;
- X_INCREMENT_CALC();
- if( current_line_style & line_style_mask[ (i++ & 15)])
- {
- if( current_write_mode == XOR)
- {
- XOR_POINT( current_colour);
- }
- else
- {
- POINT( current_colour);
- }
- }
- }
- } /* end while y3 > y4 */
- } /* end slope >= -1 */
- } /* end negative slope */
- return( 0);
- }
-
- static int l_clip(
- int *x1,
- int *y1,
- int *x2,
- int *y2
- )
- {
- int accept, done, out1[4], out2[4];
-
- accept = done = FALSE; /* Not done. */
- do
- {
- outcodes( *x1, *y1, out1); /* Check line beginning against */
- /* clip boundaries. */
- outcodes( *x2, *y2, out2); /* Check line end against */
- /* clip boundaries. */
- if( rej_chk( out1, out2)) /* Trivial reject? */
- {
- done = TRUE; /* reject. */
- }
- else
- { /* Trivial acceptance? */
- if( (accept = acc_chk( out1, out2)) != FALSE)
- {
- done = TRUE; /* Accept. */
- }
- else /* Must clip. */
- {
- if( !(out1[0] | out1[1] | out1[2] | out1[3]))
- { /* This end ok. */
- sw_out( out1, out2, x1, y1, x2, y2); /* swap ends. */
- }
- if( out1[0] )
- {
- *x1 = *x1 + ((*x2 - *x1) * ( MAXY - *y1)) /(*y2 - *y1);
- *y1 = MAXY;
- }
- else if( out1[1] )
- {
- *x1 = *x1 + ((*x2 - *x1) * ( -*y1))/(*y2 - *y1);
- *y1 = 0;
- }
- else if( out1[2] )
- {
- *y1 = *y1 + ((*y2 - *y1)*( MAXX - *x1))/(*x2 - *x1);
- *x1 = MAXX;
- }
- else if( out1[3] )
- {
- *y1 = *y1 + ((*y2 - *y1)*( -*x1))/(*x2 - *x1);
- *x1 = 0;
- }
- }
- }
- }while( !done);
- if( accept ) /* Accepted. */
- {
- return( TRUE );
- }
- else /* Rejected. */
- {
- return( FALSE);
- }
- }
-
- /************************************************************************/
- /* */
- /* Checks to see if the point is outside the clip boundaries */
- /* and sets the appropriate flags. */
- /* */
- /* V 1.00 May 24, 1986 R.T.A. */
- /* */
- /************************************************************************/
-
- static void outcodes(
- int x, /* Point. */
- int y,
- int out[4] /* Boundary flags. */
- )
- {
- int i; /* index. */
-
- for( i =0; i <=3; i++)
- {
- out[i] = 0; /* Init flags. */
- }
- if( y > MAXY ) /* Above. */
- {
- out[0] = 1;
- }
- else if( y < MINY ) /* Below. */
- {
- out[1] = 1;
- }
- if( x > MAXX ) /* Right. */
- {
- out[2] = 1;
- }
- else if( x < MINX ) /* Left. */
- {
- out[3] = 1;
- }
- } /* Th-Th-That's all Folk's. */
-
- /************************************************************************/
- /* */
- /* Checks the outcodes for the trivial rejection case. */
- /* */
- /* V 1.00 May 24, 1986 R.T.A. */
- /* */
- /************************************************************************/
-
- static int rej_chk(
- int out1[4], /* Outcodes. */
- int out2[4]
- )
- {
- int i; /* Index. */
-
- for( i = 0; i <= 3; i++)
- {
- if( out1[i] & out2[i]) /* Both ends outside ? */
- {
- return( TRUE ); /* Yes. */
- }
- }
- return( FALSE ); /* Can't Reject. */
- }
-
- /************************************************************************/
- /* */
- /* Checks outcodes for the case of trivial acceptance. */
- /* */
- /* V 1.00 May 24, 1986 R.T.A. */
- /* */
- /************************************************************************/
-
- static int acc_chk(
- int out1[4], /* Outcodes. */
- int out2[4]
- )
- {
- int i; /* Index. */
-
- for( i = 0; i <= 3; i ++)
- {
- if( out1[i] ) /* Accept? */
- {
- return( FALSE ); /* No. */
- }
- if( out2[i] ) /* Accept? */
- {
- return( FALSE ); /* No. */
- }
- }
- return ( TRUE ); /* Got this far, accept. */
- }
-
- /************************************************************************/
- /* */
- /* Switches outcodes and points for the clipper. */
- /* */
- /* V 1.00 May 24, 1986 R.T.A. */
- /* */
- /************************************************************************/
-
- static void sw_out( /* swap ends. */
- int out1[4],
- int out2[4],
- int *x1,
- int *y1,
- int *x2,
- int *y2
- )
- {
- int temp; /* Temporary. */
- int i, temp2; /* Index, temporary. */
-
- for( i = 0; i <= 3; i++) /* Switch outcodes. */
- {
- temp2 = out1[i];
- out1[i] = out2[i];
- out2[i] = temp2;
- }
- temp = *x1; /* Switch x's. */
- *x1 = *x2;
- *x2 = temp;
- temp = *y1; /* Switch y's. */
- *y1 = *y2;
- *y2 = temp;
- }
-
-
-
-