diff options
author | Kim Woelders <kim@woelders.dk> | 2021-11-20 19:34:41 +0100 |
---|---|---|
committer | Kim Woelders <kim@woelders.dk> | 2021-11-23 20:33:25 +0100 |
commit | eebe5a274765dfda7ba809de08692a7d6319e966 (patch) | |
tree | cf6d6663192a2e74814571b5700e29bccddb5f61 /src/lib | |
parent | 892af451f2ffa7bd43bb83b84354e79500f4a141 (diff) | |
download | imlib2-eebe5a274765dfda7ba809de08692a7d6319e966.tar.gz |
Refactor imlib_create_scaled_image_from_drawable()
The X11 stuff should be in x11_grab.c, like the
imlib_create_image_from_drawable() implementation.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/api.c | 121 | ||||
-rw-r--r-- | src/lib/x11_grab.c | 98 | ||||
-rw-r--r-- | src/lib/x11_grab.h | 8 |
3 files changed, 116 insertions, 111 deletions
diff --git a/src/lib/api.c b/src/lib/api.c index 5f22ea7..cae0d34 100644 --- a/src/lib/api.c +++ b/src/lib/api.c @@ -3,11 +3,6 @@ #include <math.h> #include <string.h> #include <stdarg.h> -#ifdef BUILD_X11 -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/extensions/shape.h> -#endif #include "Imlib2.h" #include "blend.h" @@ -2315,123 +2310,27 @@ imlib_create_scaled_image_from_drawable(Pixmap mask, int source_x, char get_mask_from_shape) { ImlibImage *im; - char domask = 0, tmpmask = 0; - int x, xx; - XGCValues gcv; - GC gc = 0, mgc = 0; - Pixmap p, m; + char domask; CHECK_CONTEXT(ctx); if (!IMAGE_DIMENSIONS_OK(source_width, source_height)) return NULL; if (!IMAGE_DIMENSIONS_OK(destination_width, destination_height)) return NULL; - if ((mask) || (get_mask_from_shape)) - domask = 1; - - p = XCreatePixmap(ctx->display, ctx->drawable, destination_width, - source_height, ctx->depth); - - gcv.foreground = 0; - gcv.subwindow_mode = IncludeInferiors; - gcv.graphics_exposures = False; - gc = XCreateGC(ctx->display, ctx->drawable, - GCSubwindowMode | GCGraphicsExposures, &gcv); - - if ((domask) && (!mask)) - { - XRectangle *rect; - int rect_num, rect_ord; - - rect = XShapeGetRectangles(ctx->display, ctx->drawable, ShapeBounding, - &rect_num, &rect_ord); - - if (rect && (rect_num == 1 && - rect[0].x == 0 && rect[0].y == 0 && - rect[0].width == source_width && - rect[0].height == source_height)) - { - domask = 0; - XFree(rect); - } - else - { - tmpmask = 1; - mask = - XCreatePixmap(ctx->display, ctx->drawable, source_width, - source_height, 1); - mgc = XCreateGC(ctx->display, mask, - GCForeground | GCGraphicsExposures, &gcv); - XFillRectangle(ctx->display, mask, mgc, 0, 0, source_width, - source_height); - if (rect) - { - XSetForeground(ctx->display, mgc, 1); - for (x = 0; x < rect_num; x++) - XFillRectangle(ctx->display, mask, mgc, rect[x].x, - rect[x].y, rect[x].width, rect[x].height); - XFree(rect); - } - } - } - if ((destination_width == source_width) && - (destination_height == source_height)) - { - XCopyArea(ctx->display, ctx->drawable, p, gc, source_x, source_y, - source_width, source_height, 0, 0); - m = mask; - } - else - { - if (domask) - { - m = XCreatePixmap(ctx->display, ctx->drawable, destination_width, - source_height, 1); - if (!mgc) - mgc = XCreateGC(ctx->display, m, - GCForeground | GCGraphicsExposures, &gcv); - } - else - m = None; - - for (x = 0; x < destination_width; x++) - { - xx = (source_width * x) / destination_width; - XCopyArea(ctx->display, ctx->drawable, p, gc, - source_x + xx, source_y, 1, source_height, x, 0); - if (m != None) - XCopyArea(ctx->display, mask, m, mgc, - xx, 0, 1, source_height, x, 0); - } - for (x = 0; x < destination_height; x++) - { - xx = (source_height * x) / destination_height; - XCopyArea(ctx->display, p, p, gc, - 0, xx, destination_width, 1, 0, x); - if (m != None) - XCopyArea(ctx->display, m, m, mgc, - 0, xx, destination_width, 1, 0, x); - } - } + domask = mask != 0 || get_mask_from_shape; 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, - source_height, ctx->display, p, m, - ctx->visual, ctx->colormap, ctx->depth, 0, 0, - destination_width, destination_height, &domask, - need_to_grab_x); - UPDATE_FLAG(im->flags, F_HAS_ALPHA, domask); - if (mgc) - XFreeGC(ctx->display, mgc); - if (m != None && m != mask) - XFreePixmap(ctx->display, m); - if (tmpmask) - XFreePixmap(ctx->display, mask); - XFreeGC(ctx->display, gc); - XFreePixmap(ctx->display, p); + __imlib_GrabDrawableScaledToRGBA(im->data, source_x, source_y, + source_width, source_height, + ctx->display, ctx->drawable, mask, + ctx->visual, ctx->colormap, ctx->depth, 0, + 0, destination_width, destination_height, + &domask, need_to_grab_x); + + UPDATE_FLAG(im->flags, F_HAS_ALPHA, domask); return (Imlib_Image) im; } diff --git a/src/lib/x11_grab.c b/src/lib/x11_grab.c index 709bdbe..8b31b92 100644 --- a/src/lib/x11_grab.c +++ b/src/lib/x11_grab.c @@ -829,3 +829,101 @@ __imlib_GrabDrawableToRGBA(DATA32 * data, int ox, int oy, int ow, int oh, return 1; } + +int +__imlib_GrabDrawableScaledToRGBA(DATA32 * data, int ox, int oy, int ow, int oh, + Display * d, Drawable p, Pixmap m, Visual * v, + Colormap cm, int depth, int x, int y, + int w, int h, char *pdomask, int grab) +{ + int rc; + int tmpmask = 0; + int i, xx; + XGCValues gcv; + GC gc = 0, mgc = 0; + Pixmap psc, msc; + + psc = XCreatePixmap(d, p, w, oh, depth); + + gcv.foreground = 0; + gcv.subwindow_mode = IncludeInferiors; + gcv.graphics_exposures = False; + gc = XCreateGC(d, p, GCSubwindowMode | GCGraphicsExposures, &gcv); + + if (*pdomask && !m) + { + XRectangle *rect; + int rect_num, rect_ord; + + rect = XShapeGetRectangles(d, p, ShapeBounding, &rect_num, &rect_ord); + + if (rect && (rect_num == 1 && rect[0].x == 0 && rect[0].y == 0 && + rect[0].width == ow && rect[0].height == oh)) + { + *pdomask = 0; + XFree(rect); + } + else + { + tmpmask = 1; + m = XCreatePixmap(d, p, ow, oh, 1); + mgc = XCreateGC(d, m, GCForeground | GCGraphicsExposures, &gcv); + XFillRectangle(d, m, mgc, 0, 0, ow, oh); + if (rect) + { + XSetForeground(d, mgc, 1); + for (i = 0; i < rect_num; i++) + XFillRectangle(d, m, mgc, rect[i].x, rect[i].y, + rect[i].width, rect[i].height); + XFree(rect); + } + } + } + + if (w == ow && h == oh) + { + XCopyArea(d, p, psc, gc, ox, oy, ow, oh, 0, 0); + msc = m; + } + else + { + if (*pdomask) + { + msc = XCreatePixmap(d, p, w, oh, 1); + if (!mgc) + mgc = + XCreateGC(d, msc, GCForeground | GCGraphicsExposures, &gcv); + } + else + msc = None; + + for (i = 0; i < w; i++) + { + xx = (ow * i) / w; + XCopyArea(d, p, psc, gc, ox + xx, oy, 1, oh, i, 0); + if (msc != None) + XCopyArea(d, m, msc, mgc, xx, 0, 1, oh, i, 0); + } + for (i = 0; i < h; i++) + { + xx = (oh * i) / h; + XCopyArea(d, psc, psc, gc, 0, xx, w, 1, 0, i); + if (msc != None) + XCopyArea(d, msc, msc, mgc, 0, xx, w, 1, 0, i); + } + } + + rc = __imlib_GrabDrawableToRGBA(data, 0, 0, w, oh, d, psc, msc, + v, cm, depth, 0, 0, w, h, pdomask, grab); + + if (mgc) + XFreeGC(d, mgc); + if (msc != None && msc != m) + XFreePixmap(d, msc); + if (tmpmask) + XFreePixmap(d, m); + XFreeGC(d, gc); + XFreePixmap(d, psc); + + return rc; +} diff --git a/src/lib/x11_grab.h b/src/lib/x11_grab.h index b37804b..b6f3ad6 100644 --- a/src/lib/x11_grab.h +++ b/src/lib/x11_grab.h @@ -10,6 +10,14 @@ int __imlib_GrabDrawableToRGBA(DATA32 * data, int ox, int oy, int y, int w, int h, char *domask, int grab); +int __imlib_GrabDrawableScaledToRGBA(DATA32 * data, int ox, + int oy, int ow, int oh, + Display * d, Drawable p, + Pixmap m, Visual * v, + Colormap cm, int depth, + int x, int y, int w, int h, + char *pdomask, int grab); + void __imlib_GrabXImageToRGBA(DATA32 * data, int ox, int oy, int ow, int oh, Display * d, XImage * xim, XImage * mxim, |