3 #define RGB(r, g, b) (((r) << 16) & 0xff0000) | (((g) << 8) & 0x00ff00) | ((b) & 0xff)
5 static int clip_line(int *x1, int *y1, int *x2, int *y2);
11 void draw_point(int x, int y, unsigned int col, unsigned int *ptr, int xsz) {
13 const int pt_img[sz][sz] = {
25 if(x < sz/2 || x >= xsz - sz/2 || y < sz/2 || y >= ysz - sz/2) {
29 int base_r = (col & 0xff0000) >> 16;
30 int base_g = (col & 0x00ff00) >> 8;
31 int base_b = (col & 0x0000ff);
33 unsigned int dark = RGB(base_r - base_r/4, base_g - base_g/4, base_b - base_b/4);;
35 unsigned int ctable[] = {0, col, 0xffffff, dark};
36 ptr += (y - sz / 2) * xsz + (x - sz / 2);
38 for(int i=0; i<sz; i++) {
39 for(int j=0; j<sz; j++) {
41 *(ptr + j) = ctable[pt_img[i][j]];
48 void draw_line(int x1, int y1, int x2, int y2, unsigned int col, unsigned int *ptr, int xsz) {
54 if(!clip_line(&x1, &y1, &x2, &y2)) return;
79 for(i=0; i<=dx; i++) {
116 #define MAX_CLIP_X (xsz - 1)
117 #define MAX_CLIP_Y (ysz - 1)
119 static int clip_line(int *x1, int *y1, int *x2, int *y2) {
127 // determine codes for p1 and p2
128 if(*y1 < MIN_CLIP_Y) {
131 if(*y1 > MAX_CLIP_Y) {
134 if(*x1 < MIN_CLIP_X) {
137 if(*x1 > MAX_CLIP_X) p1_code |= CLIP_E;
142 if(*y2 < MIN_CLIP_Y) {
145 if(*y2 > MAX_CLIP_Y) {
148 if(*x2 < MIN_CLIP_X) {
151 if(*x2 > MAX_CLIP_X) p2_code |= CLIP_E;
156 if((p1_code & p2_code)) return 0; // trivial rejection
157 if(p1_code == 0 && p2_code == 0) return 1; // test if totally visible
159 // find clip point for p1
165 xc1 = *x1 + 0.5 + (MIN_CLIP_Y - *y1) * (*x2 - *x1) / (*y2 - *y1);
170 xc1 = *x1 + 0.5 + (MAX_CLIP_Y - *y1) * (*x2 - *x1) / (*y2 - *y1);
175 yc1 = *y1 + 0.5 + (MIN_CLIP_X - *x1) * (*y2 - *y1) / (*x2 - *x1);
180 yc1 = *y1 + 0.5 + (MAX_CLIP_X - *x1) * (*y2 - *y1) / (*x2 - *x1);
185 xc1 = *x1 + 0.5 + (MIN_CLIP_Y - *y1) * (*x2 - *x1) / (*y2 - *y1);
186 if(xc1 < MIN_CLIP_X || xc1 > MAX_CLIP_X) {
188 yc1 = *y1 + 0.5 + (MAX_CLIP_X - *x1) * (*y2 - *y1) / (*x2 - *x1);
194 xc1 = *x1 + 0.5 + (MAX_CLIP_Y - *y1) * (*x2 - *x1) / (*y2 - *y1);
195 if(xc1 < MIN_CLIP_X || xc1 > MAX_CLIP_X) {
197 yc1 = *y1 + 0.5 + (MAX_CLIP_X - *x1) * (*y2 - *y1) / (*x2 - *x1);
203 xc1 = *x1 + 0.5 + (MIN_CLIP_Y - *y1) * (*x2 - *x1) / (*y2 - *y1);
204 if(xc1 < MIN_CLIP_X || xc1 > MAX_CLIP_X) {
206 yc1 = *y1 + 0.5 + (MIN_CLIP_X - *x1) * (*y2 - *y1) / (*x2 - *x1);
212 xc1 = *x1 + 0.5 + (MAX_CLIP_Y - *y1) * (*x2 - *x1) / (*y2 - *y1);
213 if(xc1 < MIN_CLIP_X || xc1 > MAX_CLIP_X) {
215 yc1 = *y1 + 0.5 + (MIN_CLIP_X - *x1) * (*y2 - *y1) / (*x2 - *x1);
222 // find clip point for p2
228 xc2 = *x2 + 0.5 + (MIN_CLIP_Y - *y2) * (*x1 - *x2) / (*y1 - *y2);
233 xc2 = *x2 + 0.5 + (MAX_CLIP_Y - *y2) * (*x1 - *x2) / (*y1 - *y2);
238 yc2 = *y2 + 0.5 + (MIN_CLIP_X - *x2) * (*y1 - *y2) / (*x1 - *x2);
243 yc2 = *y1 + 0.5 + (MAX_CLIP_X - *x2) * (*y1 - *y2) / (*x1 - *x2);
248 xc2 = *x2 + 0.5 + (MIN_CLIP_Y - *y2) * (*x1 - *x2) / (*y1 - *y2);
249 if(xc2 < MIN_CLIP_X || xc2 > MAX_CLIP_X) {
251 yc2 = *y2 + 0.5 + (MAX_CLIP_X - *x2) * (*y1 - *y2) / (*x1 - *x2);
257 xc2 = *x2 + 0.5 + (MAX_CLIP_Y - *y2) * (*x1 - *x2) / (*y1 - *y2);
258 if(xc2 < MIN_CLIP_X || xc2 > MAX_CLIP_X) {
260 yc2 = *y2 + 0.5 + (MAX_CLIP_X - *x2) * (*y1 - *y2) / (*x1 - *x2);
266 xc2 = *x2 + 0.5 + (MIN_CLIP_Y - *y2) * (*x1 - *x2) / (*y1 - *y2);
267 if(xc2 < MIN_CLIP_X || xc2 > MAX_CLIP_X) {
269 yc2 = *y2 + 0.5 + (MIN_CLIP_X - *x2) * (*y1 - *y2) / (*x1 - *x2);
275 xc2 = *x2 + 0.5 + (MAX_CLIP_Y - *y2) * (*x1 - *x2) / (*y1 - *y2);
276 if(xc2 < MIN_CLIP_X || xc2 > MAX_CLIP_X) {
278 yc2 = *y2 + 0.5 + (MIN_CLIP_X - *x2) * (*y1 - *y2) / (*x1 - *x2);
286 if( (xc1 < MIN_CLIP_X) || (xc1 > MAX_CLIP_X) ||
287 (yc1 < MIN_CLIP_Y) || (yc1 > MAX_CLIP_Y) ||
288 (xc2 < MIN_CLIP_X) || (xc2 > MAX_CLIP_X) ||
289 (yc2 < MIN_CLIP_Y) || (yc2 > MAX_CLIP_X) ) return 0;