www.pudn.com > ilib > IDrawLin.c
/* * IDrawLine.c * * Image library * * Description: * Portable routines to manipulate raster images. * * History: * 20-May-96 Craig Knudsen cknudsen@radix.net * Created * ****************************************************************************/ #include#include #include #include #include #include "Ilib.h" #include "IlibP.h" #define ON_OFF_PIXELS 3.0 IError IDrawLine ( image, gc, x1, y1, x2, y2 ) IImage image; IGC gc; int x1; int y1; int x2; int y2; { IGCP *gcp = (IGCP *)gc; IImageP *imagep = (IImageP *)image; int myx, myy; double slope; double myslope; double curx, cury; int done = 0; int temp; double draw_count = 0.0; double on_off_size = 0.0; if ( ! gcp ) return ( IInvalidGC ); if ( gcp->magic != IMAGIC_GC ) return ( IInvalidGC ); if ( ! imagep ) return ( IInvalidImage ); if ( imagep->magic != IMAGIC_IMAGE ) return ( IInvalidImage ); /* x2 should always be greater than x1 */ if ( x2 < x1 ) { temp = x2; x2 = x1; x1 = temp; temp = y2; y2 = y1; y1 = temp; } /* remember, our coordinate system is reversed for y */ if ( x1 == x2 ) { if ( y2 < y1 ) { temp = x2; x2 = x1; x1 = temp; temp = y2; y2 = y1; y1 = temp; } } else slope = - ( (double) y2 - (double) y1 ) / ( (double) x1 - (double) x2 ); curx = (double) x1; cury = (double) y1; if ( gcp->line_width <= 1 ) _IDrawPoint ( imagep, gcp, x1, y1 ); /* handle dashes */ if ( gcp->line_style == ILINE_ON_OFF_DASH ) { if ( x1 == x2 || abs ( slope ) < 0.1 || abs ( slope ) > 10 ) { on_off_size = ON_OFF_PIXELS; } else { myslope = abs ( slope ); if ( myslope > 1.0 ) myslope = 1.0 / myslope; /* myslope now between 0 and 1.0 */ on_off_size = ON_OFF_PIXELS + ( 0.41 * myslope ); } } while ( ! done ) { if ( x1 == x2 ) { if ( cury >= (double)y2 ) done = 1; else cury += 1.0; } else if ( slope >= 1.0 ) { if ( cury >= (double)y2 ) done = 1; else { cury += 1.0; curx += ( 1.0 / slope ); } } else if ( slope < -1.0 ) { if ( cury <= (double)y2 ) done = 1; else { cury -= 1.0; curx -= ( 1.0 / slope ); } } else if ( slope >= 0.0 ) { if ( curx >= (double)x2 ) done = 1; else { curx += 1.0; cury += slope; } } else if ( slope < 0.0 ) { if ( curx >= (double)x2 ) done = 1; else { curx += 1.0; cury += slope; } } if ( gcp->line_style == ILINE_ON_OFF_DASH ) { draw_count += 1.0; if ( ( (int)( floor ( draw_count / on_off_size ) ) % 2 ) == 1 ) continue; } if ( ! done ) { myx = (int) curx; myy = (int) cury; switch ( gcp->line_width ) { default: case 0: case 1: _IDrawPoint ( imagep, gcp, myx, myy ); break; case 2: _IDrawPoint ( imagep, gcp, myx, myy ); _IDrawPoint ( imagep, gcp, myx - 1, myy ); _IDrawPoint ( imagep, gcp, myx - 1, myy - 1 ); _IDrawPoint ( imagep, gcp, myx, myy - 1 ); break; case 3: _IDrawPoint ( imagep, gcp, myx, myy ); _IDrawPoint ( imagep, gcp, myx - 1, myy ); _IDrawPoint ( imagep, gcp, myx + 1, myy - 1 ); _IDrawPoint ( imagep, gcp, myx, myy - 1 ); _IDrawPoint ( imagep, gcp, myx, myy + 1 ); break; } } } return ( INoError ); }