|
|
@@ -28,10 +28,11 @@ |
|
|
|
#undef __USE_XOPEN /* THAT sucks, too (avoid declaring y1 in math.h) */ |
|
|
|
#include <math.h> |
|
|
|
|
|
|
|
|
|
|
|
#include "pipi.h" |
|
|
|
#include "pipi_internals.h" |
|
|
|
|
|
|
|
#if !defined TEMPLATE_FILE /* This file uses the template system */ |
|
|
|
|
|
|
|
struct line |
|
|
|
{ |
|
|
|
int x1, y1; |
|
|
@@ -48,16 +49,16 @@ struct line |
|
|
|
}; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
#define TEMPLATE_FLAGS SET_FLAG_GRAY | SET_FLAG_8BIT |
|
|
|
#define TEMPLATE_FILE "paint/line.c" |
|
|
|
#include "pipi_template.h" |
|
|
|
|
|
|
|
static void clip_line(pipi_image_t*, struct line*); |
|
|
|
static uint8_t clip_bits(pipi_image_t*, int, int); |
|
|
|
static void draw_aliased_line_u32(pipi_image_t*, struct line*); |
|
|
|
static void draw_aliased_line_gray(pipi_image_t *img, struct line* s); |
|
|
|
static void draw_aliased_line_float(pipi_image_t *img, struct line* s); |
|
|
|
static void draw_antialiased_line_float(pipi_image_t *img, struct line* s); |
|
|
|
static void draw_antialiased_line_gray(pipi_image_t *img, struct line* s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t c, int aa) |
|
|
|
{ |
|
|
|
struct line s; |
|
|
@@ -75,7 +76,7 @@ int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t |
|
|
|
dstdata = (uint32_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels; |
|
|
|
s.color32 = c; |
|
|
|
s.buf_u32 = dstdata; |
|
|
|
s.draw = draw_aliased_line_u32; |
|
|
|
s.draw = aliased_line_8bit; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@@ -92,9 +93,9 @@ int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t |
|
|
|
{ |
|
|
|
float *dstdata; |
|
|
|
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_Y_F)->pixels; |
|
|
|
s.colorf[0] = c/255.0f; /* XXX FIXME */ |
|
|
|
s.colorf[0] = (c & 0xff) / 255.0f; /* XXX FIXME */ |
|
|
|
s.buf_f = dstdata; |
|
|
|
s.draw = aa==0?draw_aliased_line_gray:draw_antialiased_line_gray; |
|
|
|
s.draw = aa==0?aliased_line_gray:draw_antialiased_line_gray; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@@ -104,7 +105,7 @@ int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t |
|
|
|
s.colorf[1] = ((c&0x0000FF00)>>8)/255.0f; /* XXX FIXME */ |
|
|
|
s.colorf[0] = (c&0x000000FF)/255.0f; /* XXX FIXME */ |
|
|
|
s.buf_f = dstdata; |
|
|
|
s.draw = aa==0?draw_aliased_line_float:draw_antialiased_line_float; |
|
|
|
s.draw = aa==0?aliased_line:draw_antialiased_line_float; |
|
|
|
} |
|
|
|
|
|
|
|
clip_line(img, &s); |
|
|
@@ -126,7 +127,7 @@ int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[], |
|
|
|
dstdata = (uint32_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels; |
|
|
|
s.color32 = c; |
|
|
|
s.buf_u32 = dstdata; |
|
|
|
s.draw = draw_aliased_line_u32; |
|
|
|
s.draw = aliased_line_8bit; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@@ -145,7 +146,7 @@ int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[], |
|
|
|
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_Y_F)->pixels; |
|
|
|
s.colorf[0] = c/255.0f; /* XXX FIXME */ |
|
|
|
s.buf_f = dstdata; |
|
|
|
s.draw = aa==0?draw_aliased_line_gray:draw_antialiased_line_gray; |
|
|
|
s.draw = aa==0?aliased_line_gray:draw_antialiased_line_gray; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@@ -155,7 +156,7 @@ int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[], |
|
|
|
s.colorf[1] = (c&0x0000FF00)/255.0f; /* XXX FIXME */ |
|
|
|
s.colorf[2] = (c&0x000000FF)/255.0f; /* XXX FIXME */ |
|
|
|
s.buf_f = dstdata; |
|
|
|
s.draw = aa==0?draw_aliased_line_float:draw_antialiased_line_float; |
|
|
|
s.draw = aa==0?aliased_line:draw_antialiased_line_float; |
|
|
|
img->last_modified = PIPI_PIXELS_RGBA_F; |
|
|
|
} |
|
|
|
|
|
|
@@ -170,13 +171,10 @@ int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[], |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
* XXX: The following functions are local. |
|
|
|
*/ |
|
|
|
|
|
|
|
/* Generic Cohen-Sutherland line clipping function. */ |
|
|
|
static void clip_line(pipi_image_t *img, struct line* s) |
|
|
|
{ |
|
|
@@ -246,31 +244,6 @@ static uint8_t clip_bits(pipi_image_t *img, int x, int y) |
|
|
|
return b; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Solid line drawing function, using Bresenham's mid-point line |
|
|
|
* scan-conversion algorithm. */ |
|
|
|
static void draw_aliased_line_u32(pipi_image_t *img, struct line* s) |
|
|
|
{ |
|
|
|
#undef ASSIGN |
|
|
|
#define ASSIGN(x, y, w) s->buf_u32[x+y*w] = s->color32; |
|
|
|
#include "line_template.h" |
|
|
|
} |
|
|
|
static void draw_aliased_line_float(pipi_image_t *img, struct line* s) |
|
|
|
{ |
|
|
|
#undef ASSIGN |
|
|
|
#define ASSIGN(x, y, w) s->buf_f[(x*4)+y*(w*4)] = s->colorf[0]; \ |
|
|
|
s->buf_f[1 + (x*4)+y*(w*4)] = s->colorf[1]; \ |
|
|
|
s->buf_f[2 + (x*4)+y*(w*4)] = s->colorf[2]; |
|
|
|
#include "line_template.h" |
|
|
|
} |
|
|
|
static void draw_aliased_line_gray(pipi_image_t *img, struct line* s) |
|
|
|
{ |
|
|
|
#undef ASSIGN |
|
|
|
#define ASSIGN(x, y, w) s->buf_f[x+y*w] = s->colorf[0]; |
|
|
|
#include "line_template.h" |
|
|
|
} |
|
|
|
|
|
|
|
/* Xiaolin Wu's line algorithm, as seen at http://portal.acm.org/citation.cfm?id=122734 */ |
|
|
|
|
|
|
|
/* math.h doesn't like y1 (sucker) */ |
|
|
@@ -314,3 +287,106 @@ static void draw_antialiased_line_gray(pipi_image_t *img, struct line* s) |
|
|
|
|
|
|
|
#include "aline_template.h" |
|
|
|
} |
|
|
|
|
|
|
|
#else /* XXX: the following functions use the template system */ |
|
|
|
|
|
|
|
/* Solid line drawing function, using Bresenham's mid-point line |
|
|
|
* scan-conversion algorithm. */ |
|
|
|
static void SUFFIX(aliased_line)(pipi_image_t *img, struct line* s) |
|
|
|
{ |
|
|
|
int x1, y1, x2, y2; |
|
|
|
int dx, dy; |
|
|
|
int xinc, yinc; |
|
|
|
|
|
|
|
x1 = s->x1; y1 = s->y1; x2 = s->x2; y2 = s->y2; |
|
|
|
|
|
|
|
dx = abs(x2 - x1); |
|
|
|
dy = abs(y2 - y1); |
|
|
|
|
|
|
|
xinc = (x1 > x2) ? -1 : 1; |
|
|
|
yinc = (y1 > y2) ? -1 : 1; |
|
|
|
|
|
|
|
if(dx >= dy) |
|
|
|
{ |
|
|
|
int dpr = dy << 1; |
|
|
|
int dpru = dpr - (dx << 1); |
|
|
|
int delta = dpr - dx; |
|
|
|
|
|
|
|
for(; dx >= 0; dx--) |
|
|
|
{ |
|
|
|
if(FLAG_GRAY) |
|
|
|
{ |
|
|
|
if(FLAG_8BIT) |
|
|
|
/* TODO */; |
|
|
|
else |
|
|
|
s->buf_f[x1 + y1 * img->w] = s->colorf[0]; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if(FLAG_8BIT) |
|
|
|
s->buf_u32[x1 + y1 * img->w] = s->color32; |
|
|
|
else |
|
|
|
{ |
|
|
|
s->buf_f[4 * (y1 * img->w + x1)] = s->colorf[0]; |
|
|
|
s->buf_f[4 * (y1 * img->w + x1) + 1] = s->colorf[1]; |
|
|
|
s->buf_f[4 * (y1 * img->w + x1) + 2] = s->colorf[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(delta > 0) |
|
|
|
{ |
|
|
|
x1 += xinc; |
|
|
|
y1 += yinc; |
|
|
|
delta += dpru; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
x1 += xinc; |
|
|
|
delta += dpr; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
int dpr = dx << 1; |
|
|
|
int dpru = dpr - (dy << 1); |
|
|
|
int delta = dpr - dy; |
|
|
|
|
|
|
|
for(; dy >= 0; dy--) |
|
|
|
{ |
|
|
|
if(FLAG_GRAY) |
|
|
|
{ |
|
|
|
if(FLAG_8BIT) |
|
|
|
/* TODO */; |
|
|
|
else |
|
|
|
s->buf_f[x1 + y1 * img->w] = s->colorf[0]; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if(FLAG_8BIT) |
|
|
|
s->buf_u32[x1 + y1 * img->w] = s->color32; |
|
|
|
else |
|
|
|
{ |
|
|
|
s->buf_f[4 * (y1 * img->w + x1)] = s->colorf[0]; |
|
|
|
s->buf_f[4 * (y1 * img->w + x1) + 1] = s->colorf[1]; |
|
|
|
s->buf_f[4 * (y1 * img->w + x1) + 2] = s->colorf[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(delta > 0) |
|
|
|
{ |
|
|
|
x1 += xinc; |
|
|
|
y1 += yinc; |
|
|
|
delta += dpru; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
y1 += yinc; |
|
|
|
delta += dpr; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|