Changeset 2798 for libpipi


Ignore:
Timestamp:
Aug 29, 2008, 12:00:18 AM (12 years ago)
Author:
Sam Hocevar
Message:
  • line.c: merge the antialiased line template back into line.c.
Location:
libpipi/trunk/pipi
Files:
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • libpipi/trunk/pipi/Makefile.am

    r2795 r2798  
    4545paint_sources = \
    4646        paint/floodfill.c \
    47         paint/line.c paint/aline_template.h \
     47        paint/line.c \
    4848        paint/bezier.c \
    4949        paint/tile.c
  • libpipi/trunk/pipi/paint/line.c

    r2795 r2798  
    3232#include "pipi_internals.h"
    3333
     34/* math.h doesn't like y1 (sucker) */
     35float floorf(float x);
     36float truncf(float x);
     37float fabsf(float x);
     38
    3439#if !defined TEMPLATE_FILE /* This file uses the template system */
     40
     41static float fractf(float d) { return (d - floorf(d)); }
     42static float fractinvf(float d) { return (1 - (d - floorf(d))); }
    3543
    3644struct line
     
    5765static void clip_line(pipi_image_t*, struct line*);
    5866static uint8_t clip_bits(pipi_image_t*, int, int);
    59 static void draw_antialiased_line_float(pipi_image_t *img, struct line* s);
    60 static void draw_antialiased_line_gray(pipi_image_t *img, struct line* s);
    6167
    6268int pipi_draw_line(pipi_image_t *img , int x1, int y1, int x2, int y2, uint32_t c, int aa)
     
    8793            s.colorf[0] = (c&0x000000FF)/255.0f;       /* XXX FIXME */
    8894            s.buf_f = dstdata;
    89             s.draw = draw_antialiased_line_float;
     95            s.draw = antialiased_line;
    9096        }
    9197    }
     
    96102        s.colorf[0] = (c & 0xff) / 255.0f; /* XXX FIXME */
    97103        s.buf_f = dstdata;
    98         s.draw = aa==0?aliased_line_gray:draw_antialiased_line_gray;
     104        s.draw = aa == 0 ? aliased_line_gray : antialiased_line_gray;
    99105    }
    100106    else
     
    106112        s.colorf[0] = (c&0x000000FF)/255.0f;       /* XXX FIXME */
    107113        s.buf_f = dstdata;
    108         s.draw = aa==0?aliased_line:draw_antialiased_line_float;
     114        s.draw = aa == 0 ? aliased_line : antialiased_line;
    109115    }
    110116
     
    138144            s.colorf[0] = (c&0x000000FF)/255.0f;       /* XXX FIXME */
    139145            s.buf_f = dstdata;
    140             s.draw = draw_antialiased_line_float;
     146            s.draw = antialiased_line;
    141147        }
    142148    }
     
    145151        float  *dstdata;
    146152        dstdata = (float *)pipi_getpixels(img, PIPI_PIXELS_Y_F)->pixels;
    147         s.colorf[0] = c/255.0f; /* XXX FIXME */
     153        s.colorf[0] = (c & 0xff) / 255.0f; /* XXX FIXME */
    148154        s.buf_f = dstdata;
    149         s.draw = aa==0?aliased_line_gray:draw_antialiased_line_gray;
     155        s.draw = aa == 0 ? aliased_line_gray : antialiased_line_gray;
    150156    }
    151157    else
     
    157163        s.colorf[2] = (c&0x000000FF)/255.0f; /* XXX FIXME */
    158164        s.buf_f = dstdata;
    159         s.draw = aa==0?aliased_line:draw_antialiased_line_float;
     165        s.draw = aa == 0 ? aliased_line : antialiased_line;
    160166        img->last_modified = PIPI_PIXELS_RGBA_F;
    161167    }
     
    245251}
    246252
     253#else /* XXX: the following functions use the template system */
     254
    247255/* Xiaolin Wu's line algorithm, as seen at http://portal.acm.org/citation.cfm?id=122734 */
    248256
    249 /* math.h doesn't like y1 (sucker) */
    250 float floorf(float x);
    251 float truncf(float x);
    252 float fabsf(float x);
    253 
    254 static float fractf(float d) { return (d - floorf(d)); }
    255 static float fractinvf(float d) { return (1 - (d - floorf(d))); }
    256 
    257 static void draw_antialiased_line_float(pipi_image_t *img, struct line* s)
    258 {
    259 /* Is that an horrible mess ? Yes, it is. */
    260 #undef  PLOT
    261 #define PLOT(x, y, c)  \
    262     { int qwer = (((int)(x)*4))+((int)(y))*(img->w*4);\
    263       int qweg = (1+((int)(x)*4))+((int)(y))*(img->w*4); \
    264       int qweb = (2+((int)(x)*4))+((int)(y))*(img->w*4); \
    265     s->buf_f[qwer] = (c*s->colorf[0]) + (1-c) * s->buf_f[qwer]; \
    266     s->buf_f[qweg] = (c*s->colorf[1]) + (1-c) * s->buf_f[qweg]; \
    267     s->buf_f[qweb] = (c*s->colorf[2]) + (1-c) * s->buf_f[qweb]; \
    268     if(s->buf_f[qwer] > 1.0f) s->buf_f[qwer] = 1.0f; \
    269     if(s->buf_f[qwer] < 0.0f || isnan(s->buf_f[qwer])) s->buf_f[qwer] = 0.0f; \
    270     if(s->buf_f[qweg] > 1.0f) s->buf_f[qweg] = 1.0f; \
    271     if(s->buf_f[qweg] < 0.0f || isnan(s->buf_f[qweg])) s->buf_f[qweg] = 0.0f; \
    272     if(s->buf_f[qweb] > 1.0f) s->buf_f[qweb] = 1.0f; \
    273     if(s->buf_f[qweb] < 0.0f || isnan(s->buf_f[qweb])) s->buf_f[qweb] = 0.0f;  }
    274 
    275 #include "aline_template.h"
     257#define PLOT(x, y, c) \
     258    if(FLAG_GRAY) \
     259    { \
     260        if(FLAG_8BIT) \
     261        { \
     262            /* TODO */ \
     263        } \
     264        else \
     265        { \
     266            s->buf_f[((int)(x))+((int)(y))*img->w] =  \
     267            (c*s->colorf[0]) + (1-c) * s->buf_f[((int)(x))+((int)(y))*img->w]; \
     268            if(s->buf_f[((int)(x))+((int)(y))*img->w] > 1.0f) \
     269                s->buf_f[((int)(x))+((int)(y))*img->w] = 1.0f; \
     270            if(s->buf_f[((int)(x))+((int)(y))*img->w] < 0.0f) \
     271                s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f; \
     272            if(isnan(s->buf_f[((int)(x))+((int)(y))*img->w])) \
     273                s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f; \
     274        } \
     275    } \
     276    else \
     277    { \
     278        if(FLAG_8BIT) \
     279        { \
     280            /* TODO */ \
     281        } \
     282        else \
     283        { \
     284            int qwer = (((int)(x)*4))+((int)(y))*(img->w*4);\
     285            int qweg = (1+((int)(x)*4))+((int)(y))*(img->w*4); \
     286            int qweb = (2+((int)(x)*4))+((int)(y))*(img->w*4); \
     287            s->buf_f[qwer] = (c*s->colorf[0]) + (1-c) * s->buf_f[qwer]; \
     288            s->buf_f[qweg] = (c*s->colorf[1]) + (1-c) * s->buf_f[qweg]; \
     289            s->buf_f[qweb] = (c*s->colorf[2]) + (1-c) * s->buf_f[qweb]; \
     290            if(s->buf_f[qwer] > 1.0f) \
     291                s->buf_f[qwer] = 1.0f; \
     292            if(s->buf_f[qwer] < 0.0f || isnan(s->buf_f[qwer])) \
     293                s->buf_f[qwer] = 0.0f; \
     294            if(s->buf_f[qweg] > 1.0f) \
     295                s->buf_f[qweg] = 1.0f; \
     296            if(s->buf_f[qweg] < 0.0f || isnan(s->buf_f[qweg])) \
     297                s->buf_f[qweg] = 0.0f; \
     298            if(s->buf_f[qweb] > 1.0f) \
     299                s->buf_f[qweb] = 1.0f; \
     300            if(s->buf_f[qweb] < 0.0f || isnan(s->buf_f[qweb])) \
     301                s->buf_f[qweb] = 0.0f; \
     302        } \
     303    }
     304
     305static void SUFFIX(antialiased_line)(pipi_image_t *img, struct line* s)
     306{
     307    float x1 = s->x1, y1 = s->y1, x2 = s->x2, y2 = s->y2;
     308    float g, xd, yd, xgap, xend, yend, xf, yf, val1, val2;
     309    int x, y, ix1, ix2, iy1, iy2;
     310
     311    xd = x2 - x1;
     312    yd = y2 - y1;
     313
     314    /* "Horizontal" line (X greater than Y)*/
     315    if (fabsf(xd) > fabsf(yd))
     316    {
     317        if (x1 > x2)
     318        {
     319            float tmp;
     320            tmp = x1; x1 = x2; x2 = tmp;
     321            tmp = y1; y1 = y2; y2 = tmp;
     322            xd = (x2-x1);
     323            yd = (y2-y1);
     324        }
     325        g = yd/xd;
     326
     327        xend = truncf(x1+0.5);
     328        yend = y1 + g*(xend-x1);
     329        xgap = fractinvf(x1+0.5);
     330        ix1 = (int)xend;
     331        iy1 = (int)yend;
     332        val1 = fractinvf(yend)*xgap;
     333        val2 = fractf(yend)*xgap;
     334
     335        PLOT(ix1, iy1,   val1);
     336        PLOT(ix1, (iy1+1)<y1?(iy1+1):iy1, val2);
     337
     338        yf = yend+g;
     339        xend = truncf(x2+0.5);
     340        yend = y2 + g*(xend-x2);
     341        xgap = fractinvf(x2-0.5);
     342        ix2 = (int)xend;
     343        iy2 = (int)yend;
     344        val1 = fractinvf(yend)*xgap;
     345        val2 = fractf(yend)*xgap;
     346
     347        PLOT(ix2, iy2,   val1);
     348        PLOT(ix2, iy2+1<y2?iy2+1:iy2, val2);
     349
     350        for (x = (ix1+1); x < ix2; x++)
     351        {
     352            float focus;
     353
     354            val1 = fractinvf(yf);
     355            val2 = fractf(yf);
     356            focus = (1.0 - fabsf(val1-val2));
     357            val1 += 0.3*focus;
     358            val2 += 0.3*focus;
     359
     360            PLOT(x, yf, val1);
     361            PLOT(x, (yf+1)<y1?(yf+1):yf, val2);
     362
     363            yf = yf + g;
     364        }
     365    }
     366    /* "Vertical" line (Y greater than X)*/
     367    else
     368    {
     369        if (x1 > x2)
     370        {
     371            float tmp;
     372            tmp = x1; x1 = x2; x2 = tmp;
     373            tmp = y1; y1 = y2; y2 = tmp;
     374            xd = (x2-x1);
     375            yd = (y2-y1);
     376        }
     377
     378        g = xd/yd;
     379
     380        xend = truncf(x1+0.5);
     381        yend = y1 + g*(xend-x1);
     382        xgap = fractf(x1+0.5);
     383        ix1 = (int)xend;
     384        iy1 = (int)yend;
     385        val1 = fractinvf(yend)*xgap;
     386        val2 = fractf(yend)*xgap;
     387
     388        PLOT(ix1, iy1, val1);
     389        PLOT(ix1, (iy1+1)<y1?(iy1+1):iy1, val2);
     390
     391        xf = xend + g;
     392
     393        xend = truncf(x2+0.5);
     394        yend = y2 + g*(xend-x2);
     395        xgap = fractinvf(x2-0.5);
     396        ix2 = (int)xend;
     397        iy2 = (int)yend;
     398        val1 = fractinvf(yend)*xgap;
     399        val2 = fractf(yend)*xgap;
     400
     401        PLOT(ix2, iy2,   val1);
     402        PLOT(ix2, (iy2+1)<y2?(iy2+1):iy2, val2);
     403
     404
     405        for (y = (iy1+1); y < iy2; y++)
     406        {
     407            float focus;
     408            int   vx = xf;
     409            val1 = fractinvf(xf);
     410            val2 = fractf(xf);
     411            focus = (1.0 - fabsf(val1-val2));
     412            val1 += 0.3*focus;
     413            val2 += 0.3*focus;
     414            PLOT(vx, y, val1);
     415            vx++;
     416            PLOT(vx, y, val2);
     417            xf = xf + g;
     418        }
     419    }
    276420}
    277421
    278 
    279 static void draw_antialiased_line_gray(pipi_image_t *img, struct line* s)
    280 {
    281 #undef  PLOT
    282 #define PLOT(x, y, c) s->buf_f[((int)(x))+((int)(y))*img->w] =  \
    283     (c*s->colorf[0]) + (1-c) * s->buf_f[((int)(x))+((int)(y))*img->w]; \
    284     if(s->buf_f[((int)(x))+((int)(y))*img->w] > 1.0f) s->buf_f[((int)(x))+((int)(y))*img->w] = 1.0f; \
    285     if(s->buf_f[((int)(x))+((int)(y))*img->w] < 0.0f) s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f; \
    286     if(isnan(s->buf_f[((int)(x))+((int)(y))*img->w])) s->buf_f[((int)(x))+((int)(y))*img->w] = 0.0f;
    287 
    288 #include "aline_template.h"
    289 }
    290 
    291 #else /* XXX: the following functions use the template system */
     422#undef PLOT
    292423
    293424/* Solid line drawing function, using Bresenham's mid-point line
Note: See TracChangeset for help on using the changeset viewer.