750 lines
17 KiB
C
750 lines
17 KiB
C
/*
|
|
* Copyright (C) 2004-2021 Kim Woelders
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
* and software packages that this Software was used.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#include "config.h"
|
|
|
|
#include <Imlib2.h>
|
|
#include <X11/Xlib.h>
|
|
#if USE_XRENDER
|
|
#include <X11/extensions/Xrender.h>
|
|
#endif
|
|
|
|
#include "E.h"
|
|
#include "eimage.h"
|
|
#include "file.h"
|
|
#include "xwin.h"
|
|
|
|
#define IMG_CACHE_DEFAULT_SIZE (2 * 1024 * 1024)
|
|
#define XIM_CACHE_DEFAULT_COUNT 0
|
|
|
|
void
|
|
EImageInit(void)
|
|
{
|
|
EImageSetCacheSize(Conf.testing.image_cache_size);
|
|
EImageSetXImageCacheSize(Conf.testing.ximage_cache_count, -1);
|
|
imlib_set_font_cache_size(512 * 1024);
|
|
|
|
imlib_set_color_usage(128);
|
|
|
|
imlib_context_set_display(disp);
|
|
imlib_context_set_visual(WinGetVisual(VROOT));
|
|
imlib_context_set_colormap(WinGetCmap(VROOT));
|
|
|
|
#ifdef HAVE_IMLIB_CONTEXT_SET_MASK_ALPHA_THRESHOLD
|
|
imlib_context_set_mask_alpha_threshold(Conf.testing.mask_alpha_threshold);
|
|
#endif
|
|
|
|
imlib_context_set_anti_alias(0);
|
|
imlib_context_set_dither(1);
|
|
}
|
|
|
|
void
|
|
EImageExit(int quit __UNUSED__)
|
|
{
|
|
#if HAVE_IMLIB_CONTEXT_DISCONNECT_DISPLAY
|
|
imlib_context_disconnect_display();
|
|
#endif
|
|
}
|
|
|
|
void
|
|
EImageSetCacheSize(int size)
|
|
{
|
|
Conf.testing.image_cache_size = size;
|
|
if (size < 0)
|
|
size = IMG_CACHE_DEFAULT_SIZE;
|
|
imlib_set_cache_size(size);
|
|
}
|
|
|
|
void
|
|
EImageSetXImageCacheSize(int count, int size __UNUSED__)
|
|
{
|
|
Conf.testing.ximage_cache_count = count;
|
|
#if HAVE_IMLIB_XIMAGE_CACHE_CONTROL
|
|
if (count < 0)
|
|
count = XIM_CACHE_DEFAULT_COUNT;
|
|
imlib_set_ximage_cache_count_max(count);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
EImageGetCacheInfo(ECacheInfo * ci)
|
|
{
|
|
memset(ci, 0, sizeof(ECacheInfo));
|
|
ci->img.max_mem = imlib_get_cache_size();
|
|
#if HAVE_IMLIB_XIMAGE_CACHE_CONTROL
|
|
ci->img.used_mem = imlib_get_cache_used();
|
|
ci->xim.max_mem = imlib_get_ximage_cache_size_max();
|
|
ci->xim.used_mem = imlib_get_ximage_cache_size_used();
|
|
ci->xim.max_cnt = imlib_get_ximage_cache_count_max();
|
|
ci->xim.used_cnt = imlib_get_ximage_cache_count_used();
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
_EImageFlagsSet(int flags)
|
|
{
|
|
if (flags & EIMAGE_ANTI_ALIAS)
|
|
imlib_context_set_anti_alias(1);
|
|
if (flags & EIMAGE_BLEND)
|
|
imlib_context_set_blend(1);
|
|
#ifdef HAVE_IMLIB_CONTEXT_SET_MASK_ALPHA_THRESHOLD
|
|
if (flags & EIMAGE_HIGH_MASK_THR)
|
|
imlib_context_set_mask_alpha_threshold(128);
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
_EImageFlagsReset(void)
|
|
{
|
|
imlib_context_set_anti_alias(0);
|
|
imlib_context_set_blend(0);
|
|
#ifdef HAVE_IMLIB_CONTEXT_SET_MASK_ALPHA_THRESHOLD
|
|
imlib_context_set_mask_alpha_threshold(Conf.testing.mask_alpha_threshold);
|
|
#endif
|
|
}
|
|
|
|
EImage *
|
|
EImageLoad(const char *file)
|
|
{
|
|
return imlib_load_image(file);
|
|
}
|
|
|
|
EImage *
|
|
EImageLoadOrientate(const char *file, int orientation)
|
|
{
|
|
EImage *im, *im2;
|
|
char name[2048], path[4096], *s, *s2;
|
|
|
|
snprintf(name, sizeof(name), "%s", file);
|
|
for (s = name, s2 = NULL; *s; s++)
|
|
{
|
|
if (*s == '/')
|
|
*s = '.';
|
|
else if (*s == '.')
|
|
s2 = s;
|
|
}
|
|
if (s2)
|
|
*s2 = '\0';
|
|
snprintf(path, sizeof(path), "%s/cached/cfg/%s-%d.png",
|
|
EDirUserCache(), name, orientation);
|
|
|
|
if (!exists(path))
|
|
{
|
|
im = imlib_load_image(file);
|
|
if (!im)
|
|
return NULL;
|
|
|
|
imlib_context_set_image(im);
|
|
im2 = imlib_clone_image();
|
|
imlib_free_image();
|
|
|
|
imlib_context_set_image(im2);
|
|
imlib_image_orientate(orientation);
|
|
imlib_image_set_format("png");
|
|
imlib_save_image(path);
|
|
imlib_free_image();
|
|
}
|
|
|
|
im = imlib_load_image(path);
|
|
|
|
return im;
|
|
}
|
|
|
|
void
|
|
EImageSave(EImage * im, const char *file)
|
|
{
|
|
imlib_context_set_image(im);
|
|
imlib_image_set_format("png");
|
|
imlib_save_image(file);
|
|
}
|
|
|
|
EImage *
|
|
EImageCreate(int w, int h)
|
|
{
|
|
EImage *im;
|
|
|
|
im = imlib_create_image(w, h);
|
|
|
|
return im;
|
|
}
|
|
|
|
EImage *
|
|
EImageCreateFromData(int w, int h, unsigned int *data)
|
|
{
|
|
EImage *im;
|
|
|
|
im = imlib_create_image_using_copied_data(w, h, data);
|
|
|
|
return im;
|
|
}
|
|
|
|
EImage *
|
|
EImageCreateScaled(EImage * im, int sx, int sy, int sw, int sh, int dw, int dh)
|
|
{
|
|
imlib_context_set_image(im);
|
|
if (sw <= 0)
|
|
sw = imlib_image_get_width();
|
|
if (sh <= 0)
|
|
sh = imlib_image_get_height();
|
|
if (dw <= 0)
|
|
dw = sw;
|
|
if (dh <= 0)
|
|
dh = sh;
|
|
return imlib_create_cropped_scaled_image(sx, sy, sw, sh, dw, dh);
|
|
}
|
|
|
|
void
|
|
EImageFree(EImage * im)
|
|
{
|
|
imlib_context_set_image(im);
|
|
imlib_free_image();
|
|
}
|
|
|
|
void
|
|
EImageDecache(EImage * im)
|
|
{
|
|
imlib_context_set_image(im);
|
|
imlib_free_image_and_decache();
|
|
}
|
|
|
|
static int
|
|
_EImageCheckAlpha(void)
|
|
{
|
|
static const short oink = 3; /* For endianness checking */
|
|
unsigned char *pb, *pe;
|
|
|
|
if (!imlib_image_has_alpha())
|
|
return 0;
|
|
|
|
pb = (unsigned char *)imlib_image_get_data_for_reading_only();
|
|
if (!pb)
|
|
return 0;
|
|
|
|
pe = pb + 4 * imlib_image_get_width() * imlib_image_get_height();
|
|
pb += *((char *)(&oink));
|
|
for (; pb < pe; pb += 4)
|
|
if (*pb != 0xff)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
EImageCheckAlpha(EImage * im)
|
|
{
|
|
imlib_context_set_image(im);
|
|
|
|
if (imlib_image_has_alpha() && !_EImageCheckAlpha())
|
|
{
|
|
#if 0
|
|
Eprintf("Alpha set but no shape %s\n", is->real_file);
|
|
#endif
|
|
imlib_image_set_has_alpha(0);
|
|
}
|
|
}
|
|
|
|
void
|
|
EImageSetHasAlpha(EImage * im, int has_alpha)
|
|
{
|
|
imlib_context_set_image(im);
|
|
imlib_image_set_has_alpha(has_alpha);
|
|
}
|
|
|
|
void
|
|
EImageSetBorder(EImage * im, EImageBorder * border)
|
|
{
|
|
Imlib_Border ib;
|
|
|
|
ib.left = border->left;
|
|
ib.right = border->right;
|
|
ib.top = border->top;
|
|
ib.bottom = border->bottom;
|
|
imlib_context_set_image(im);
|
|
imlib_image_set_border(&ib);
|
|
|
|
if (EDebug(1))
|
|
{
|
|
int l;
|
|
|
|
l = imlib_image_get_width();
|
|
if ((l < ib.left + ib.right) || (ib.left < 0) || (ib.left < 0))
|
|
Eprintf("%s: %s: Image W = %d < border L+R = %d+%d\n", __func__,
|
|
imlib_image_get_filename(), l, ib.left, ib.right);
|
|
l = imlib_image_get_height();
|
|
if ((l < ib.top + ib.bottom) || (ib.top < 0) || (ib.bottom < 0))
|
|
Eprintf("%s: %s: Image H = %d < border T+B = %d+%d\n", __func__,
|
|
imlib_image_get_filename(), l, ib.top, ib.bottom);
|
|
}
|
|
}
|
|
|
|
int
|
|
EImageHasAlpha(EImage * im)
|
|
{
|
|
imlib_context_set_image(im);
|
|
return imlib_image_has_alpha();
|
|
}
|
|
|
|
void
|
|
EImageGetSize(EImage * im, int *pw, int *ph)
|
|
{
|
|
imlib_context_set_image(im);
|
|
*pw = imlib_image_get_width();
|
|
*ph = imlib_image_get_height();
|
|
}
|
|
|
|
void *
|
|
EImageGetData(EImage * im)
|
|
{
|
|
imlib_context_set_image(im);
|
|
return imlib_image_get_data_for_reading_only();
|
|
}
|
|
|
|
void
|
|
EImageFill(EImage * im, int x, int y, int w, int h, unsigned int color)
|
|
{
|
|
int a, r, g, b;
|
|
|
|
imlib_context_set_image(im);
|
|
COLOR32_TO_ARGB(color, a, r, g, b);
|
|
imlib_context_set_color(r, g, b, a);
|
|
imlib_context_set_blend(0);
|
|
imlib_image_fill_rectangle(x, y, w, h);
|
|
}
|
|
|
|
void
|
|
EImageOrientate(EImage * im, int orientation)
|
|
{
|
|
imlib_context_set_image(im);
|
|
imlib_image_orientate(orientation);
|
|
}
|
|
|
|
void
|
|
EImageBlend(EImage * im, EImage * src, int flags,
|
|
int sx, int sy, int sw, int sh,
|
|
int dx, int dy, int dw, int dh, int merge_alpha)
|
|
{
|
|
imlib_context_set_image(im);
|
|
if (flags)
|
|
_EImageFlagsSet(flags);
|
|
imlib_blend_image_onto_image(src, merge_alpha, sx, sy, sw, sh,
|
|
dx, dy, dw, dh);
|
|
if (flags)
|
|
_EImageFlagsReset();
|
|
}
|
|
|
|
void
|
|
EImageTile(EImage * im, EImage * tile, int flags, int tw, int th,
|
|
int dx, int dy, int dw, int dh, int ox, int oy)
|
|
{
|
|
Imlib_Image tim;
|
|
int x, y, tx, ty, ww, hh;
|
|
int sw, sh;
|
|
|
|
if (tw <= 0 || th <= 0)
|
|
return;
|
|
|
|
if (flags)
|
|
_EImageFlagsSet(flags);
|
|
|
|
imlib_context_set_image(tile);
|
|
sw = imlib_image_get_width();
|
|
sh = imlib_image_get_height();
|
|
if (sw == tw && sh == th)
|
|
{
|
|
tim = tile;
|
|
}
|
|
else
|
|
{
|
|
tim = imlib_create_image(tw, th);
|
|
imlib_context_set_image(tim);
|
|
imlib_context_set_blend(0);
|
|
imlib_context_set_anti_alias(1);
|
|
imlib_blend_image_onto_image(tile, 0, 0, 0, sw, sh, 0, 0, tw, th);
|
|
imlib_context_set_anti_alias(0);
|
|
}
|
|
imlib_context_set_image(im);
|
|
|
|
if (ox)
|
|
{
|
|
ox = tw - ox;
|
|
ox %= tw;
|
|
if (ox < 0)
|
|
ox += tw;
|
|
}
|
|
if (oy)
|
|
{
|
|
oy = th - oy;
|
|
oy %= th;
|
|
if (oy < 0)
|
|
oy += th;
|
|
}
|
|
dw += dx;
|
|
dh += dy;
|
|
y = dy;
|
|
ty = oy;
|
|
hh = th - oy;
|
|
for (;;)
|
|
{
|
|
if (y + hh >= dh)
|
|
hh = dh - y;
|
|
if (hh <= 0)
|
|
break;
|
|
x = dx;
|
|
tx = ox;
|
|
ww = tw - ox;
|
|
for (;;)
|
|
{
|
|
if (x + ww >= dw)
|
|
ww = dw - x;
|
|
if (ww <= 0)
|
|
break;
|
|
imlib_blend_image_onto_image(tim, 0, tx, ty, ww, hh, x, y, ww, hh);
|
|
tx = 0;
|
|
x += ww;
|
|
ww = tw;
|
|
}
|
|
ty = 0;
|
|
y += hh;
|
|
hh = th;
|
|
}
|
|
if (tim != tile)
|
|
{
|
|
imlib_context_set_image(tim);
|
|
imlib_free_image();
|
|
imlib_context_set_image(im); /* FIXME - Remove */
|
|
}
|
|
|
|
if (flags)
|
|
_EImageFlagsReset();
|
|
}
|
|
|
|
EImage *
|
|
EImageGrabDrawable(EX_Drawable draw, EX_Pixmap mask, int x, int y, int w,
|
|
int h, int grab)
|
|
{
|
|
EImage *im;
|
|
EX_Colormap cm;
|
|
|
|
cm = imlib_context_get_colormap();
|
|
imlib_context_set_colormap(NoXID); /* Fix for grabbing bitmaps */
|
|
imlib_context_set_drawable(draw);
|
|
im = imlib_create_image_from_drawable(mask, x, y, w, h, grab);
|
|
imlib_context_set_colormap(cm);
|
|
|
|
return im;
|
|
}
|
|
|
|
EImage *
|
|
EImageGrabDrawableScaled(Win win, EX_Drawable draw, EX_Pixmap mask,
|
|
int x, int y, int w, int h,
|
|
int iw, int ih, int grab, int get_mask_from_shape)
|
|
{
|
|
EImage *im;
|
|
Visual *vis;
|
|
|
|
imlib_context_set_drawable(draw);
|
|
vis = (win) ? WinGetVisual(win) : NULL;
|
|
if (vis)
|
|
imlib_context_set_visual(vis);
|
|
|
|
im = imlib_create_scaled_image_from_drawable(mask, x, y, w, h, iw, ih, grab,
|
|
get_mask_from_shape);
|
|
|
|
if (vis)
|
|
imlib_context_set_visual(WinGetVisual(VROOT));
|
|
|
|
return im;
|
|
}
|
|
|
|
void
|
|
EImageRenderOnDrawable(EImage * im, Win win, EX_Drawable draw, int flags,
|
|
int x, int y, int w, int h)
|
|
{
|
|
Visual *vis;
|
|
|
|
imlib_context_set_image(im);
|
|
imlib_context_set_drawable((draw != NoXID) ? draw : WinGetXwin(win));
|
|
vis = (win) ? WinGetVisual(win) : NULL;
|
|
if (vis)
|
|
imlib_context_set_visual(vis);
|
|
|
|
if (flags)
|
|
_EImageFlagsSet(flags);
|
|
imlib_render_image_on_drawable_at_size(x, y, w, h);
|
|
if (flags)
|
|
_EImageFlagsReset();
|
|
|
|
if (vis)
|
|
imlib_context_set_visual(WinGetVisual(VROOT));
|
|
}
|
|
|
|
#if USE_XRENDER
|
|
|
|
void
|
|
EImageRenderOnDrawableARGB(EImage * im, EX_Drawable draw, int w, int h)
|
|
{
|
|
Visual *vis;
|
|
|
|
imlib_context_set_image(im);
|
|
imlib_context_set_drawable(draw);
|
|
vis = EVisualFindARGB();
|
|
if (vis)
|
|
imlib_context_set_visual(vis);
|
|
|
|
imlib_render_image_on_drawable_at_size(0, 0, w, h);
|
|
|
|
if (vis)
|
|
imlib_context_set_visual(WinGetVisual(VROOT));
|
|
}
|
|
|
|
#endif
|
|
|
|
void
|
|
EImageRenderPixmaps(EImage * im, Win win, int flags,
|
|
EX_Pixmap * ppmap, EX_Pixmap * pmask, int w, int h)
|
|
{
|
|
Visual *vis;
|
|
Pixmap pmap, mask, *pm;
|
|
|
|
imlib_context_set_image(im);
|
|
imlib_context_set_drawable((win) ? WinGetXwin(win) : WinGetXwin(VROOT));
|
|
vis = (win) ? WinGetVisual(win) : NULL;
|
|
if (vis)
|
|
imlib_context_set_visual(vis);
|
|
|
|
pmap = mask = NoXID;
|
|
pm = pmask ? &mask : NULL;
|
|
|
|
if (flags)
|
|
_EImageFlagsSet(flags);
|
|
if (w <= 0 || h <= 0)
|
|
imlib_render_pixmaps_for_whole_image(&pmap, pm);
|
|
else
|
|
imlib_render_pixmaps_for_whole_image_at_size(&pmap, pm, w, h);
|
|
if (flags)
|
|
_EImageFlagsReset();
|
|
|
|
if (vis)
|
|
imlib_context_set_visual(WinGetVisual(VROOT));
|
|
|
|
*ppmap = pmap;
|
|
if (pmask)
|
|
*pmask = mask;
|
|
}
|
|
|
|
void
|
|
EImagePixmapsFree(EX_Pixmap pmap, EX_Pixmap mask __UNUSED__)
|
|
{
|
|
imlib_free_pixmap_and_mask(pmap);
|
|
}
|
|
|
|
void
|
|
EImageApplyToWin(EImage * im, Win win, int flags, int w, int h)
|
|
{
|
|
EX_Pixmap pmap, mask;
|
|
|
|
EImageRenderPixmaps(im, win, flags, &pmap, &mask, w, h);
|
|
ESetWindowBackgroundPixmap(win, pmap, 0);
|
|
if ((mask != NoXID) || (mask == NoXID && WinIsShaped(win)))
|
|
EShapeSetMask(win, 0, 0, mask);
|
|
EImagePixmapsFree(pmap, mask);
|
|
EClearWindow(win);
|
|
}
|
|
|
|
void
|
|
ScaleRect(Win wsrc, EX_Drawable src, Win wdst, EX_Pixmap dst,
|
|
int sx, int sy, int sw, int sh,
|
|
int dx, int dy, int dw, int dh, int flags)
|
|
{
|
|
#if USE_XRENDER
|
|
if (Conf.testing.use_render_for_scaling)
|
|
{
|
|
XTransform tr;
|
|
EX_Picture psrc, pdst;
|
|
double scale_x, scale_y;
|
|
|
|
scale_x = (double)sw / (double)dw;
|
|
scale_y = (double)sh / (double)dh;
|
|
memset(&tr, 0, sizeof(tr));
|
|
tr.matrix[0][0] = XDoubleToFixed(scale_x);
|
|
tr.matrix[1][1] = XDoubleToFixed(scale_y);
|
|
tr.matrix[2][2] = XDoubleToFixed(1.);
|
|
|
|
psrc = EPictureCreateII(wsrc, src);
|
|
pdst = EPictureCreateII(wdst, dst);
|
|
|
|
XRenderSetPictureFilter(disp, psrc, (flags & EIMAGE_ANTI_ALIAS) ?
|
|
FilterBest : FilterNearest, NULL, 0);
|
|
XRenderSetPictureTransform(disp, psrc, &tr);
|
|
XRenderComposite(disp, PictOpSrc, psrc, NoXID, pdst,
|
|
(int)(sx / scale_x + .5), (int)(sy / scale_y + .5),
|
|
0, 0, dx, dy, dw, dh);
|
|
XRenderFreePicture(disp, psrc);
|
|
XRenderFreePicture(disp, pdst);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
int scale;
|
|
Imlib_Image im;
|
|
|
|
if (flags & (EIMAGE_ISCALE))
|
|
{
|
|
scale = (flags & EIMAGE_ISCALE) >> 8;
|
|
im = EImageGrabDrawableScaled(wsrc, src, NoXID, sx, sy, sw, sh,
|
|
scale * dw, scale * dh, 0, 0);
|
|
flags |= EIMAGE_ANTI_ALIAS;
|
|
}
|
|
else
|
|
{
|
|
im = EImageGrabDrawableScaled(wsrc, src, NoXID, sx, sy, sw, sh,
|
|
sw, sh, 0, 0);
|
|
}
|
|
|
|
EImageRenderOnDrawable(im, wdst, dst, flags, dx, dy, dw, dh);
|
|
imlib_free_image();
|
|
}
|
|
}
|
|
|
|
void
|
|
ScaleTile(Win wsrc, EX_Drawable src, Win wdst, EX_Pixmap dst,
|
|
int dx, int dy, int dw, int dh, int scale)
|
|
{
|
|
Imlib_Image im, tim;
|
|
int sw, sh, stw, sth, tw, th;
|
|
|
|
sw = WinGetW(wsrc);
|
|
sh = WinGetH(wsrc);
|
|
EXGetSize(src, &stw, &sth);
|
|
if (stw >= sw && sth >= sh)
|
|
{
|
|
ScaleRect(wsrc, src, wdst, dst, 0, 0, sw, sh, dx, dy, dw, dh, scale);
|
|
return;
|
|
}
|
|
|
|
/* Source Drawawble is smaller than source window - do scaled tiling */
|
|
|
|
scale = (scale) ? 2 : 1;
|
|
|
|
tw = (int)((float)(stw * scale * dw) / sw + .5f);
|
|
th = (int)((float)(sth * scale * dh) / sh + .5f);
|
|
#if 0
|
|
Eprintf("%s: Tile %#x %dx%d -> %dx%d T %dx%d -> %dx%d\n", __func__,
|
|
src, stw, sth, tw, th, scale * dw, scale * dh, dw, dh);
|
|
#endif
|
|
tim =
|
|
EImageGrabDrawableScaled(wsrc, src, NoXID, 0, 0, stw, sth, tw, th, 0, 0);
|
|
im = EImageCreate(scale * dw, scale * dh);
|
|
EImageTile(im, tim, 0, tw, th, 0, 0, scale * dw, scale * dh, 0, 0);
|
|
EImageFree(tim);
|
|
|
|
EImageRenderOnDrawable(im, wdst, dst, EIMAGE_ANTI_ALIAS, dx, dy, dw, dh);
|
|
imlib_free_image();
|
|
}
|
|
|
|
#if 0 /* Unused */
|
|
void
|
|
EDrawableDumpImage(EX_Drawable draw, const char *txt)
|
|
{
|
|
static int seqn = 0;
|
|
char buf[1024];
|
|
Imlib_Image im;
|
|
int w, h;
|
|
|
|
EXGetSize(draw, &w, &h);
|
|
if (w <= 0 || h <= 0)
|
|
return;
|
|
im = EImageGrabDrawableScaled(ELookupXwin(draw), draw, NoXID,
|
|
0, 0, w, h, w, h, 0, 0);
|
|
imlib_context_set_image(im);
|
|
imlib_image_set_format("png");
|
|
sprintf(buf, "%s-%#x-%d.png", txt, draw, seqn++);
|
|
Eprintf("%s: %s\n", __func__, buf);
|
|
imlib_save_image(buf);
|
|
imlib_free_image_and_decache();
|
|
}
|
|
#endif
|
|
|
|
void
|
|
PmapMaskInit(PmapMask * pmm, Win win, int w, int h)
|
|
{
|
|
if (pmm->pmap)
|
|
{
|
|
if (pmm->w == w && pmm->h == h && pmm->depth == WinGetDepth(win))
|
|
return;
|
|
PmapMaskFree(pmm);
|
|
}
|
|
|
|
pmm->type = 0;
|
|
pmm->depth = WinGetDepth(win);
|
|
pmm->pmap = ECreatePixmap(win, w, h, 0);
|
|
pmm->mask = NoXID;
|
|
pmm->w = w;
|
|
pmm->h = h;
|
|
}
|
|
|
|
void
|
|
PmapMaskFree(PmapMask * pmm)
|
|
{
|
|
/* type !=0: Created by imlib_render_pixmaps_for_whole_image... */
|
|
if (pmm->pmap)
|
|
{
|
|
if (pmm->type == 0)
|
|
EFreePixmap(pmm->pmap);
|
|
else
|
|
imlib_free_pixmap_and_mask(pmm->pmap);
|
|
pmm->pmap = 0;
|
|
}
|
|
|
|
if (pmm->mask)
|
|
{
|
|
if (pmm->type == 0)
|
|
EFreePixmap(pmm->mask);
|
|
pmm->mask = 0;
|
|
}
|
|
}
|
|
|
|
#if USE_XRENDER
|
|
|
|
EX_Cursor
|
|
EImageDefineCursor(EImage * im, int xh, int yh)
|
|
{
|
|
EX_Cursor curs;
|
|
int w, h;
|
|
EX_Pixmap pmap;
|
|
EX_Picture pict;
|
|
|
|
EImageGetSize(im, &w, &h);
|
|
|
|
pict = EPictureCreateBuffer(RROOT, w, h, 1, &pmap);
|
|
|
|
EImageRenderOnDrawableARGB(im, pmap, w, h);
|
|
EFreePixmap(pmap);
|
|
|
|
curs = XRenderCreateCursor(disp, pict, xh, yh);
|
|
XRenderFreePicture(disp, pict);
|
|
|
|
return curs;
|
|
}
|
|
|
|
#endif /* USE_XRENDER */
|