diff --git a/Makefile b/Makefile index b63a509..f915748 100644 --- a/Makefile +++ b/Makefile @@ -100,7 +100,7 @@ jpeg_la_LDFLAGS = -no-undefined -module -avoid-version jpeg_la_LIBADD = -ljpeg bin_PROGRAMS = imlib2 -imlib2_SOURCES = rend.c ximage.c scale.c main.c rgba.c image.c color.c grab.c blend.c file.c rgbadraw.c api.c draw.c context.c +imlib2_SOURCES = rend.c ximage.c scale.c main.c rgba.c image.c color.c grab.c blend.c file.c rgbadraw.c api.c draw.c context.c updates.c imlib2_LDADD = -export-dynamic $(top_builddir)/libltdl/libltdlc.la -lX11 -lXext @@ -122,7 +122,7 @@ jpeg_la_OBJECTS = loader_jpeg.lo PROGRAMS = $(bin_PROGRAMS) imlib2_OBJECTS = rend.o ximage.o scale.o main.o rgba.o image.o color.o \ -grab.o blend.o file.o rgbadraw.o api.o draw.o context.o +grab.o blend.o file.o rgbadraw.o api.o draw.o context.o updates.o imlib2_DEPENDENCIES = $(top_builddir)/libltdl/libltdlc.la imlib2_LDFLAGS = CFLAGS = -O6 -mpentiumpro -mcpu=pentiumpro -march=pentiumpro -malign-loops=2 -malign-jumps=2 -malign-functions=2 -g -W -Wall -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith @@ -142,7 +142,8 @@ GZIP_ENV = --best DEP_FILES = .deps/api.P .deps/blend.P .deps/color.P .deps/context.P \ .deps/draw.P .deps/file.P .deps/grab.P .deps/image.P \ .deps/loader_jpeg.P .deps/loader_png.P .deps/main.P .deps/rend.P \ -.deps/rgba.P .deps/rgbadraw.P .deps/scale.P .deps/ximage.P +.deps/rgba.P .deps/rgbadraw.P .deps/scale.P .deps/updates.P \ +.deps/ximage.P SOURCES = $(png_la_SOURCES) $(jpeg_la_SOURCES) $(imlib2_SOURCES) OBJECTS = $(png_la_OBJECTS) $(jpeg_la_OBJECTS) $(imlib2_OBJECTS) diff --git a/Makefile.am b/Makefile.am index 145485f..e881a3c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -27,7 +27,7 @@ jpeg_la_LIBADD = -ljpeg bin_PROGRAMS = imlib2 imlib2_SOURCES = rend.c ximage.c scale.c main.c rgba.c image.c \ color.c grab.c blend.c file.c rgbadraw.c api.c draw.c \ - context.c + context.c updates.c imlib2_LDADD = @DLLDFLAGS@ $(top_builddir)/libltdl/libltdlc.la -lX11 -lXext SYS_LOADERS_PATH = @pkglibdir@ diff --git a/api.c b/api.c index 344d13b..6da9ee2 100644 --- a/api.c +++ b/api.c @@ -1,4 +1,6 @@ #include +#include +#include #include "common.h" #include "scale.h" #include "image.h" @@ -455,6 +457,97 @@ imlib_create_image_from_drawable(Display *display, return (Imlib_Image)im; } +Imlib_Image +imlib_create_scaled_image_from_drawable(Display *display, + Drawable drawable, + Pixmap mask, Visual *visual, + Colormap colormap, int depth, + int source_x, int source_y, + int source_width, int source_height, + int destination_width, int destination_height, + char need_to_grab_x, + char get_mask_from_shape) +{ + ImlibImage *im; + char domask = 0, tmpmask = 0; + int x, xx; + XGCValues gcv; + GC gc, mgc; + Pixmap p, m; + + if ((mask) || (get_mask_from_shape)) + domask = 1; + p = XCreatePixmap(display, drawable, destination_width, + source_height, depth); + gcv.foreground = 0; + gcv.subwindow_mode = IncludeInferiors; + if (domask) + { + m = XCreatePixmap(display, drawable, destination_width, + source_height, 1); + mgc = XCreateGC(display, m, GCForeground, &gcv); + } + else + m = None; + gc = XCreateGC(display, drawable, GCSubwindowMode, &gcv); + if ((domask) && (!mask)) + { + XRectangle *rect; + int rect_num, rect_ord; + + tmpmask = 1; + mask = XCreatePixmap(display, drawable, source_width, + source_height, 1); + rect = XShapeGetRectangles(display, drawable, ShapeBounding, &rect_num, &rect_ord); + XFillRectangle(display, mask, mgc, 0, 0, source_width, source_height); + if (rect) + { + XSetForeground(display, mgc, 1); + for (x = 0; x < rect_num; x++) + XFillRectangle(display, mask, mgc, rect[x].x, rect[x].y, + rect[x].width, rect[x].height); + XFree(rect); + } + /* build mask from window shape rects */ + } + for (x = 0; x < destination_width; x++) + { + xx = (source_width * x) / destination_width; + XCopyArea(display, drawable, p, gc, source_x + xx, 0, 1, source_height, + xx, 0); + if (m != None) + XCopyArea(display, mask, m, mgc, xx, 0, 1, source_height, + xx, 0); + } + for (x = 0; x < destination_height; x++) + { + xx = (source_height * x) / destination_height; + XCopyArea(display, drawable, p, gc, 0, source_y + xx, destination_width, 1, + 0, xx); + if (m != None) + XCopyArea(display, mask, m, mgc, 0, source_y + xx, destination_width, 1, + 0, xx); + } + im = __imlib_CreateImage(destination_width, destination_height, NULL); + im->data = malloc(destination_width * destination_height * sizeof(DATA32)); + __imlib_GrabDrawableToRGBA(im->data, 0, 0, destination_width, + destination_height, + display, p, m, visual, + colormap, depth, 0, 0, source_width, + source_height, + domask, need_to_grab_x); + XFreePixmap(display, p); + if (m != None) + { + XFreeGC(display, mgc); + XFreePixmap(display, m); + if (tmpmask) + XFreePixmap(display, mask); + } + XFreeGC(display, gc); + return (Imlib_Image)im; +} + char imlib_copy_drawable_to_image(Imlib_Image image, Display *display, Drawable drawable, Pixmap mask, Visual *visual, diff --git a/api.h b/api.h index 30caea4..dd75b45 100644 --- a/api.h +++ b/api.h @@ -125,24 +125,6 @@ void imlib_blend_image_onto_image(Imlib_Image source_image, Imlib_Color_Modifier color_modifier, Imlib_Operation operation); -#if 0 - -/* FIXME: */ -/* draw line, polygon, rect - with option of drawing in rgb or alpha or both */ -/* apply alpha of one image to another */ -void imlib_image_updates_reset(Imlib_Image image); -void imlib_image_updates_flush_to_drawable(Imlib_Image image, Display *display, - Drawable drawable, Visual *visual, - Colormap colormap, int depth, - char dithered_rendering, - char alpha_blending, - int x, int y, - int width, int height, - Imlib_Color_Modifier color_modifier); -void imlibimage_updates_add(Imlib_Image image, int x, int y, - int width, int height); - -#endif /* image creation and grabbing */ Imlib_Image imlib_create_image(int width, int height); @@ -157,6 +139,20 @@ Imlib_Image imlib_create_image_from_drawable(Display *display, int x, int y, int width, int height, char need_to_grab_x); +Imlib_Image imlib_create_scaled_image_from_drawable(Display *display, + Drawable drawable, + Pixmap mask, + Visual *visual, + Colormap colormap, + int depth, + int source_x, + int source_y, + int source_width, + int source_height, + int destination_width, + int destination_height, + char need_to_grab_x, + char get_mask_from_shape); Imlib_Image imlib_clone_image(Imlib_Image image); char imlib_copy_drawable_to_image(Imlib_Image image, Display *display, Drawable drawable, @@ -185,7 +181,8 @@ Imlib_Image imlib_create_cropped_scaled_image(Imlib_Image image, /* Imlib_image imlib_create_image_from_xpm_data(unsigned char *data);*/ /* color stuff */ -int imlib_match_color(int red, int green, int blue); +int imlib_match_color(Display *displpay, Visual *visual, Colormap colormap, + int red, int green, int blue); /* image modification - color */ Imlib_Color_Modifier imlib_create_color_modifier(void); diff --git a/blend.c b/blend.c index 3c35a75..4cff23e 100644 --- a/blend.c +++ b/blend.c @@ -709,7 +709,7 @@ __imlib_ReCopyRGBAToRGBA(DATA32 *src, int src_jump, DATA32 *dst, int dst_jump, #define LINESIZE 16 #define CLIP(x, y, w, h, xx, yy, ww, hh) \ if (x < xx) {w += x; x = xx;} \ -if (y < yy) {h += y; y = xx;} \ +if (y < yy) {h += y; y = yy;} \ if ((x + w) > ww) {w = ww - x;} \ if ((y + h) > hh) {h = hh - y;} diff --git a/rend.c b/rend.c index 2685d79..6945703 100644 --- a/rend.c +++ b/rend.c @@ -17,7 +17,7 @@ /* useful macro */ #define CLIP(x, y, w, h, xx, yy, ww, hh) \ if (x < xx) {w += x; x = xx;} \ -if (y < yy) {h += y; y = xx;} \ +if (y < yy) {h += y; y = yy;} \ if ((x + w) > ww) {w = ww - x;} \ if ((y + h) > hh) {h = hh - y;} diff --git a/updates.c b/updates.c new file mode 100644 index 0000000..bc6b1f5 --- /dev/null +++ b/updates.c @@ -0,0 +1,122 @@ +#include "common.h" +#include "updates.h" + +enum _t_used +{ + T_UNUSED = 0, + T_USED = 1, + T_SPAN_H = 2, + T_SPAN_V = 4 +}; + +struct _tile +{ + enum _t_used used; + int min_x, min_y, max_x, max_y; +}; + +#define TB 5 +#define TM 31 +#define TS 32 +#define T(x, y) t[((y) * tw) + (x)] +#define CLIP(x, y, w, h, xx, yy, ww, hh) \ +if (x < xx) {w += x; x = xx;} \ +if (y < yy) {h += y; y = yy;} \ +if ((x + w) > ww) {w = ww - x;} \ +if ((y + h) > hh) {h = hh - y;} +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +ImlibUpdate * +__imlib_MergeUpdate(ImlibUpdate *u, int w, int h) +{ + ImlibUpdate *nu = NULL, *uu; + struct _tile *t; + int tw, th, x, y, i; + + /* if theres only one rect - retunr it - no point cleaning up 1 rect */ + if (!u->next) + return u; + tw = w >> TB; + if (w & TM) + tw++; + th = h >> TB; + if (h & TM) + th++; + t = malloc(tw * th * sizeof(struct _tile)); + i = 0; + /* fill in tiles to be all not used */ + for (y = 0; y < th; y++) + { + for (x = 0; x < tw; x++) + t[i++].used = T_UNUSED; + } + /* fill in all tiles with minimum and maximum x & y values */ + for (uu = u; uu; uu = uu->next) + { + CLIP(uu->x, uu->y, uu->w, uu->h, 0, 0, w, h); + for (y = uu->y >> TB; y < ((uu->y + uu->h - 1) >> TB) + 1; y++) + { + for (x = uu->x >> TB; x < ((uu->x + uu->w - 1) >> TB) + 1; x++) + { + if (T(x, y).used == T_USED) + { + int xx, yy; + + xx = MAX(uu->x, x << TB); + yy = MAX(uu->y, y << TB); + T(x, y).min_x = (MIN(xx, T(x, y).min_x)) - (x << TB); + T(x, y).min_y = (MIN(yy, T(x, y).min_y)) - (y << TB); + xx = MIN(uu->x + uu->w - 1, ((x + 1) << TB) - 1); + yy = MIN(uu->y + uu->h - 1, ((y + 1) << TB) - 1); + T(x, y).max_x = (MAX(xx, T(x, y).max_x)) - (x << TB); + T(x, y).max_y = (MAX(yy, T(x, y).max_y)) - (y << TB); + } + else + { + T(x, y).used = T_USED; + T(x, y).min_x = (MAX(x << TB, uu->x)) - (x << TB); + T(x, y).min_y = (MAX(y << TB, uu->y)) - (y << TB); + T(x, y).max_x = (MIN(((x + 1) << TB) - 1, uu->x + uu->w - 1)) - (x << TB); + T(x, y).max_y = (MIN(((y + 1) << TB) - 1, uu->y + uu->h - 1)) - (y << TB); + } + } + } + } + /* concatinate tiles horizontally */ + /* concatinate tiles vertically */ + free(t); + __imlib_FreeUpdates(u); + return nu; +} + +ImlibUpdate * +__imlib_AddUpdate(ImlibUpdate *u, int x, int y, int w, int h) +{ + ImlibUpdate *nu; + + if ((w < 1) || (h < 1) || ((x + w) < 1) || ((y + h) < 1)) + return u; + nu = malloc(sizeof(ImlibUpdate)); + nu->x = x; + nu->y = y; + nu->w = w; + nu->h = h; + nu->next = u; + return nu; +} + +void +__imlib_FreeUpdates(ImlibUpdate *u) +{ + ImlibUpdate *uu; + + uu = u; + while (uu) + { + u = uu; + uu = uu->next; + free(u); + } +} + diff --git a/updates.h b/updates.h new file mode 100644 index 0000000..531e1e4 --- /dev/null +++ b/updates.h @@ -0,0 +1,15 @@ +#ifndef __UPDATES +#define __UPDATES 1 +typedef struct _imlibupdate ImlibUpdate; + +struct _imlibupdate +{ + int x, y, w, h; + ImlibUpdate *next; +}; + +ImlibUpdate *__imlib_AddUpdate(ImlibUpdate *u, int x, int y, int w, int h); +ImlibUpdate *__imlib_MergeUpdate(ImlibUpdate *u, int w, int h); +void __imlib_FreeUpdates(ImlibUpdate *u); + +#endif