Browse Source

* line.c: convert the aliased line drawing to the template system.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2795 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam 16 years ago
parent
commit
39865db8bd
3 changed files with 119 additions and 100 deletions
  1. +1
    -1
      pipi/Makefile.am
  2. +118
    -42
      pipi/paint/line.c
  3. +0
    -57
      pipi/paint/line_template.h

+ 1
- 1
pipi/Makefile.am View File

@@ -44,7 +44,7 @@ codec_sources =
# Submodules
paint_sources = \
paint/floodfill.c \
paint/line.c paint/line_template.h paint/aline_template.h \
paint/line.c paint/aline_template.h \
paint/bezier.c \
paint/tile.c



+ 118
- 42
pipi/paint/line.c View File

@@ -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


+ 0
- 57
pipi/paint/line_template.h View File

@@ -1,57 +0,0 @@
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--)
{
ASSIGN(x1, y1, img->w);

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--)
{
ASSIGN(x1, y1, img->w);
if(delta > 0)
{
x1 += xinc;
y1 += yinc;
delta += dpru;
}
else
{
y1 += yinc;
delta += dpr;
}
}
}

Loading…
Cancel
Save