1 /* 2 3 Copyright (C) 2015-2018 Night Dive Studios, LLC. 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 */ 19 /* 20 * $Source: n:/project/lib/src/2d/RCS/fl8lin.h $ 21 * $Revision: 1.1 $ 22 * $Author: lmfeeney $ 23 * $Date: 1994/06/11 00:51:50 $ 24 */ 25 26 /* this was originally the guts of flat8_fix_uline */ 27 28 fix x0, y0, x1, y1; 29 fix dx, dy; /* deltas in x and y */ 30 fix t; /* temporary fix */ 31 32 uchar *p; /* pointer into canvas */ 33 34 x0 = v0->x; 35 y0 = v0->y; 36 x1 = v1->x; 37 y1 = v1->y; 38 39 /* set endpoints 40 note that this cannot go negative or change octant, since the == 41 case is excluded */ 42 43 if (x0 < x1) { 44 x1 -= 1; /* e.g. - epsilon */ 45 } else if (x0 > x1) { 46 x0 -= 1; 47 } 48 49 if (y0 < y1) { 50 y1 -= 1; 51 } else if (y0 > y1) { 52 y0 -= 1; 53 } 54 55 dx = fix_trunc(x1) - fix_trunc(x0); /* x extent in pixels, (macro is flakey) */ 56 dx = fix_abs(dx); 57 dy = fix_trunc(y1) - fix_trunc(y0); /* y extent in pixels */ 58 dy = fix_abs(dy); 59 60 if (dx == 0 && dy == 0) 61 return; 62 63 flat8_pixel_fill_init; 64 65 /* three cases: absolute value dx < = > dy 66 67 along the longer dimension, the fixpoint x0 (or y0) is treated 68 as an int 69 70 the points are swapped if needed and the rgb initial and deltas 71 are calculated accordingly 72 73 there are two or three sub-cases - a horizontal or vertical line, 74 and the dx or dy being added or subtracted. dx and dy 75 are kept as absolute values and +/- is managed in 76 two separate inner loops if it is a y change, since you need to 77 manage the canvas pointer 78 79 if y is being changed by 'dy' and x is being incremented, do a 80 FunkyBitCheck (TM) to see whether the integer part of y has changed 81 and if it has, resetting the the canvas pointer to the next row 82 83 if x is being changed by 'dx' and y is being incremented, just 84 add or subtract row to increment y in the canvas 85 86 the endpoints are walked inclusively in all cases, see above 87 88 45' degree lines are explicitly special cased -- because it 89 all runs as integers, but it's probably not frequent enough 90 to justify the check 91 92 */ 93 94 if (dx > dy) { 95 96 x0 = fix_int(x0); 97 x1 = fix_int(x1); 98 99 if (x0 > x1) { 100 t = x0; 101 x0 = x1; 102 x1 = t; 103 t = y0; 104 y0 = y1; 105 y1 = t; 106 } 107 p = grd_bm.bits + grd_bm.row * (fix_int(y0)); 108 109 if ((fix_int(y0)) == (fix_int(y1))) { 110 flat8_pixel_fill_row; 111 } else if (y0 < y1) { 112 dy = fix_div((y1 - y0), dx); 113 while (x0 <= x1) { 114 flat8_pixel_fill_xi; 115 x0++; 116 y0 += dy; 117 p += (grd_bm.row & (-(fix_frac(y0) < dy))); 118 } 119 } else { 120 dy = fix_div((y0 - y1), dx); 121 while (x0 <= x1) { 122 flat8_pixel_fill_xi; 123 x0++; 124 p -= (grd_bm.row & (-(fix_frac(y0) < dy))); 125 y0 -= dy; 126 } 127 } 128 } 129 130 else if (dy > dx) { 131 132 y0 = fix_int(y0); 133 y1 = fix_int(y1); 134 135 if (y0 > y1) { 136 t = x0; 137 x0 = x1; 138 x1 = t; 139 t = y0; 140 y0 = y1; 141 y1 = t; 142 } 143 144 p = grd_bm.bits + grd_bm.row * y0; 145 146 if ((fix_int(x0)) == (fix_int(x1))) { 147 x0 = fix_int(x0); 148 while (y0 <= y1) { 149 flat8_pixel_fill_xi; 150 y0++; 151 p += grd_bm.row; 152 } 153 } else { 154 dx = fix_div((x1 - x0), dy); 155 while (y0 <= y1) { 156 flat8_pixel_fill_xf; 157 x0 += dx; 158 y0++; 159 p += grd_bm.row; 160 } 161 } 162 } else { /* dy == dx, walk the x axis, all integers */ 163 164 x0 = fix_int(x0); 165 x1 = fix_int(x1); 166 y0 = fix_int(y0); 167 y1 = fix_int(y1); 168 169 if (x0 > x1) { 170 t = x0; 171 x0 = x1; 172 x1 = t; 173 t = y0; 174 y0 = y1; 175 y1 = t; 176 } 177 p = grd_bm.bits + grd_bm.row * y0; 178 179 if (y0 < y1) { 180 while (y0 <= y1) { 181 flat8_pixel_fill_xi; 182 x0++; 183 y0++; 184 p += grd_bm.row; 185 } 186 } else { 187 while (y0 >= y1) { 188 flat8_pixel_fill_xi; 189 x0++; 190 y0--; 191 p -= grd_bm.row; 192 } 193 } 194 } 195