forked from old/legacy-imlib2
nice FAST gradient drawing code.... :) eat my dast... MUHAHAHAHAHHA! :)
SVN revision: 1000
This commit is contained in:
parent
837ea16fd3
commit
ced2f2026f
51
api.c
51
api.c
|
@ -20,6 +20,7 @@
|
|||
#include "api.h"
|
||||
#include <freetype.h>
|
||||
#include "font.h"
|
||||
#include "grad.h"
|
||||
|
||||
#define CAST_IMAGE(im, image) (im) = (ImlibImage *)(image)
|
||||
|
||||
|
@ -280,6 +281,11 @@ imlib_image_set_format(Imlib_Image image, char *format)
|
|||
if (im->format)
|
||||
free(im->format);
|
||||
im->format = strdup(format);
|
||||
if (!(im->flags & F_FORMAT_IRRELEVANT))
|
||||
{
|
||||
__imlib_DirtyImage(im);
|
||||
__imlib_DirtyPixmapsForImage(im);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -405,18 +411,6 @@ imlib_render_pixmaps_for_whole_image_at_size(Imlib_Image image, Display *display
|
|||
color_modifier);
|
||||
}
|
||||
|
||||
void
|
||||
imlib_free_pixmap_and_mask(Display *display, Pixmap pixmap)
|
||||
{
|
||||
ImlibImagePixmap *ip;
|
||||
|
||||
ip = __imlib_FindCachedImagePixmapByID(display, pixmap);
|
||||
if (ip)
|
||||
ip->references--;
|
||||
__imlib_CleanupImagePixmapCache();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
imlib_render_image_on_drawable(Imlib_Image image, Display *display,
|
||||
Drawable drawable, Visual *visual,
|
||||
|
@ -1454,3 +1448,36 @@ imlib_image_copy_rect(Imlib_Image image, int x, int y, int width, int height,
|
|||
CAST_IMAGE(im, image);
|
||||
__imlib_copy_image_data(im, x, y, width, height, new_x, new_y);
|
||||
}
|
||||
|
||||
Imlib_Color_Range imlib_create_color_range(void)
|
||||
{
|
||||
return (Imlib_Color_Range)__imlib_CreateRange();
|
||||
}
|
||||
|
||||
void
|
||||
imlib_free_color_range(Imlib_Color_Range color_range)
|
||||
{
|
||||
__imlib_FreeRange((ImlibRange *)color_range);
|
||||
}
|
||||
|
||||
void
|
||||
imlib_add_color_to_color_range(Imlib_Color_Range color_range,
|
||||
Imlib_Color *color,
|
||||
int distance_away)
|
||||
{
|
||||
__imlib_AddRangeColor((ImlibRange *)color_range,
|
||||
color->red, color->green, color->blue, color->alpha,
|
||||
distance_away);
|
||||
}
|
||||
|
||||
void
|
||||
imlib_image_fill_color_range_rectangle(Imlib_Image image, int x, int y,
|
||||
int width, int height,
|
||||
Imlib_Color_Range color_range,
|
||||
double angle,
|
||||
Imlib_Operation operation)
|
||||
{
|
||||
__imlib_DrawGradient((ImlibImage *)image, x, y, width, height,
|
||||
(ImlibRange *)color_range, angle,
|
||||
(ImlibOp)operation);
|
||||
}
|
||||
|
|
7
api.h
7
api.h
|
@ -13,6 +13,7 @@ typedef void * Imlib_Image;
|
|||
typedef void * Imlib_Color_Modifier;
|
||||
typedef void * Imlib_Updates;
|
||||
typedef void * Imlib_Font;
|
||||
typedef void * Imlib_Color_Range;
|
||||
typedef struct _imlib_border Imlib_Border;
|
||||
typedef struct _imlib_color Imlib_Color;
|
||||
typedef struct _imlib_rectangle Imlib_Rectangle;
|
||||
|
@ -348,11 +349,9 @@ void imlib_image_copy_rect(Imlib_Image image, int x, int y,
|
|||
int width, int height, int new_x,
|
||||
int new_y);
|
||||
|
||||
# if 0
|
||||
/* need to add arbitary rotation */
|
||||
/* polygon fills */
|
||||
|
||||
|
||||
Imlib_Color_Range imlib_create_color_range(void);
|
||||
void imlib_free_color_range(Imlib_Color_Range color_range);
|
||||
void imlib_add_color_to_color_range(Imlib_Color_Range color_range,
|
||||
|
@ -361,8 +360,10 @@ void imlib_add_color_to_color_range(Imlib_Color_Range color_range,
|
|||
void imlib_image_fill_color_range_rectangle(Imlib_Image image, int x, int y,
|
||||
int width, int height,
|
||||
Imlib_Color_Range color_range,
|
||||
double angle, double spread,
|
||||
double angle,
|
||||
Imlib_Operation operation);
|
||||
|
||||
# if 0
|
||||
/* FIXME: have to figure out generic saving mechanism that lets savers have */
|
||||
/* options like quality, color , compression etc. */
|
||||
|
||||
|
|
|
@ -0,0 +1,366 @@
|
|||
#include "common.h"
|
||||
#include "colormod.h"
|
||||
#include "file.h"
|
||||
#include "loaderpath.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <math.h>
|
||||
#include "image.h"
|
||||
#include "blend.h"
|
||||
#include "grad.h"
|
||||
|
||||
ImlibRange *
|
||||
__imlib_CreateRange(void)
|
||||
{
|
||||
ImlibRange *rg = NULL;
|
||||
|
||||
rg = malloc(sizeof(ImlibRange));
|
||||
rg->color = NULL;
|
||||
return rg;
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_FreeRange(ImlibRange *rg)
|
||||
{
|
||||
ImlibRangeColor *p, *pp;
|
||||
|
||||
p = rg->color;
|
||||
while(p)
|
||||
{
|
||||
pp = p;
|
||||
p = p->next;
|
||||
free(pp);
|
||||
}
|
||||
free(rg);
|
||||
}
|
||||
|
||||
void
|
||||
__imlib_AddRangeColor(ImlibRange *rg, DATA8 r, DATA8 g, DATA8 b, DATA8 a,
|
||||
int dist)
|
||||
{
|
||||
ImlibRangeColor *p, *rc;
|
||||
|
||||
if (dist < 1)
|
||||
dist = 1;
|
||||
if (!rg->color)
|
||||
dist = 0;
|
||||
|
||||
rc = malloc(sizeof(ImlibRangeColor));
|
||||
rc->red = r;
|
||||
rc->green = g;
|
||||
rc->blue = b;
|
||||
rc->alpha = a;
|
||||
rc->distance = 0;
|
||||
rc->next = NULL;
|
||||
|
||||
p = rg->color;
|
||||
if (p)
|
||||
{
|
||||
while (p)
|
||||
{
|
||||
if (!p->next)
|
||||
{
|
||||
p->distance = dist;
|
||||
p->next = rc;
|
||||
p = NULL;
|
||||
}
|
||||
else
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
rg->color = rc;
|
||||
}
|
||||
|
||||
DATA32 *
|
||||
__imlib_MapRange(ImlibRange *rg, int len)
|
||||
{
|
||||
ImlibRangeColor *p;
|
||||
DATA32 *map, *pmap, v, vv;
|
||||
int r, g, b, a, rr, gg, bb, aa, i, l, ll, v1, v2, inc, j;
|
||||
|
||||
if (!rg->color)
|
||||
return NULL;
|
||||
if (!rg->color->next)
|
||||
return NULL;
|
||||
ll = 1;
|
||||
for (p = rg->color; p; p = p->next)
|
||||
ll += p->distance;
|
||||
map = malloc(len * sizeof(DATA32));
|
||||
pmap = malloc(ll * sizeof(DATA32));
|
||||
i = 0;
|
||||
for (p = rg->color; p; p = p->next)
|
||||
{
|
||||
if (p->next)
|
||||
{
|
||||
for (j = 0; j < p->distance; j++)
|
||||
{
|
||||
v1 = (j << 16) / p->distance;
|
||||
v2 = 65536 - v1;
|
||||
r = ((p->red * v2) + (p->next->red * v1)) >> 16;
|
||||
g = ((p->green * v2) + (p->next->green * v1)) >> 16;
|
||||
b = ((p->blue * v2) + (p->next->blue * v1)) >> 16;
|
||||
a = ((p->alpha * v2) + (p->next->alpha * v1)) >> 16;
|
||||
pmap[i++] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = p->red;
|
||||
g = p->green;
|
||||
b = p->blue;
|
||||
a = p->alpha;
|
||||
pmap[i++] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
inc = ((ll - 1) << 16) / (len);
|
||||
l = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
v = pmap[l >> 16];
|
||||
if ((l >> 16) < ll)
|
||||
vv = pmap[(l >> 16) + 1];
|
||||
else
|
||||
vv = pmap[(l >> 16)];
|
||||
v1 = l - ((l >> 16) << 16);
|
||||
v2 = 65536 - v1;
|
||||
b = ((v) ) & 0xff;
|
||||
g = ((v) >> 8 ) & 0xff;
|
||||
r = ((v) >> 16) & 0xff;
|
||||
a = ((v) >> 24) & 0xff;
|
||||
bb = ((vv) ) & 0xff;
|
||||
gg = ((vv) >> 8 ) & 0xff;
|
||||
rr = ((vv) >> 16) & 0xff;
|
||||
aa = ((vv) >> 24) & 0xff;
|
||||
r = ((r * v2) + (rr * v1)) >> 16;
|
||||
g = ((g * v2) + (gg * v1)) >> 16;
|
||||
b = ((b * v2) + (bb * v1)) >> 16;
|
||||
a = ((a * v2) + (aa * v1)) >> 16;
|
||||
map[i] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
l += inc;
|
||||
}
|
||||
free(pmap);
|
||||
return map;
|
||||
}
|
||||
|
||||
#define BLEND(r1, g1, b1, a1, dest) \
|
||||
bb = ((dest) ) & 0xff;\
|
||||
gg = ((dest) >> 8 ) & 0xff;\
|
||||
rr = ((dest) >> 16) & 0xff;\
|
||||
aa = ((dest) >> 24) & 0xff;\
|
||||
tmp = ((r1) - rr) * (a1);\
|
||||
nr = rr + ((tmp + (tmp >> 8) + 0x80) >> 8);\
|
||||
tmp = ((g1) - gg) * (a1);\
|
||||
ng = gg + ((tmp + (tmp >> 8) + 0x80) >> 8);\
|
||||
tmp = ((b1) - bb) * (a1);\
|
||||
nb = bb + ((tmp + (tmp >> 8) + 0x80) >> 8);\
|
||||
tmp = (a1) + aa;\
|
||||
na = (tmp | ((tmp & 256) - ((tmp & 256) >> 8)));\
|
||||
(dest) = (na << 24) | (nr << 16) | (ng << 8) | nb;
|
||||
|
||||
#define BLEND_ADD(r1, g1, b1, a1, dest) \
|
||||
bb = ((dest) ) & 0xff;\
|
||||
gg = ((dest) >> 8 ) & 0xff;\
|
||||
rr = ((dest) >> 16) & 0xff;\
|
||||
aa = ((dest) >> 24) & 0xff;\
|
||||
tmp = rr + (((r1) * (a1)) >> 8);\
|
||||
nr = (tmp | ((tmp & 256) - ((tmp & 256) >> 8)));\
|
||||
tmp = gg + (((g1) * (a1)) >> 8);\
|
||||
ng = (tmp | ((tmp & 256) - ((tmp & 256) >> 8)));\
|
||||
tmp = bb + (((b1) * (a1)) >> 8);\
|
||||
nb = (tmp | ((tmp & 256) - ((tmp & 256) >> 8)));\
|
||||
tmp = (a1) + aa;\
|
||||
na = (tmp | ((tmp & 256) - ((tmp & 256) >> 8)));\
|
||||
(dest) = (na << 24) | (nr << 16) | (ng << 8) | nb;
|
||||
|
||||
#define BLEND_SUB(r1, g1, b1, a1, dest) \
|
||||
bb = ((dest) ) & 0xff;\
|
||||
gg = ((dest) >> 8 ) & 0xff;\
|
||||
rr = ((dest) >> 16) & 0xff;\
|
||||
aa = ((dest) >> 24) & 0xff;\
|
||||
tmp = rr - (((r1) * (a1)) >> 8);\
|
||||
nr = tmp & (~(tmp >> 8));\
|
||||
tmp = gg - (((g1) * (a1)) >> 8);\
|
||||
ng = tmp & (~(tmp >> 8));\
|
||||
tmp = bb - (((b1) * (a1)) >> 8);\
|
||||
nb = tmp & (~(tmp >> 8));\
|
||||
tmp = (a1) + aa;\
|
||||
na = (tmp | ((tmp & 256) - ((tmp & 256) >> 8)));\
|
||||
(dest) = (na << 24) | (nr << 16) | (ng << 8) | nb;
|
||||
|
||||
#define BLEND_RE(r1, g1, b1, a1, dest) \
|
||||
bb = ((dest) ) & 0xff;\
|
||||
gg = ((dest) >> 8 ) & 0xff;\
|
||||
rr = ((dest) >> 16) & 0xff;\
|
||||
aa = ((dest) >> 24) & 0xff;\
|
||||
tmp = rr + ((((r1) - 127) * (a1)) >> 7);\
|
||||
nr = (tmp | ((tmp & 256) - ((tmp & 256) >> 8))) & (~(tmp >> 8));\
|
||||
tmp = gg + ((((g1) - 127) * (a1)) >> 7);\
|
||||
ng = (tmp | ((tmp & 256) - ((tmp & 256) >> 8))) & (~(tmp >> 8));\
|
||||
tmp = bb + ((((b1) - 127) * (a1)) >> 7);\
|
||||
nb = (tmp | ((tmp & 256) - ((tmp & 256) >> 8))) & (~(tmp >> 8));\
|
||||
tmp = (a1) + aa;\
|
||||
na = (tmp | ((tmp & 256) - ((tmp & 256) >> 8)));\
|
||||
(dest) = (na << 24) | (nr << 16) | (ng << 8) | nb;
|
||||
|
||||
void
|
||||
__imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h,
|
||||
ImlibRange *rg, double angle, ImlibOp op)
|
||||
{
|
||||
DATA32 *map, *p, v;
|
||||
int *hlut, *vlut, len = 0, xx, yy, xoff = 0, yoff = 0, ww, hh, jump;
|
||||
int tmp, i;
|
||||
DATA8 rr, gg, bb, aa, r, g, b, a, nr, ng, nb, na;
|
||||
|
||||
ww = w;
|
||||
hh = h;
|
||||
if (x < 0)
|
||||
{
|
||||
w += x;
|
||||
xoff = -x;
|
||||
x = 0;
|
||||
}
|
||||
if (w <= 0)
|
||||
return;
|
||||
if ((x + w) > im->w)
|
||||
w = (im->w - x);
|
||||
if (w <= 0)
|
||||
return;
|
||||
if (y < 0)
|
||||
{
|
||||
h += y;
|
||||
yoff = -y;
|
||||
y = 0;
|
||||
}
|
||||
if (h <= 0)
|
||||
return;
|
||||
if ((y + h) > im->h)
|
||||
h = (im->h - y);
|
||||
if (h <= 0)
|
||||
return;
|
||||
|
||||
hlut = malloc(sizeof(int) * ww);
|
||||
vlut = malloc(sizeof(int) * hh);
|
||||
if (ww > hh)
|
||||
len = ww * 16;
|
||||
else
|
||||
len = hh * 16;
|
||||
map = __imlib_MapRange(rg, len);
|
||||
|
||||
xx = (int)(256 * sin(((angle + 180) * 2 * 3.141592654) / 360));
|
||||
yy = -(int)(256 * cos(((angle + 180) * 2 * 3.141592654) / 360));
|
||||
if (xx < 0)
|
||||
{
|
||||
for (i = 0; i < ww; i++)
|
||||
hlut[i] = ((-xx * (ww - 1 - i) * len) / (ww - 1)) >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < ww; i++)
|
||||
hlut[i] = ((xx * i * len) / (ww - 1)) >> 8;
|
||||
}
|
||||
if (yy < 0)
|
||||
{
|
||||
for (i = 0; i < hh; i++)
|
||||
vlut[i] = ((-yy * (hh - 1 - i) * len) / (hh - 1)) >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < hh; i++)
|
||||
vlut[i] = ((yy * i * len) / (hh - 1)) >> 8;
|
||||
}
|
||||
jump = im->w - w;
|
||||
p = im->data + (y * im->w) + x;
|
||||
switch (op)
|
||||
{
|
||||
case OP_COPY:
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (xx = 0; xx < w; xx++)
|
||||
{
|
||||
i = vlut[yoff + yy] + hlut[xoff + xx];
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
else if (i >= len)
|
||||
i = len - 1;
|
||||
v = map[i];
|
||||
b = ((v) ) & 0xff;
|
||||
g = ((v) >> 8 ) & 0xff;
|
||||
r = ((v) >> 16) & 0xff;
|
||||
a = ((v) >> 24) & 0xff;
|
||||
BLEND(r, g, b, a, *p);
|
||||
p++;
|
||||
}
|
||||
p += jump;
|
||||
}
|
||||
break;
|
||||
case OP_ADD:
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (xx = 0; xx < w; xx++)
|
||||
{
|
||||
i = vlut[yoff + yy] + hlut[xoff + xx];
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
else if (i >= len)
|
||||
i = len - 1;
|
||||
v = map[i];
|
||||
b = ((v) ) & 0xff;
|
||||
g = ((v) >> 8 ) & 0xff;
|
||||
r = ((v) >> 16) & 0xff;
|
||||
a = ((v) >> 24) & 0xff;
|
||||
BLEND_SUB(r, g, b, a, *p);
|
||||
p++;
|
||||
}
|
||||
p += jump;
|
||||
}
|
||||
break;
|
||||
case OP_SUBTRACT:
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (xx = 0; xx < w; xx++)
|
||||
{
|
||||
i = vlut[yoff + yy] + hlut[xoff + xx];
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
else if (i >= len)
|
||||
i = len - 1;
|
||||
v = map[i];
|
||||
b = ((v) ) & 0xff;
|
||||
g = ((v) >> 8 ) & 0xff;
|
||||
r = ((v) >> 16) & 0xff;
|
||||
a = ((v) >> 24) & 0xff;
|
||||
BLEND_SUB(r, g, b, a, *p);
|
||||
p++;
|
||||
}
|
||||
p += jump;
|
||||
}
|
||||
break;
|
||||
case OP_RESHADE:
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (xx = 0; xx < w; xx++)
|
||||
{
|
||||
i = vlut[yoff + yy] + hlut[xoff + xx];
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
else if (i >= len)
|
||||
i = len - 1;
|
||||
v = map[i];
|
||||
b = ((v) ) & 0xff;
|
||||
g = ((v) >> 8 ) & 0xff;
|
||||
r = ((v) >> 16) & 0xff;
|
||||
a = ((v) >> 24) & 0xff;
|
||||
BLEND_RE(r, g, b, a, *p);
|
||||
p++;
|
||||
}
|
||||
p += jump;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free(vlut);
|
||||
free(hlut);
|
||||
free(map);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef __GRAD
|
||||
#define __GRAD 1
|
||||
|
||||
typedef struct _imlib_range ImlibRange;
|
||||
typedef struct _imlib_range_color ImlibRangeColor;
|
||||
|
||||
struct _imlib_range_color
|
||||
{
|
||||
DATA8 red, green, blue, alpha;
|
||||
int distance;
|
||||
ImlibRangeColor *next;
|
||||
};
|
||||
|
||||
struct _imlib_range
|
||||
{
|
||||
ImlibRangeColor *color;
|
||||
};
|
||||
|
||||
ImlibRange *__imlib_CreateRange(void);
|
||||
void __imlib_FreeRange(ImlibRange *rg);
|
||||
void __imlib_AddRangeColor(ImlibRange *rg, DATA8 r, DATA8 g, DATA8 b,
|
||||
DATA8 a, int dist);
|
||||
DATA32 *__imlib_MapRange(ImlibRange *rg, int len);
|
||||
void __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, ImlibRange *rg, double angle, ImlibOp op);
|
||||
|
||||
#endif
|
26
main.c
26
main.c
|
@ -296,19 +296,27 @@ int main (int argc, char **argv)
|
|||
}
|
||||
#endif
|
||||
{
|
||||
void *rg = NULL;;
|
||||
Imlib_Color_Range rg = NULL;
|
||||
|
||||
if (!rg)
|
||||
{
|
||||
rg = __imlib_CreateRange();
|
||||
__imlib_AddRangeColor(rg, 255, 255, 255, 255, 0);
|
||||
__imlib_AddRangeColor(rg, 255, 255, 160, 200, 1);
|
||||
__imlib_AddRangeColor(rg, 255, 160, 120, 140, 1);
|
||||
__imlib_AddRangeColor(rg, 100, 80, 100, 80, 1);
|
||||
__imlib_AddRangeColor(rg, 32, 48, 80, 0, 1);
|
||||
Imlib_Color cl;
|
||||
|
||||
rg = imlib_create_color_range();
|
||||
cl.red = 255; cl.green = 255; cl.blue = 255; cl.alpha = 255;
|
||||
imlib_add_color_to_color_range(rg, &cl, 0);
|
||||
cl.red = 255; cl.green = 255; cl.blue = 160; cl.alpha = 200;
|
||||
imlib_add_color_to_color_range(rg, &cl, 1);
|
||||
cl.red = 255; cl.green = 160; cl.blue = 120; cl.alpha = 140;
|
||||
imlib_add_color_to_color_range(rg, &cl, 1);
|
||||
cl.red = 100; cl.green = 80; cl.blue = 100; cl.alpha = 80;
|
||||
imlib_add_color_to_color_range(rg, &cl, 1);
|
||||
cl.red = 32; cl.green = 48; cl.blue = 80; cl.alpha = 0;
|
||||
imlib_add_color_to_color_range(rg, &cl, 1);
|
||||
}
|
||||
__imlib_DrawGradient(im, 30, 30, 256, 256, rg, (double)x,
|
||||
IMLIB_OP_COPY);
|
||||
imlib_image_fill_color_range_rectangle(im, 30, 30, 256, 256,
|
||||
rg, (double)x,
|
||||
IMLIB_OP_COPY);
|
||||
up = imlib_update_append_rect(up, 40, 40, 256, 256);
|
||||
}
|
||||
if (fon)
|
||||
|
|
Loading…
Reference in New Issue