|
|
@@ -48,10 +48,12 @@ 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 pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t c, int aa) |
|
|
|
{ |
|
|
|
struct line s; |
|
|
|
s.x1 = x1; |
|
|
@@ -59,28 +61,45 @@ int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t |
|
|
|
s.x2 = x2; |
|
|
|
s.y2 = y2; |
|
|
|
|
|
|
|
if(img->last_modified == PIPI_PIXELS_RGBA_C) { |
|
|
|
uint32_t *dstdata; |
|
|
|
dstdata = (uint32_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels; |
|
|
|
s.color32 = c; |
|
|
|
s.buf_u32 = dstdata; |
|
|
|
s.draw = draw_aliased_line_u32; |
|
|
|
} else if(img->last_modified == PIPI_PIXELS_Y_F) { |
|
|
|
/* No Transparency routine for u32 yet, fallback to float version */ |
|
|
|
if(img->last_modified == PIPI_PIXELS_RGBA_C) |
|
|
|
{ |
|
|
|
if(!aa) |
|
|
|
{ |
|
|
|
uint32_t *dstdata; |
|
|
|
dstdata = (uint32_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels; |
|
|
|
s.color32 = c; |
|
|
|
s.buf_u32 = dstdata; |
|
|
|
s.draw = draw_aliased_line_u32; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
float *dstdata; |
|
|
|
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_RGBA_F)->pixels; |
|
|
|
s.colorf[2] = ((c&0x00FF0000)>>16)/255.0f; /* XXX FIXME */ |
|
|
|
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 = draw_antialiased_line_float; |
|
|
|
} |
|
|
|
} |
|
|
|
else if(img->last_modified == PIPI_PIXELS_Y_F) |
|
|
|
{ |
|
|
|
float *dstdata; |
|
|
|
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_Y_F)->pixels; |
|
|
|
s.colorf[0] = c/255.0f; /* XXX FIXME */ |
|
|
|
s.buf_f = dstdata; |
|
|
|
s.draw = draw_aliased_line_gray; |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
s.draw = aa==0?draw_aliased_line_gray:draw_antialiased_line_gray; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
float *dstdata; |
|
|
|
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_RGBA_F)->pixels; |
|
|
|
s.colorf[0] = (c&0x00FF0000)/255.0f; /* XXX FIXME */ |
|
|
|
s.colorf[1] = (c&0x0000FF00)/255.0f; /* XXX FIXME */ |
|
|
|
s.colorf[2] = (c&0x000000FF)/255.0f; /* XXX FIXME */ |
|
|
|
s.colorf[2] = ((c&0x00FF0000)>>16)/255.0f; /* XXX FIXME */ |
|
|
|
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 = draw_aliased_line_float; |
|
|
|
s.draw = aa==0?draw_aliased_line_float:draw_antialiased_line_float; |
|
|
|
} |
|
|
|
|
|
|
|
clip_line(img, &s); |
|
|
@@ -94,13 +113,16 @@ int pipi_draw_polyline(pipi_image_t *img, int const x[], int const y[], |
|
|
|
int i; |
|
|
|
struct line s; |
|
|
|
|
|
|
|
if(img->last_modified == PIPI_PIXELS_RGBA_C) { |
|
|
|
if(img->last_modified == PIPI_PIXELS_RGBA_C) |
|
|
|
{ |
|
|
|
uint32_t *dstdata; |
|
|
|
dstdata = (uint32_t *)pipi_getpixels(img, PIPI_PIXELS_RGBA_C)->pixels; |
|
|
|
s.color32 = c; |
|
|
|
s.buf_u32 = dstdata; |
|
|
|
s.draw = draw_aliased_line_u32; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
float *dstdata; |
|
|
|
dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_RGBA_F)->pixels; |
|
|
|
s.colorf[0] = (c&0x00FF0000)/255.0f; /* XXX FIXME */ |
|
|
@@ -204,21 +226,53 @@ static uint8_t clip_bits(pipi_image_t *img, int x, int y) |
|
|
|
* 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.c" |
|
|
|
#undef ASSIGN |
|
|
|
#define ASSIGN(x, y, w) s->buf_u32[x+y*w] = s->color32; |
|
|
|
#include "line_template.c" |
|
|
|
} |
|
|
|
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]; \ |
|
|
|
#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.c" |
|
|
|
#include "line_template.c" |
|
|
|
} |
|
|
|
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.c" |
|
|
|
#undef ASSIGN |
|
|
|
#define ASSIGN(x, y, w) s->buf_f[x+y*w] = s->colorf[0]; |
|
|
|
#include "line_template.c" |
|
|
|
} |
|
|
|
|
|
|
|
/* Xiaolin Wu's line algorithm, as seen at http://portal.acm.org/citation.cfm?id=122734 */ |
|
|
|
|
|
|
|
/* math.h doesn't like y0 (sucker) */ |
|
|
|
float floorf(float x); |
|
|
|
float truncf(float x); |
|
|
|
float fabsf(float x); |
|
|
|
static float fractf(float d) { return (d - floorf(d)); } |
|
|
|
static float fractinvf(float d) { return (1 - (d - floorf(d))); } |
|
|
|
|
|
|
|
static void draw_antialiased_line_float(pipi_image_t *img, struct line* s) |
|
|
|
{ |
|
|
|
/* Is that an horrible mess ? Yes, it is. */ |
|
|
|
#undef PLOT |
|
|
|
#define PLOT(x, y, c) \ |
|
|
|
s->buf_f[(((int)(x)*4))+((int)(y))*(img->w*4)] = \ |
|
|
|
(c*s->colorf[0]) + (1-c) * s->buf_f[(((int)(x)*4))+((int)(y))*(img->w*4)]; \ |
|
|
|
s->buf_f[(1+((int)(x)*4))+((int)(y))*(img->w*4)] = \ |
|
|
|
(c*s->colorf[1]) + (1-c) * s->buf_f[(1+((int)(x)*4))+((int)(y))*(img->w*4)]; \ |
|
|
|
s->buf_f[(2+((int)(x)*4))+((int)(y))*(img->w*4)] = \ |
|
|
|
(c*s->colorf[2]) + (1-c) * s->buf_f[(2+((int)(x)*4))+((int)(y))*(img->w*4)]; |
|
|
|
#include "aline_template.c" |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void draw_antialiased_line_gray(pipi_image_t *img, struct line* s) |
|
|
|
{ |
|
|
|
#undef PLOT |
|
|
|
#define PLOT(x, y, c) s->buf_f[((int)(x))+((int)(y))*img->w] = \ |
|
|
|
(c*s->colorf[0]) + (1-c) * s->buf_f[((int)(x))+((int)(y))*img->w]; |
|
|
|
#include "aline_template.c" |
|
|
|
} |