summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2021-11-20 19:34:41 +0100
committerKim Woelders <kim@woelders.dk>2021-11-23 20:33:25 +0100
commiteebe5a274765dfda7ba809de08692a7d6319e966 (patch)
treecf6d6663192a2e74814571b5700e29bccddb5f61 /src/lib
parent892af451f2ffa7bd43bb83b84354e79500f4a141 (diff)
downloadimlib2-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.c121
-rw-r--r--src/lib/x11_grab.c98
-rw-r--r--src/lib/x11_grab.h8
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,