x11_grab: Various fixes in __imlib_GrabDrawableScaledToRGBA()
- Fix clipping to source. - Fix error when mask from shape is requested but drawable is pixmap. - Use queried drawable depth, not the context one. This eliminates the last usage of the context depth in the grabbing functions.
This commit is contained in:
parent
3b21892c77
commit
8af7975804
|
@ -847,7 +847,10 @@ __imlib_GrabDrawableScaledToRGBA(const ImlibContextX11 * x11, uint32_t * data,
|
||||||
char *pdomask, int grab, bool clear)
|
char *pdomask, int grab, bool clear)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
XWindowAttributes xatt;
|
||||||
|
bool is_pixmap;
|
||||||
int h_tmp, i, xx;
|
int h_tmp, i, xx;
|
||||||
|
int x_src_, y_src_, width, height, x_dst_, y_dst_;
|
||||||
XGCValues gcv;
|
XGCValues gcv;
|
||||||
GC gc, mgc = NULL;
|
GC gc, mgc = NULL;
|
||||||
Pixmap mask = mask_;
|
Pixmap mask = mask_;
|
||||||
|
@ -860,17 +863,63 @@ __imlib_GrabDrawableScaledToRGBA(const ImlibContextX11 * x11, uint32_t * data,
|
||||||
gcv.graphics_exposures = False;
|
gcv.graphics_exposures = False;
|
||||||
gc = XCreateGC(x11->dpy, draw, GCSubwindowMode | GCGraphicsExposures, &gcv);
|
gc = XCreateGC(x11->dpy, draw, GCSubwindowMode | GCGraphicsExposures, &gcv);
|
||||||
|
|
||||||
if (*pdomask && mask == None)
|
is_pixmap = _DrawableCheck(x11->dpy, draw, &xatt);
|
||||||
|
|
||||||
|
width = w_dst;
|
||||||
|
height = h_dst;
|
||||||
|
|
||||||
|
if (is_pixmap)
|
||||||
{
|
{
|
||||||
mask = _WindowGetShapeMask(x11->dpy, draw,
|
Window rret;
|
||||||
0, 0, w_src, h_src, w_src, h_src);
|
unsigned int bw;
|
||||||
if (mask == None)
|
|
||||||
*pdomask = 0;
|
XGetGeometry(x11->dpy, draw, &rret, &xatt.x, &xatt.y,
|
||||||
|
(unsigned int *)&xatt.width, (unsigned int *)&xatt.height,
|
||||||
|
&bw, (unsigned int *)&xatt.depth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XWindowAttributes ratt;
|
||||||
|
Window cret;
|
||||||
|
|
||||||
|
if ((xatt.map_state != IsViewable) && (xatt.backing_store == NotUseful))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Clip source to screen */
|
||||||
|
XGetWindowAttributes(x11->dpy, xatt.root, &ratt);
|
||||||
|
XTranslateCoordinates(x11->dpy, draw, xatt.root,
|
||||||
|
0, 0, &xatt.x, &xatt.y, &cret);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (xatt.x + x_src < 0)
|
||||||
|
{
|
||||||
|
width += xatt.x + x_src;
|
||||||
|
x_src = -xatt.x;
|
||||||
|
}
|
||||||
|
if (xatt.x + x_src + width > ratt.width)
|
||||||
|
width = ratt.width - (xatt.x + x_src);
|
||||||
|
|
||||||
|
if (xatt.y + y_src < 0)
|
||||||
|
{
|
||||||
|
height += xatt.y + y_src;
|
||||||
|
y_src = -xatt.y;
|
||||||
|
}
|
||||||
|
if (xatt.y + y_src + height > ratt.height)
|
||||||
|
height = ratt.height - (xatt.y + y_src);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (*pdomask && mask == None)
|
||||||
|
{
|
||||||
|
mask = _WindowGetShapeMask(x11->dpy, draw,
|
||||||
|
0, 0, w_src, h_src, w_src, h_src);
|
||||||
|
if (mask == None)
|
||||||
|
*pdomask = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
psc = XCreatePixmap(x11->dpy, draw, w_dst, h_tmp, x11->depth);
|
psc = XCreatePixmap(x11->dpy, draw, w_dst, h_tmp, xatt.depth);
|
||||||
|
|
||||||
if (*pdomask)
|
if (!is_pixmap && *pdomask)
|
||||||
{
|
{
|
||||||
msc = XCreatePixmap(x11->dpy, draw, w_dst, h_tmp, 1);
|
msc = XCreatePixmap(x11->dpy, draw, w_dst, h_tmp, 1);
|
||||||
mgc =
|
mgc =
|
||||||
|
@ -879,6 +928,7 @@ __imlib_GrabDrawableScaledToRGBA(const ImlibContextX11 * x11, uint32_t * data,
|
||||||
else
|
else
|
||||||
msc = None;
|
msc = None;
|
||||||
|
|
||||||
|
/* Copy source height vertical lines from input to intermediate */
|
||||||
for (i = 0; i < w_dst; i++)
|
for (i = 0; i < w_dst; i++)
|
||||||
{
|
{
|
||||||
xx = (w_src * i) / w_dst;
|
xx = (w_src * i) / w_dst;
|
||||||
|
@ -886,6 +936,8 @@ __imlib_GrabDrawableScaledToRGBA(const ImlibContextX11 * x11, uint32_t * data,
|
||||||
if (msc != None)
|
if (msc != None)
|
||||||
XCopyArea(x11->dpy, mask, msc, mgc, xx, 0, 1, h_src, i, 0);
|
XCopyArea(x11->dpy, mask, msc, mgc, xx, 0, 1, h_src, i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy destination width horzontal lines from/to intermediate */
|
||||||
if (h_dst > h_src)
|
if (h_dst > h_src)
|
||||||
{
|
{
|
||||||
for (i = h_dst - 1; i > 0; i--)
|
for (i = h_dst - 1; i > 0; i--)
|
||||||
|
@ -911,8 +963,39 @@ __imlib_GrabDrawableScaledToRGBA(const ImlibContextX11 * x11, uint32_t * data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = __imlib_GrabDrawableToRGBA(x11, data, 0, 0, w_dst, h_dst, psc, msc,
|
x_dst_ = y_dst_ = 0; /* Clipped x_dst, y_dst */
|
||||||
0, 0, w_dst, h_dst, pdomask, grab, clear);
|
x_src_ = y_src_ = 0; /* Clipped, scaled x_src, y_src */
|
||||||
|
|
||||||
|
/* Adjust offsets and areas to not touch "non-existing" pixels */
|
||||||
|
if (x_src < 0)
|
||||||
|
{
|
||||||
|
xx = (-x_src * w_dst + w_src - 1) / w_src;
|
||||||
|
width -= xx;
|
||||||
|
x_src_ = x_dst_ = xx;
|
||||||
|
}
|
||||||
|
if (x_src + w_src > xatt.width)
|
||||||
|
{
|
||||||
|
xx = x_src + w_src - xatt.width;
|
||||||
|
xx = (xx * w_dst + w_src - 1) / w_src;
|
||||||
|
width -= xx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y_src < 0)
|
||||||
|
{
|
||||||
|
xx = (-y_src * h_dst + h_src - 1) / h_src;
|
||||||
|
height -= xx;
|
||||||
|
y_src_ = y_dst_ = xx;
|
||||||
|
}
|
||||||
|
if (y_src + h_src > xatt.height)
|
||||||
|
{
|
||||||
|
xx = y_src + h_src - xatt.height;
|
||||||
|
xx = (xx * h_dst + h_src - 1) / h_src;
|
||||||
|
height -= xx;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = __imlib_GrabDrawableToRGBA(x11, data, x_dst_, y_dst_, w_dst, h_dst,
|
||||||
|
psc, msc, x_src_, y_src_, width, height,
|
||||||
|
pdomask, grab, clear);
|
||||||
|
|
||||||
if (mgc)
|
if (mgc)
|
||||||
XFreeGC(x11->dpy, mgc);
|
XFreeGC(x11->dpy, mgc);
|
||||||
|
|
Loading…
Reference in New Issue