diff --git a/libee/line.c b/libee/line.c index 487d46e..ef7e8b2 100644 --- a/libee/line.c +++ b/libee/line.c @@ -27,15 +27,36 @@ #include "ee.h" +struct line +{ + int x1, y1; + int x2, y2; + char c; + void (*draw) (struct line*); +}; + +static void clip_line(struct line*); static uint8_t clip_bits(int, int); -static void draw_solid_line(int, int, int, int, char); +static void draw_solid_line(struct line*); void ee_draw_line(int x1, int y1, int x2, int y2, char c) +{ + struct line s; + s.x1 = x1; + s.y1 = y1; + s.x2 = x2; + s.y2 = y2; + s.c = c; + s.draw = draw_solid_line; + clip_line(&s); +} + +static void clip_line(struct line* s) { uint8_t bits1, bits2; - bits1 = clip_bits(x1, y1); - bits2 = clip_bits(x2, y2); + bits1 = clip_bits(s->x1, s->y1); + bits2 = clip_bits(s->x2, s->y2); if(bits1 & bits2) return; @@ -43,41 +64,68 @@ void ee_draw_line(int x1, int y1, int x2, int y2, char c) if(bits1 == 0) { if(bits2 == 0) - draw_solid_line(x1, y1, x2, y2, c); + s->draw(s); else - ee_draw_line(x2, y2, x1, y1, c); + { + int tmp; + tmp = s->x1; s->x1 = s->x2; s->x2 = tmp; + tmp = s->y1; s->y1 = s->y2; s->y2 = tmp; + clip_line(s); + } return; } if(bits1 & (1<<0)) { - y1 = y2 - (x2-0) * (y2-y1) / (x2-x1); - x1 = 0; + s->y1 = s->y2 - (s->x2 - 0) * (s->y2 - s->y1) / (s->x2 - s->x1); + s->x1 = 0; } else if( bits1 & (1<<1) ) { int xmax = ee_get_width() - 1; - y1 = y2 - (x2-xmax) * (y2-y1) / (x2-x1); - x1 = xmax; + s->y1 = s->y2 - (s->x2 - xmax) * (s->y2 - s->y1) / (s->x2 - s->x1); + s->x1 = xmax; } else if( bits1 & (1<<2) ) { - x1 = x2 - (y2-0) * (x2-x1) / (y2-y1); - y1 = 0; + s->x1 = s->x2 - (s->y2 - 0) * (s->x2 - s->x1) / (s->y2 - s->y1); + s->y1 = 0; } else if( bits1 & (1<<3) ) { int ymax = ee_get_height() - 1; - x1 = x2 - (y2-ymax) * (x2-x1) / (y2-y1); - y1 = ymax; + s->x1 = s->x2 - (s->y2 - ymax) * (s->x2 - s->x1) / (s->y2 - s->y1); + s->y1 = ymax; } - ee_draw_line(x1, y1, x2, y2, c); + clip_line(s); +} + +static uint8_t clip_bits(int x, int y) +{ + uint8_t b = 0; + + if(x < 0) + b |= (1<<0); + else if(x >= ee_get_width()) + b |= (1<<1); + + if(y < 0) + b |= (1<<2); + else if(y >= ee_get_height()) + b |= (1<<3); + + return b; } -static void draw_solid_line(int x1, int y1, int x2, int y2, char c) +static void draw_solid_line(struct line* s) { + int x1 = s->x1; + int y1 = s->y1; + int x2 = s->x2; + int y2 = s->y2; + int dx = abs(x2-x1); int dy = abs(y2-y1); @@ -95,7 +143,7 @@ static void draw_solid_line(int x1, int y1, int x2, int y2, char c) for(; dx>=0; dx--) { ee_goto(x1, y1); - ee_putchar(c); + ee_putchar(s->c); if(delta > 0) { x1 += xinc; @@ -118,7 +166,7 @@ static void draw_solid_line(int x1, int y1, int x2, int y2, char c) for(; dy >= 0; dy--) { ee_goto(x1, y1); - ee_putchar(c); + ee_putchar(s->c); if(delta > 0) { x1 += xinc; @@ -134,20 +182,3 @@ static void draw_solid_line(int x1, int y1, int x2, int y2, char c) } } -static uint8_t clip_bits(int x, int y) -{ - uint8_t b = 0; - - if(x < 0) - b |= (1<<0); - else if(x >= ee_get_width()) - b |= (1<<1); - - if(y < 0) - b |= (1<<2); - else if(y >= ee_get_height()) - b |= (1<<3); - - return b; -} -