// // aegis - project change supervisor // Copyright (C) 1998, 2003-2006, 2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include #include #define XLO (1 << 0) #define XHI (1 << 1) #define YLO (1 << 2) #define YHI (1 << 3) #define clip_x_min 0 #define clip_y_min 0 #define clip_x_max (gp->width) #define clip_y_max (gp->height) #define encode(x, y) \ ( \ (x < clip_x_min ? XLO : 0) \ | \ (x > clip_x_max ? XHI : 0) \ | \ (y < clip_y_min ? YLO : 0) \ | \ (y > clip_y_max ? YHI : 0) \ ) void gif_line(gif_ty *gp, int x1, int y1, int x2, int y2, int clr) { int c1; int c2; double dx1, dy1; double dx2, dy2; int dx; int dy; int e; int dirn; dx1 = x1; dx2 = x2; dy1 = y1; dy2 = y2; c1 = encode(x1, y1); c2 = encode(x2, y2); while (c1 || c2) { if (c1 & c2) return; // outside viewport if (c1 & XLO) { // // No divide by zero possibility, because (x1 != x2) // otherwise (c1 & c2) would have been true. // y1 = y1 + (y2 - y1) * (clip_x_min - x1) / (x2 - x1); //lint !e414 x1 = clip_x_min; c1 = encode(x1, y1); continue; } if (c1 & XHI) { // // No divide by zero possibility, because (x1 != x2) // otherwise (c1 & c2) would have been true. // y1 = y1 + (y2 - y1) * (clip_x_max - x1) / (x2 - x1); //lint !e414 x1 = clip_x_max; c1 = encode(x1, y1); continue; } if (c1 & YLO) { // // No divide by zero possibility, because (y1 != y2) // otherwise (c1 & c2) would have been true. // x1 = x1 + (x2 - x1) * (clip_y_min - y1) / (y2 - y1); //lint !e414 y1 = clip_y_min; c1 = encode(x1, y1); continue; } if (c1 & YHI) { // // No divide by zero possibility, because (y1 != y2) // otherwise (c1 & c2) would have been true. // x1 = x1 + (x2 - x1) * (clip_y_max - y1) / (y2 - y1); //lint !e414 y1 = clip_y_max; c1 = encode(x1, y1); continue; } if (c2 & XLO) { // // No divide by zero possibility, because (x1 != x2) // otherwise (c1 & c2) would have been true. // y2 = y2 + (y1 - y2) * (clip_x_min - x2) / (x1 - x2); //lint !e414 x2 = clip_x_min; c2 = encode(x2, y2); continue; } if (c2 & XHI) { // // No divide by zero possibility, because (x1 != x2) // otherwise (c1 & c2) would have been true. // y2 = y2 + (y1 - y2) * (clip_x_max - x2) / (x1 - x2); //lint !e414 x2 = clip_x_max; c2 = encode(x2, y2); continue; } if (c2 & YLO) { // // No divide by zero possibility, because (y1 != y2) // otherwise (c1 & c2) would have been true. // x2 = x2 + (x1 - x2) * (clip_y_min - y2) / (y1 - y2); //lint !e414 y2 = clip_y_min; c2 = encode(x2, y2); continue; } if (c2 & YHI) { // // No divide by zero possibility, because (y1 != y2) // otherwise (c1 & c2) would have been true. // x2 = x2 + (x1 - x2) * (clip_y_max - y2) / (y1 - y2); //lint !e414 y2 = clip_y_max; c2 = encode(x2, y2); continue; } } // // round the clipped values // x1 = (int)(0.5 + dx1); y1 = (int)(0.5 + dy1); x2 = (int)(0.5 + dx2); y2 = (int)(0.5 + dy2); // // draw the line // dx = abs(x2 - x1); dy = abs(y2 - y1); if (dx > dy) { if (x1 > x2) { int hold; hold = x1; x1 = x2; x2 = hold; hold = y1; y1 = y2; y2 = hold; } dirn = (y1 < y2) ? 1 : -1; e = dx/2; do { gif_pixel_set(gp, x1, y1, clr); e -= dy; if (e < 0) { e += dx; y1 += dirn; } x1++; } while (x1 <= x2); } else { if (y1 > y2) { int hold; hold = y1; y1 = y2; y2 = hold; hold = x1; x1 = x2; x2 = hold; } dirn = (x1 < x2) ? 1 : -1; e = dy/2; do { gif_pixel_set(gp, x1, y1, clr); e -= dx; if (e < 0) { e += dy; x1 += dirn; } y1++; } while (y1 <= y2); } }