2 * Copyright (C) 2004-2008 Kim Woelders
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies of the Software, its documentation and marketing & publicity
13 * materials, and acknowledgment shall be given in the documentation, materials
14 * and software packages that this Software was used.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #if HAVE_X11_EXTENSIONS_XRENDER_H
28 #include <X11/extensions/Xrender.h>
34 imlib_set_cache_size(2048 * 1024);
35 imlib_set_font_cache_size(512 * 1024);
37 imlib_set_color_usage(128);
39 imlib_context_set_display(disp);
40 imlib_context_set_visual(WinGetVisual(VROOT));
41 imlib_context_set_colormap(WinGetCmap(VROOT));
43 #ifdef HAVE_IMLIB_CONTEXT_SET_MASK_ALPHA_THRESHOLD
44 imlib_context_set_mask_alpha_threshold(Conf.testing.mask_alpha_threshold);
47 imlib_context_set_anti_alias(0);
48 imlib_context_set_dither(1);
52 EImageExit(int quit __UNUSED__)
54 #if HAVE_IMLIB_CONTEXT_DISCONNECT_DISPLAY
55 imlib_context_disconnect_display();
60 EImageSetCacheSize(int size)
64 size_old = imlib_get_cache_size();
65 imlib_set_cache_size(size);
71 _EImageFlagsSet(int flags)
73 if (flags & EIMAGE_ANTI_ALIAS)
74 imlib_context_set_anti_alias(1);
75 if (flags & EIMAGE_BLEND)
76 imlib_context_set_blend(1);
77 #ifdef HAVE_IMLIB_CONTEXT_SET_MASK_ALPHA_THRESHOLD
78 if (flags & EIMAGE_HIGH_MASK_THR)
79 imlib_context_set_mask_alpha_threshold(128);
84 _EImageFlagsReset(void)
86 imlib_context_set_anti_alias(0);
87 imlib_context_set_blend(0);
88 #ifdef HAVE_IMLIB_CONTEXT_SET_MASK_ALPHA_THRESHOLD
89 imlib_context_set_mask_alpha_threshold(Conf.testing.mask_alpha_threshold);
94 EImageLoad(const char *file)
96 return imlib_load_image(file);
100 EImageSave(EImage * im, const char *file)
102 imlib_context_set_image(im);
103 imlib_image_set_format("png");
104 imlib_save_image(file);
108 EImageCreate(int w, int h)
112 im = imlib_create_image(w, h);
118 EImageCreateFromData(int w, int h, unsigned int *data)
122 im = imlib_create_image_using_copied_data(w, h, data);
128 EImageCreateScaled(EImage * im, int sx, int sy, int sw, int sh, int dw, int dh)
130 imlib_context_set_image(im);
132 sw = imlib_image_get_width();
134 sh = imlib_image_get_height();
139 return imlib_create_cropped_scaled_image(sx, sy, sw, sh, dw, dh);
143 EImageFree(EImage * im)
145 imlib_context_set_image(im);
150 EImageDecache(EImage * im)
152 imlib_context_set_image(im);
153 imlib_free_image_and_decache();
157 _EImageCheckAlpha(void)
159 static const short oink = 3; /* For endianness checking */
160 unsigned char *pb, *pe;
162 if (!imlib_image_has_alpha())
165 pb = (unsigned char *)imlib_image_get_data_for_reading_only();
169 pe = pb + 4 * imlib_image_get_width() * imlib_image_get_height();
170 pb += *((char *)(&oink));
171 for (; pb < pe; pb += 4)
179 EImageCheckAlpha(EImage * im)
181 imlib_context_set_image(im);
183 if (imlib_image_has_alpha() && !_EImageCheckAlpha())
186 Eprintf("Alpha set but no shape %s\n", is->real_file);
188 imlib_image_set_has_alpha(0);
193 EImageSetHasAlpha(EImage * im, int has_alpha)
195 imlib_context_set_image(im);
196 imlib_image_set_has_alpha(has_alpha);
200 EImageSetBorder(EImage * im, EImageBorder * border)
204 ib.left = border->left;
205 ib.right = border->right;
206 ib.top = border->top;
207 ib.bottom = border->bottom;
208 imlib_context_set_image(im);
209 imlib_image_set_border(&ib);
213 EImageHasAlpha(EImage * im)
215 imlib_context_set_image(im);
216 return imlib_image_has_alpha();
220 EImageGetSize(EImage * im, int *pw, int *ph)
222 imlib_context_set_image(im);
223 *pw = imlib_image_get_width();
224 *ph = imlib_image_get_height();
228 EImageGetData(EImage * im)
230 imlib_context_set_image(im);
231 return imlib_image_get_data_for_reading_only();
235 EImageFill(EImage * im, int x, int y, int w, int h, int r, int g, int b, int a)
237 imlib_context_set_image(im);
238 imlib_context_set_color(r, g, b, a);
239 imlib_context_set_blend(0);
240 imlib_image_fill_rectangle(x, y, w, h);
244 EImageOrientate(EImage * im, int orientation)
246 imlib_context_set_image(im);
247 imlib_image_orientate(orientation);
251 EImageBlend(EImage * im, EImage * src, int flags,
252 int sx, int sy, int sw, int sh,
253 int dx, int dy, int dw, int dh, int merge_alpha)
255 imlib_context_set_image(im);
257 _EImageFlagsSet(flags);
258 imlib_blend_image_onto_image(src, merge_alpha, sx, sy, sw, sh,
265 EImageBlendCM(EImage * im, EImage * src, EImageColorModifier * icm)
269 imlib_context_set_image(src);
270 iw = imlib_image_get_width();
271 ih = imlib_image_get_height();
272 imlib_context_set_image(im);
273 w = imlib_image_get_width();
274 h = imlib_image_get_height();
276 imlib_context_set_blend(1);
278 imlib_context_set_color_modifier(icm);
279 imlib_context_set_operation(IMLIB_OP_COPY);
280 imlib_blend_image_onto_image(src, 0, 0, 0, iw, ih, 0, 0, w, h);
281 imlib_context_set_blend(0);
283 imlib_context_set_color_modifier(NULL);
287 EImageTile(EImage * im, EImage * tile, int flags, int tw, int th,
288 int dx, int dy, int dw, int dh, int ox, int oy)
291 int x, y, tx, ty, ww, hh;
294 if (tw <= 0 || th <= 0)
298 _EImageFlagsSet(flags);
300 imlib_context_set_image(tile);
301 sw = imlib_image_get_width();
302 sh = imlib_image_get_height();
303 if (sw == tw && sh == th)
309 tim = imlib_create_image(tw, th);
310 imlib_context_set_image(tim);
311 imlib_context_set_blend(0);
312 imlib_context_set_anti_alias(1);
313 imlib_blend_image_onto_image(tile, 0, 0, 0, sw, sh, 0, 0, tw, th);
314 imlib_context_set_anti_alias(0);
316 imlib_context_set_image(im);
352 imlib_blend_image_onto_image(tim, 0, tx, ty, ww, hh, x, y, ww, hh);
363 imlib_context_set_image(tim);
365 imlib_context_set_image(im); /* FIXME - Remove */
373 EImageGrabDrawable(Drawable draw, Pixmap mask, int x, int y, int w, int h,
379 cm = imlib_context_get_colormap();
380 imlib_context_set_colormap(None); /* Fix for grabbing bitmaps */
381 imlib_context_set_drawable(draw);
382 im = imlib_create_image_from_drawable(mask, x, y, w, h, grab);
383 imlib_context_set_colormap(cm);
389 EImageGrabDrawableScaled(Win win, Drawable draw, Pixmap mask,
390 int x, int y, int w, int h,
391 int iw, int ih, int grab, int get_mask_from_shape)
396 imlib_context_set_drawable(draw);
397 vis = (win) ? WinGetVisual(win) : NULL;
399 imlib_context_set_visual(vis);
401 im = imlib_create_scaled_image_from_drawable(mask, x, y, w, h, iw, ih, grab,
402 get_mask_from_shape);
405 imlib_context_set_visual(WinGetVisual(VROOT));
411 EImageRenderOnDrawable(EImage * im, Win win, Drawable draw, int flags,
412 int x, int y, int w, int h)
416 imlib_context_set_image(im);
417 imlib_context_set_drawable((draw != None) ? draw : WinGetXwin(win));
418 vis = (win) ? WinGetVisual(win) : NULL;
420 imlib_context_set_visual(vis);
423 _EImageFlagsSet(flags);
424 imlib_render_image_on_drawable_at_size(x, y, w, h);
429 imlib_context_set_visual(WinGetVisual(VROOT));
433 EImageRenderPixmaps(EImage * im, Win win, int flags,
434 Pixmap * pmap, Pixmap * mask, int w, int h)
439 imlib_context_set_image(im);
440 imlib_context_set_drawable((win) ? WinGetXwin(win) : WinGetXwin(VROOT));
441 vis = (win) ? WinGetVisual(win) : NULL;
443 imlib_context_set_visual(vis);
446 if (!mask) /* Imlib2 <= 1.3.0 needs a mask pointer */
447 mask = &m; /* ... to avoid bogus error messages */
452 _EImageFlagsSet(flags);
453 if (w <= 0 || h <= 0)
454 imlib_render_pixmaps_for_whole_image(pmap, mask);
456 imlib_render_pixmaps_for_whole_image_at_size(pmap, mask, w, h);
461 imlib_context_set_visual(WinGetVisual(VROOT));
465 EImagePixmapsFree(Pixmap pmap, Pixmap mask __UNUSED__)
467 imlib_free_pixmap_and_mask(pmap);
471 EImageApplyToWin(EImage * im, Win win, int flags, int w, int h)
475 EImageRenderPixmaps(im, win, flags, &pmap, &mask, w, h);
476 ESetWindowBackgroundPixmap(win, pmap);
477 if ((mask != None) || (mask == None && WinIsShaped(win)))
478 EShapeSetMask(win, 0, 0, mask);
479 EImagePixmapsFree(pmap, mask);
484 ScaleRect(Win wsrc, Drawable src, Win wdst, Pixmap dst,
485 int sx, int sy, int sw, int sh,
486 int dx, int dy, int dw, int dh, int flags)
488 #if HAVE_X11_EXTENSIONS_XRENDER_H
489 if (Conf.testing.use_render_for_scaling)
491 XRenderPictFormat *pictfmt;
492 XRenderPictureAttributes pa;
495 double scale_x, scale_y;
497 scale_x = (double)sw / (double)dw;
498 scale_y = (double)sh / (double)dh;
499 memset(&tr, 0, sizeof(tr));
500 tr.matrix[0][0] = XDoubleToFixed(scale_x);
501 tr.matrix[1][1] = XDoubleToFixed(scale_y);
502 tr.matrix[2][2] = XDoubleToFixed(1.);
504 pa.subwindow_mode = IncludeInferiors;
505 pictfmt = XRenderFindVisualFormat(disp, wsrc->visual);
506 psrc = XRenderCreatePicture(disp, src, pictfmt, CPSubwindowMode, &pa);
507 pictfmt = XRenderFindVisualFormat(disp, wdst->visual);
508 pdst = XRenderCreatePicture(disp, dst, pictfmt, CPSubwindowMode, &pa);
510 XRenderSetPictureFilter(disp, psrc, (flags & EIMAGE_ANTI_ALIAS) ?
511 FilterBest : FilterNearest, NULL, 0);
512 XRenderSetPictureTransform(disp, psrc, &tr);
513 XRenderComposite(disp, PictOpSrc, psrc, None, pdst,
514 (int)(sx / scale_x + .5), (int)(sy / scale_y + .5),
515 0, 0, dx, dy, dw, dh);
516 XRenderFreePicture(disp, psrc);
517 XRenderFreePicture(disp, pdst);
525 if (flags & (EIMAGE_ISCALE))
527 scale = (flags & EIMAGE_ISCALE) >> 8;
528 im = EImageGrabDrawableScaled(wsrc, src, None, sx, sy, sw, sh,
529 scale * dw, scale * dh, 0, 0);
530 flags |= EIMAGE_ANTI_ALIAS;
534 im = EImageGrabDrawableScaled(wsrc, src, None, sx, sy, sw, sh,
538 EImageRenderOnDrawable(im, wdst, dst, flags, dx, dy, dw, dh);
544 ScaleTile(Win wsrc, Drawable src, Win wdst, Pixmap dst,
545 int dx, int dy, int dw, int dh, int scale)
548 int sw, sh, stw, sth, tw, th;
552 EXGetGeometry(src, NULL, NULL, NULL, &stw, &sth, NULL, NULL);
553 if (stw >= sw && sth >= sh)
555 ScaleRect(wsrc, src, wdst, dst, 0, 0, sw, sh, dx, dy, dw, dh, scale);
559 /* Source Drawawble is smaller than source window - do scaled tiling */
561 scale = (scale) ? 2 : 1;
563 tw = (int)((double)(stw * scale * dw) / sw + .5);
564 th = (int)((double)(sth * scale * dh) / sh + .5);
566 Eprintf("ScaleTile: Tile %#lx %dx%d -> %dx%d T %dx%d -> %dx%d\n", src,
567 stw, sth, tw, th, scale * dw, scale * dh, dw, dh);
570 EImageGrabDrawableScaled(wsrc, src, None, 0, 0, stw, sth, tw, th, 0, 0);
571 im = EImageCreate(scale * dw, scale * dh);
572 EImageTile(im, tim, 0, tw, th, 0, 0, scale * dw, scale * dh, 0, 0);
575 EImageRenderOnDrawable(im, wdst, dst, EIMAGE_ANTI_ALIAS, dx, dy, dw, dh);
581 EDrawableDumpImage(Drawable draw, const char *txt)
589 EXGetGeometry(draw, NULL, NULL, NULL, &w, &h, NULL, NULL);
590 if (w <= 0 || h <= 0)
592 imlib_context_set_drawable(draw);
593 im = imlib_create_image_from_drawable(None, 0, 0, w, h, !EServerIsGrabbed());
594 imlib_context_set_image(im);
595 imlib_image_set_format("png");
596 sprintf(buf, "%s-%#lx-%d.png", txt, draw, seqn++);
597 Eprintf("EDrawableDumpImage: %s\n", buf);
598 imlib_save_image(buf);
599 imlib_free_image_and_decache();
604 FreePmapMask(PmapMask * pmm)
606 /* type !=0: Created by imlib_render_pixmaps_for_whole_image... */
610 EFreePixmap(pmm->pmap);
612 imlib_free_pixmap_and_mask(pmm->pmap);
619 EFreePixmap(pmm->mask);
624 EImageColorModifier *
625 EImageColorModifierCreate(void)
627 return imlib_create_color_modifier();
631 EImageColorModifierSetTables(EImageColorModifier * icm,
632 unsigned char *r, unsigned char *g,
633 unsigned char *b, unsigned char *a)
638 imlib_context_set_color_modifier(icm);
639 #if 0 /* Useful in this context? */
640 imlib_modify_color_modifier_gamma(0.5);
641 imlib_modify_color_modifier_brightness(0.5);
642 imlib_modify_color_modifier_contrast(0.5);
644 imlib_set_color_modifier_tables(r, g, b, a);
645 imlib_context_set_color_modifier(NULL);