1 #include "config.h"
2 
3 #include <math.h>
4 #include <string.h>
5 #include <stdarg.h>
6 #include <ft2build.h>
7 #include FT_FREETYPE_H
8 #ifdef BUILD_X11
9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h>
11 #include <X11/extensions/shape.h>
12 #else
13 #ifndef X_DISPLAY_MISSING
14 #define X_DISPLAY_MISSING
15 #endif
16 #endif
17 
18 #include "Imlib2.h"
19 #include "blend.h"
20 #include "colormod.h"
21 #include "color_helpers.h"
22 #include "common.h"
23 #include "dynamic_filters.h"
24 #include "file.h"
25 #include "filter.h"
26 #include "font.h"
27 #include "grad.h"
28 #include "image.h"
29 #include "rgbadraw.h"
30 #include "rotate.h"
31 #include "scale.h"
32 #include "script.h"
33 #include "span.h"
34 #include "updates.h"
35 #ifdef BUILD_X11
36 #include "color.h"
37 #include "draw.h"
38 #include "grab.h"
39 #include "rend.h"
40 #include "ximage.h"
41 #endif
42 
43 /* convenience macros */
44 #define   CAST_IMAGE(im, image) (im) = (ImlibImage *)(image)
45 #define   CHECK_PARAM_POINTER_RETURN(func, sparam, param, ret) \
46 if (!(param)) \
47 { \
48   fprintf(stderr, "***** Imlib2 Developer Warning ***** :\n" \
49                   "\tThis program is calling the Imlib call:\n\n" \
50                   "\t%s();\n\n" \
51                   "\tWith the parameter:\n\n" \
52                   "\t%s\n\n" \
53                   "\tbeing NULL. Please fix your program.\n", func, sparam); \
54   return ret; \
55 }
56 
57 #define   CHECK_PARAM_POINTER(func, sparam, param) \
58 if (!(param)) \
59 { \
60   fprintf(stderr, "***** Imlib2 Developer Warning ***** :\n" \
61                   "\tThis program is calling the Imlib call:\n\n" \
62                   "\t%s();\n\n" \
63                   "\tWith the parameter:\n\n" \
64                   "\t%s\n\n" \
65                   "\tbeing NULL. Please fix your program.\n", func, sparam); \
66   return; \
67 }
68 
69 /* internal typedefs for function pointers */
70 typedef void        (*Imlib_Internal_Progress_Function)(void *, char, int, int,
71                                                         int, int);
72 typedef void        (*Imlib_Internal_Data_Destructor_Function)(void *, void *);
73 
74 struct _imlibcontext;
75 typedef struct _imlibcontext ImlibContext;
76 
77 struct _imlibcontext {
78 #ifdef BUILD_X11
79    Display            *display;
80    Visual             *visual;
81    Colormap            colormap;
82    int                 depth;
83    Drawable            drawable;
84    Pixmap              mask;
85 #endif
86    char                anti_alias;
87    char                dither;
88    char                blend;
89    Imlib_Color_Modifier color_modifier;
90    ImlibOp             operation;
91    Imlib_Font          font;
92    Imlib_Text_Direction direction;
93    double              angle;
94    Imlib_Color         color;
95    DATA32              pixel;
96    Imlib_Color_Range   color_range;
97    Imlib_Image         image;
98    Imlib_Image_Data_Memory_Function image_data_memory_func;
99    Imlib_Progress_Function progress_func;
100    char                progress_granularity;
101    char                dither_mask;
102    int                 mask_alpha_threshold;
103    Imlib_Filter        filter;
104    Imlib_Rectangle     cliprect;
105    Imlib_TTF_Encoding  encoding;
106 
107    int                 references;
108    char                dirty;
109 };
110 
111 struct _imlibcontextitem;
112 typedef struct _imlibcontextitem ImlibContextItem;
113 struct _imlibcontextitem {
114    ImlibContext       *context;
115    ImlibContextItem   *below;
116 };
117 
118 /* a stack of contexts -- only used by context-handling functions. */
119 static ImlibContextItem *contexts = NULL;       /* (ImlibContext*) imlib_context_new(); */
120 
121 /* this is the context all functions use rely on */
122 static ImlibContext *ctx = NULL;        /* contexts->context; */
123 
124 /* frees the given context including all its members */
125 static void
__imlib_free_context(ImlibContext * context)126 __imlib_free_context(ImlibContext * context)
127 {
128    ImlibContextItem   *next = contexts;
129 
130    if (ctx == context)
131      {
132         next = contexts->below;
133         free(contexts);
134         contexts = next;
135      }
136 
137    ctx = context;
138 
139    if (ctx->image)
140      {
141         imlib_free_image();
142         ctx->image = NULL;
143      }
144    if (ctx->font)
145      {
146         imlib_free_font();
147         ctx->font = NULL;
148      }
149    if (ctx->color_modifier)
150      {
151         imlib_free_color_modifier();
152         ctx->color_modifier = NULL;
153      }
154    if (ctx->filter)
155      {
156         imlib_free_filter();
157         ctx->filter = NULL;
158      }
159 
160    free(ctx);
161    ctx = next->context;
162 }
163 
164 EAPI                Imlib_Context
imlib_context_new(void)165 imlib_context_new(void)
166 {
167    ImlibContext       *context = malloc(sizeof(ImlibContext));
168 
169 #ifdef BUILD_X11
170    context->display = NULL;
171    context->visual = NULL;
172    context->colormap = 0;
173    context->depth = 0;
174    context->drawable = 0;
175    context->mask = 0;
176 #endif
177    context->anti_alias = 1;
178    context->dither = 0;
179    context->blend = 1;
180    context->color_modifier = NULL;
181    context->operation = (ImlibOp) IMLIB_OP_COPY;
182    context->font = NULL;
183    context->direction = IMLIB_TEXT_TO_RIGHT;
184    context->angle = 0.0;
185    context->color.alpha = 255;
186    context->color.red = 255;
187    context->color.green = 255;
188    context->color.blue = 255;
189    context->pixel = 0xffffffff;
190    context->color_range = NULL;
191    context->image = NULL;
192    context->image_data_memory_func = NULL;
193    context->progress_func = NULL;
194    context->progress_granularity = 0;
195    context->dither_mask = 0;
196    context->mask_alpha_threshold = 128;
197    context->filter = NULL;
198    context->cliprect.x = 0;
199    context->cliprect.y = 0;
200    context->cliprect.w = 0;
201    context->cliprect.h = 0;
202    context->encoding = IMLIB_TTF_ENCODING_ISO_8859_1;
203 
204    context->references = 0;
205    context->dirty = 0;
206 
207    return (Imlib_Context) context;
208 }
209 
210 static ImlibContext *
_imlib_context_get(void)211 _imlib_context_get(void)
212 {
213    ImlibContext       *context;
214 
215    context = imlib_context_new();
216    imlib_context_push(context);
217 
218    return context;
219 }
220 
221 #define CHECK_CONTEXT(_ctx) \
222    if (!_ctx) _ctx = _imlib_context_get()
223 
224 /* frees the given context if it doesn't have any reference anymore. The
225    last (default) context can never be freed.
226    If context is the current context, the context below will be made the
227    current context.
228 */
229 EAPI void
imlib_context_free(Imlib_Context context)230 imlib_context_free(Imlib_Context context)
231 {
232    ImlibContext       *c = (ImlibContext *) context;
233 
234    CHECK_PARAM_POINTER("imlib_context_free", "context", context);
235    if (c == ctx && !contexts->below)
236       return;
237 
238    if (c->references == 0)
239       __imlib_free_context(c);
240    else
241       c->dirty = 1;
242 }
243 
244 EAPI void
imlib_context_push(Imlib_Context context)245 imlib_context_push(Imlib_Context context)
246 {
247    ImlibContextItem   *item;
248 
249    CHECK_PARAM_POINTER("imlib_context_push", "context", context);
250    ctx = (ImlibContext *) context;
251 
252    item = malloc(sizeof(ImlibContextItem));
253    item->context = ctx;
254    item->below = contexts;
255    contexts = item;
256 
257    ctx->references++;
258 }
259 
260 EAPI void
imlib_context_pop(void)261 imlib_context_pop(void)
262 {
263    ImlibContextItem   *item = contexts;
264    ImlibContext       *current_ctx = item->context;
265 
266    if (!item->below)
267       return;
268 
269    contexts = item->below;
270    ctx = contexts->context;
271    current_ctx->references--;
272    if (current_ctx->dirty && current_ctx->references <= 0)
273       __imlib_free_context(current_ctx);
274 
275    free(item);
276 }
277 
278 EAPI                Imlib_Context
imlib_context_get(void)279 imlib_context_get(void)
280 {
281    return (Imlib_Context) ctx;
282 }
283 
284 /* context setting/getting functions */
285 
286 /**
287  * @param x The top left x coordinate of the rectangle.
288  * @param y The top left y coordinate of the rectangle.
289  * @param w The width of the rectangle.
290  * @param h The height of the rectangle.
291  *
292  * Sets the rectangle of the current context.
293  **/
294 EAPI void
imlib_context_set_cliprect(int x,int y,int w,int h)295 imlib_context_set_cliprect(int x, int y, int w, int h)
296 {
297    CHECK_CONTEXT(ctx);
298    ctx->cliprect.x = x;
299    ctx->cliprect.y = y;
300    ctx->cliprect.w = w;
301    ctx->cliprect.h = h;
302 }
303 
304 EAPI void
imlib_context_get_cliprect(int * x,int * y,int * w,int * h)305 imlib_context_get_cliprect(int *x, int *y, int *w, int *h)
306 {
307    CHECK_CONTEXT(ctx);
308    *x = ctx->cliprect.x;
309    *y = ctx->cliprect.y;
310    *w = ctx->cliprect.w;
311    *h = ctx->cliprect.h;
312 }
313 
314 #ifdef BUILD_X11
315 /**
316  * @param display Current display to be used.
317  *
318  * Sets the current X display to be used for rendering of images to
319  * drawables. You do not need to set this if you do not intend to
320  * render an image to an X drawable. If you do you will need to set
321  * this. If you change displays just set this to the new display
322  * pointer. Do not use a Display pointer if you have closed that
323  * display already - also note that if you close a display connection
324  * and continue to render using Imlib2 without setting the display
325  * pointer to NULL or something new, crashes may occur.
326  */
327 EAPI void
imlib_context_set_display(Display * display)328 imlib_context_set_display(Display * display)
329 {
330    CHECK_CONTEXT(ctx);
331    ctx->display = display;
332 }
333 
334 /**
335  * @return The current display.
336  *
337  * Returns the current display used for Imlib2's display context.
338  */
339 EAPI Display       *
imlib_context_get_display(void)340 imlib_context_get_display(void)
341 {
342    CHECK_CONTEXT(ctx);
343    return ctx->display;
344 }
345 
346 /**
347  * Tell Imlib2 that the current display connection has been closed.
348  *
349  * Call when (and only when) you close a display connection but continue
350  * using Imlib2 on a different connection.
351  */
352 EAPI void
imlib_context_disconnect_display(void)353 imlib_context_disconnect_display(void)
354 {
355    CHECK_CONTEXT(ctx);
356    if (!ctx->display)
357       return;
358    __imlib_RenderDisconnect(ctx->display);
359    ctx->display = NULL;
360 }
361 
362 /**
363  * @param visual Current visual to use.
364  *
365  * Sets the current visual to use when rendering images to
366  * drawables or producing pixmaps. You need to set this for anything to
367  * render to a drawable or produce any pixmaps (this can be the default
368  * visual).
369  */
370 EAPI void
imlib_context_set_visual(Visual * visual)371 imlib_context_set_visual(Visual * visual)
372 {
373    CHECK_CONTEXT(ctx);
374    ctx->visual = visual;
375    ctx->depth = imlib_get_visual_depth(ctx->display, ctx->visual);
376 }
377 
378 /**
379  * @return The current visual.
380  *
381  * Returns the current visual used for Imlib2's context.
382  */
383 EAPI Visual        *
imlib_context_get_visual(void)384 imlib_context_get_visual(void)
385 {
386    CHECK_CONTEXT(ctx);
387    return ctx->visual;
388 }
389 
390 /**
391  * @param colormap Colormap to use.
392  *
393  * Sets the colormap to use when rendering to drawables and allocating
394  * colors. You must set this to the colormap you are using to render any
395  * images or produce any pixmaps (this can be the default colormap).
396  */
397 EAPI void
imlib_context_set_colormap(Colormap colormap)398 imlib_context_set_colormap(Colormap colormap)
399 {
400    CHECK_CONTEXT(ctx);
401    ctx->colormap = colormap;
402 }
403 
404 /**
405  * @return The current colormap.
406  *
407  * Returns the current Colormap used for Imlib2's context.
408  */
409 EAPI                Colormap
imlib_context_get_colormap(void)410 imlib_context_get_colormap(void)
411 {
412    CHECK_CONTEXT(ctx);
413    return ctx->colormap;
414 }
415 
416 /**
417  * @param drawable An X drawable.
418  *
419  * Sets the X drawable to which images will be rendered when you call
420  * a render call in Imlib2. This may be either a pixmap or a
421  * window. You must set this to render anything.
422  */
423 EAPI void
imlib_context_set_drawable(Drawable drawable)424 imlib_context_set_drawable(Drawable drawable)
425 {
426    CHECK_CONTEXT(ctx);
427    ctx->drawable = drawable;
428 }
429 
430 /**
431  * @return The current drawable.
432  *
433  * Returns the current Drawable used for Imlib2's context.
434  */
435 EAPI                Drawable
imlib_context_get_drawable(void)436 imlib_context_get_drawable(void)
437 {
438    CHECK_CONTEXT(ctx);
439    return ctx->drawable;
440 }
441 
442 /**
443  * @param mask An 1-bit deep pixmap.
444  *
445  * Sets the 1-bit deep pixmap to be drawn to when rendering to generate
446  * a mask pixmap. This is only useful if the image you are rendering
447  * has alpha. Set this to 0 to not render a pixmap mask.
448  */
449 EAPI void
imlib_context_set_mask(Pixmap mask)450 imlib_context_set_mask(Pixmap mask)
451 {
452    CHECK_CONTEXT(ctx);
453    ctx->mask = mask;
454 }
455 
456 /**
457  * @return The current pixmap.
458  *
459  * Returns the current pixmap destination to be used to render a mask into.
460  */
461 EAPI                Pixmap
imlib_context_get_mask(void)462 imlib_context_get_mask(void)
463 {
464    CHECK_CONTEXT(ctx);
465    return ctx->mask;
466 }
467 
468 /**
469  * @return The current number of cached XImages.
470  */
471 EAPI int
imlib_get_ximage_cache_count_used(void)472 imlib_get_ximage_cache_count_used(void)
473 {
474    CHECK_CONTEXT(ctx);
475    return __imlib_GetXImageCacheCountUsed(ctx->display);
476 }
477 
478 /**
479  * @return The current XImage cache max count.
480  */
481 EAPI int
imlib_get_ximage_cache_count_max(void)482 imlib_get_ximage_cache_count_max(void)
483 {
484    CHECK_CONTEXT(ctx);
485    return __imlib_GetXImageCacheCountMax(ctx->display);
486 }
487 
488 /**
489  * @param count XImage cache max count.
490  *
491  * Sets the maximum number of XImages to cache.
492  * Setting the cache size to 0 effectively flushes the cache and keeps
493  * the cached XImage count at 0 until set to another value.
494  * Whenever you set the max count Imlib2 will flush as many old XImages
495  * from the cache as possible until the current cached XImage count is
496  * less than or equal to the cache max count.
497  */
498 EAPI void
imlib_set_ximage_cache_count_max(int count)499 imlib_set_ximage_cache_count_max(int count)
500 {
501    CHECK_CONTEXT(ctx);
502    __imlib_SetXImageCacheCountMax(ctx->display, count);
503 }
504 
505 /**
506  * @return The current XImage cache memory usage.
507  */
508 EAPI int
imlib_get_ximage_cache_size_used(void)509 imlib_get_ximage_cache_size_used(void)
510 {
511    CHECK_CONTEXT(ctx);
512    return __imlib_GetXImageCacheSizeUsed(ctx->display);
513 }
514 
515 /**
516  * @return The current XImage cache max size.
517  */
518 EAPI int
imlib_get_ximage_cache_size_max(void)519 imlib_get_ximage_cache_size_max(void)
520 {
521    CHECK_CONTEXT(ctx);
522    return __imlib_GetXImageCacheSizeMax(ctx->display);
523 }
524 
525 /**
526  * @param bytes XImage cache max size.
527  *
528  * Sets the XImage cache maximum size. The size is in bytes.
529  * Setting the cache size to 0 effectively flushes the cache and keeps
530  * the cache size at 0 until set to another value.
531  * Whenever you set the max size Imlib2 will flush as many old XImages
532  * from the cache as possible until the current XImage cache usage is
533  * less than or equal to the cache max size.
534  */
535 EAPI void
imlib_set_ximage_cache_size_max(int bytes)536 imlib_set_ximage_cache_size_max(int bytes)
537 {
538    CHECK_CONTEXT(ctx);
539    __imlib_SetXImageCacheSizeMax(ctx->display, bytes);
540 }
541 #endif
542 
543 /**
544  * @param dither_mask The dither mask flag.
545  *
546  * Selects if, you are rendering to a mask, or producing pixmap masks
547  * from images, if the mask is to be dithered or not. passing in 1 for
548  * dither_mask means the mask pixmap will be dithered, 0 means it will
549  * not be dithered.
550  */
551 EAPI void
imlib_context_set_dither_mask(char dither_mask)552 imlib_context_set_dither_mask(char dither_mask)
553 {
554    CHECK_CONTEXT(ctx);
555    ctx->dither_mask = dither_mask;
556 }
557 
558 /**
559  * @return The current dither mask flag.
560  *
561  * Returns the current mode for dithering pixmap masks. 1 means
562  * dithering is enabled and 0 means it is not.
563  */
564 EAPI char
imlib_context_get_dither_mask(void)565 imlib_context_get_dither_mask(void)
566 {
567    CHECK_CONTEXT(ctx);
568    return ctx->dither_mask;
569 }
570 
571 /**
572  * @param mask_alpha_threshold The mask alpha threshold.
573  *
574  * Selects, if you are rendering to a mask, the alpha threshold above which
575  * mask bits are set. The default mask alpha threshold is 128, meaning that
576  * a mask bit will be set if the pixel alpha is >= 128.
577  */
578 EAPI void
imlib_context_set_mask_alpha_threshold(int mask_alpha_threshold)579 imlib_context_set_mask_alpha_threshold(int mask_alpha_threshold)
580 {
581    CHECK_CONTEXT(ctx);
582    ctx->mask_alpha_threshold = mask_alpha_threshold;
583 }
584 
585 /**
586  * @return The current mask mask alpha threshold.
587  *
588  * Returns the current mask alpha threshold.
589  */
590 EAPI int
imlib_context_get_mask_alpha_threshold(void)591 imlib_context_get_mask_alpha_threshold(void)
592 {
593    CHECK_CONTEXT(ctx);
594    return ctx->mask_alpha_threshold;
595 }
596 
597 /**
598  * @param anti_alias The anti alias flag.
599  *
600  * Toggles "anti-aliased" scaling of images. This
601  * isn't quite correct since it's actually super and sub pixel
602  * sampling that it turns on and off, but anti-aliasing is used for
603  * having "smooth" edges to lines and shapes and this means when
604  * images are scaled they will keep their smooth appearance. Passing
605  * in 1 turns this on and 0 turns it off.
606  */
607 EAPI void
imlib_context_set_anti_alias(char anti_alias)608 imlib_context_set_anti_alias(char anti_alias)
609 {
610    CHECK_CONTEXT(ctx);
611    ctx->anti_alias = anti_alias;
612 }
613 
614 /**
615  * @return The current anti alias flag.
616  *
617  * Returns if Imlib2 currently will smoothly scale images. 1 means it
618  * will and 0 means it will not.
619  */
620 EAPI char
imlib_context_get_anti_alias(void)621 imlib_context_get_anti_alias(void)
622 {
623    CHECK_CONTEXT(ctx);
624    return ctx->anti_alias;
625 }
626 
627 /**
628  * @param dither The dithering flag.
629  *
630  * Sets the dithering flag for rendering to a drawable or when pixmaps
631  * are produced. This affects the color image appearance by enabling
632  * dithering. Dithering slows down rendering but produces considerably
633  * better results. this option has no effect foe rendering in 24 bit
634  * and up, but in 16 bit and lower it will dither, producing smooth
635  * gradients and much better quality images. setting dither to 1
636  * enables it and 0 disables it.
637  */
638 EAPI void
imlib_context_set_dither(char dither)639 imlib_context_set_dither(char dither)
640 {
641    CHECK_CONTEXT(ctx);
642    ctx->dither = dither;
643 }
644 
645 /**
646  * @return The current dithering flag.
647  *
648  * Returns if image data is rendered with dithering currently. 1 means
649  * yes and 0 means no.
650  */
651 EAPI char
imlib_context_get_dither(void)652 imlib_context_get_dither(void)
653 {
654    CHECK_CONTEXT(ctx);
655    return ctx->dither;
656 }
657 
658 /**
659  * @param blend The blending flag.
660  *
661  * When rendering an image to a drawable, Imlib2 is able to blend the
662  * image directly onto the drawable during rendering. Setting this to 1
663  * will enable this. If the image has no alpha channel this has no
664  * effect. Setting it to 0 will disable this.
665  */
666 EAPI void
imlib_context_set_blend(char blend)667 imlib_context_set_blend(char blend)
668 {
669    CHECK_CONTEXT(ctx);
670    ctx->blend = blend;
671 }
672 
673 /**
674  * @return The current blending flag.
675  *
676  * Returns if Imlib2 will blend images onto a drawable whilst
677  * rendering to that drawable. 1 means yes and 0 means no.
678  */
679 EAPI char
imlib_context_get_blend(void)680 imlib_context_get_blend(void)
681 {
682    CHECK_CONTEXT(ctx);
683    return ctx->blend;
684 }
685 
686 /**
687  * @param color_modifier Current color modifier.
688  *
689  * Sets the current color modifier used for rendering pixmaps or
690  * images to a drawable or images onto other images. Color modifiers
691  * are lookup tables that map the values in the red, green, blue and
692  * alpha channels to other values in the same channel when rendering,
693  * allowing for fades, color correction etc. to be done whilst
694  * rendering. pass in NULL as the color_modifier to disable the color
695  * modifier for rendering.
696  */
697 EAPI void
imlib_context_set_color_modifier(Imlib_Color_Modifier color_modifier)698 imlib_context_set_color_modifier(Imlib_Color_Modifier color_modifier)
699 {
700    CHECK_CONTEXT(ctx);
701    ctx->color_modifier = color_modifier;
702 }
703 
704 /**
705  * @return The current color modifier.
706  *
707  * Returns the current color modifier being used.
708  */
709 EAPI                Imlib_Color_Modifier
imlib_context_get_color_modifier(void)710 imlib_context_get_color_modifier(void)
711 {
712    CHECK_CONTEXT(ctx);
713    return ctx->color_modifier;
714 }
715 
716 /**
717  * @param operation
718  *
719  * When Imlib2 draws an image onto another or an image onto a drawable
720  * it is able to do more than just blend the result on using the given
721  * alpha channel of the image. It is also able to do saturating
722  * additive, subtractive and a combination of the both (called reshade)
723  * rendering. The default mode is IMLIB_OP_COPY. you can also set it to
724  * IMLIB_OP_ADD, IMLIB_OP_SUBTRACT or IMLIB_OP_RESHADE. Use this
725  * function to set the rendering operation. IMLIB_OP_COPY performs
726  * basic alpha blending: DST = (SRC * A) + (DST * (1 -
727  * A)). IMLIB_OP_ADD does DST = DST + (SRC * A). IMLIB_OP_SUBTRACT does
728  * DST = DST - (SRC * A) and IMLIB_OP_RESHADE does DST = DST + (((SRC -
729  * 0.5) / 2) * A).
730  */
731 EAPI void
imlib_context_set_operation(Imlib_Operation operation)732 imlib_context_set_operation(Imlib_Operation operation)
733 {
734    CHECK_CONTEXT(ctx);
735    ctx->operation = (ImlibOp) operation;
736 }
737 
738 /**
739  * @return The current operation mode.
740  *
741  * Returns the current operation mode.
742  */
743 EAPI                Imlib_Operation
imlib_context_get_operation(void)744 imlib_context_get_operation(void)
745 {
746    CHECK_CONTEXT(ctx);
747    return (Imlib_Operation) ctx->operation;
748 }
749 
750 /**
751  * @param font Current font.
752  *
753  * Sets the current font to use when rendering text. you should load
754  * the font first with imlib_load_font().
755  */
756 EAPI void
imlib_context_set_font(Imlib_Font font)757 imlib_context_set_font(Imlib_Font font)
758 {
759    CHECK_CONTEXT(ctx);
760    ctx->font = font;
761 }
762 
763 /**
764  * @return The current font.
765  *
766  * Returns the current font.
767  */
768 EAPI                Imlib_Font
imlib_context_get_font(void)769 imlib_context_get_font(void)
770 {
771    CHECK_CONTEXT(ctx);
772    return ctx->font;
773 }
774 
775 /**
776  * @param direction Text direction.
777  *
778  * Sets the direction in which to draw text in terms of simple 90
779  * degree orientations or an arbitrary angle. The direction can be one
780  * of IMLIB_TEXT_TO_RIGHT, IMLIB_TEXT_TO_LEFT, IMLIB_TEXT_TO_DOWN,
781  * IMLIB_TEXT_TO_UP or IMLIB_TEXT_TO_ANGLE. The default is
782  * IMLIB_TEXT_TO_RIGHT. If you use IMLIB_TEXT_TO_ANGLE, you will also
783  * have to set the angle with imlib_context_set_angle().
784  */
785 EAPI void
imlib_context_set_direction(Imlib_Text_Direction direction)786 imlib_context_set_direction(Imlib_Text_Direction direction)
787 {
788    CHECK_CONTEXT(ctx);
789    ctx->direction = direction;
790 }
791 
792 /**
793  * @param angle Angle of the text strings.
794  *
795  * Sets the angle at which text strings will be drawn if the text
796  * direction has been set to IMLIB_TEXT_TO_ANGLE with
797  * imlib_context_set_direction().
798  */
799 EAPI void
imlib_context_set_angle(double angle)800 imlib_context_set_angle(double angle)
801 {
802    CHECK_CONTEXT(ctx);
803    ctx->angle = angle;
804 }
805 
806 /**
807  * @return The current angle of the text strings.
808  *
809  * Returns the current angle used to render text at if the direction
810  * is IMLIB_TEXT_TO_ANGLE.
811  */
812 EAPI double
imlib_context_get_angle(void)813 imlib_context_get_angle(void)
814 {
815    CHECK_CONTEXT(ctx);
816    return ctx->angle;
817 }
818 
819 /**
820  * @return The current direction of the text.
821  *
822  * Returns the current direction to render text in.
823  */
824 EAPI                Imlib_Text_Direction
imlib_context_get_direction(void)825 imlib_context_get_direction(void)
826 {
827    CHECK_CONTEXT(ctx);
828    return ctx->direction;
829 }
830 
831 /**
832  * @param red Red channel of the current color.
833  * @param green Green channel of the current color.
834  * @param blue Blue channel of the current color.
835  * @param alpha Alpha channel of the current color.
836  *
837  * Sets the color with which text, lines and rectangles are drawn when
838  * being rendered onto an image. Values for @p red, @p green, @p blue
839  * and @p alpha are between 0 and 255 - any other values have
840  * undefined results.
841  */
842 EAPI void
imlib_context_set_color(int red,int green,int blue,int alpha)843 imlib_context_set_color(int red, int green, int blue, int alpha)
844 {
845    DATA8               r, g, b, a;
846 
847    CHECK_CONTEXT(ctx);
848 
849    r = red;
850    g = green;
851    b = blue;
852    a = alpha;
853 
854    ctx->color.red = r;
855    ctx->color.green = g;
856    ctx->color.blue = b;
857    ctx->color.alpha = a;
858 
859    ctx->pixel = PIXEL_ARGB(a, r, g, b);
860 }
861 
862 /**
863  * @param red Red channel of the current color.
864  * @param green Green channel of the current color.
865  * @param blue Blue channel of the current color.
866  * @param alpha Alpha channel of the current color.
867  *
868  * Returns the current color for rendering text, rectangles and lines.
869  */
870 EAPI void
imlib_context_get_color(int * red,int * green,int * blue,int * alpha)871 imlib_context_get_color(int *red, int *green, int *blue, int *alpha)
872 {
873    CHECK_CONTEXT(ctx);
874    *red = ctx->color.red;
875    *green = ctx->color.green;
876    *blue = ctx->color.blue;
877    *alpha = ctx->color.alpha;
878 }
879 
880 /**
881  * @return The current color.
882  *
883  * Returns the current color as a color struct. Do NOT free this
884  * pointer.
885  */
886 EAPI Imlib_Color   *
imlib_context_get_imlib_color(void)887 imlib_context_get_imlib_color(void)
888 {
889    CHECK_CONTEXT(ctx);
890    return &ctx->color;
891 }
892 
893 /**
894  * @param hue Hue channel of the current color.
895  * @param saturation Saturation channel of the current color.
896  * @param value Value channel of the current color.
897  * @param alpha Alpha channel of the current color.
898  *
899  * Sets the color in HSVA space. Values for @p hue are between 0 and 360,
900  * values for @p saturation and @p value between 0 and 1, and values for
901  * @p alpha are between 0 and 255 - any other values have undefined
902  * results.
903  */
904 EAPI void
imlib_context_set_color_hsva(float hue,float saturation,float value,int alpha)905 imlib_context_set_color_hsva(float hue, float saturation, float value,
906                              int alpha)
907 {
908    int                 r, g, b;
909 
910    __imlib_hsv_to_rgb(hue, saturation, value, &r, &g, &b);
911    imlib_context_set_color(r, g, b, alpha);
912 }
913 
914 /**
915  * @param hue Hue channel of the current color.
916  * @param saturation Saturation channel of the current color.
917  * @param value Value channel of the current color.
918  * @param alpha Alpha channel of the current color.
919  *
920  * Returns the current color for rendering text, rectangles and lines
921  * in HSVA space.
922  */
923 EAPI void
imlib_context_get_color_hsva(float * hue,float * saturation,float * value,int * alpha)924 imlib_context_get_color_hsva(float *hue, float *saturation, float *value,
925                              int *alpha)
926 {
927    int                 r, g, b;
928 
929    imlib_context_get_color(&r, &g, &b, alpha);
930    __imlib_rgb_to_hsv(r, g, b, hue, saturation, value);
931 }
932 
933 /**
934  * @param hue Hue channel of the current color.
935  * @param lightness Lightness channel of the current color.
936  * @param saturation Saturation channel of the current color.
937  * @param alpha Alpha channel of the current color.
938  *
939  * Sets the color in HLSA space. Values for @p hue are between 0 and 360,
940  * values for @p lightness and @p saturation between 0 and 1, and values for
941  * @p alpha are between 0 and 255 - any other values have undefined
942  * results.
943  */
944 EAPI void
imlib_context_set_color_hlsa(float hue,float lightness,float saturation,int alpha)945 imlib_context_set_color_hlsa(float hue, float lightness, float saturation,
946                              int alpha)
947 {
948    int                 r, g, b;
949 
950    __imlib_hls_to_rgb(hue, lightness, saturation, &r, &g, &b);
951    imlib_context_set_color(r, g, b, alpha);
952 }
953 
954 /**
955  * @param hue Hue channel of the current color.
956  * @param lightness Lightness channel of the current color.
957  * @param saturation Saturation channel of the current color.
958  * @param alpha Alpha channel of the current color.
959  *
960  * Returns the current color for rendering text, rectangles and lines
961  * in HLSA space.
962  */
963 EAPI void
imlib_context_get_color_hlsa(float * hue,float * lightness,float * saturation,int * alpha)964 imlib_context_get_color_hlsa(float *hue, float *lightness, float *saturation,
965                              int *alpha)
966 {
967    int                 r, g, b;
968 
969    imlib_context_get_color(&r, &g, &b, alpha);
970    __imlib_rgb_to_hls(r, g, b, hue, lightness, saturation);
971 }
972 
973 /**
974  * @param cyan Cyan channel of the current color.
975  * @param magenta Magenta channel of the current color.
976  * @param yellow Yellow channel of the current color.
977  * @param alpha Alpha channel of the current color.
978  *
979  * Sets the color in CMYA space. Values for @p cyan, @p magenta, @p yellow and
980  * @p alpha are between 0 and 255 - any other values have undefined
981  * results.
982  */
983 EAPI void
imlib_context_set_color_cmya(int cyan,int magenta,int yellow,int alpha)984 imlib_context_set_color_cmya(int cyan, int magenta, int yellow, int alpha)
985 {
986    DATA8               r, g, b, a;
987 
988    CHECK_CONTEXT(ctx);
989 
990    r = 255 - cyan;
991    g = 255 - magenta;
992    b = 255 - yellow;
993    a = alpha;
994 
995    ctx->color.red = r;
996    ctx->color.green = g;
997    ctx->color.blue = b;
998    ctx->color.alpha = a;
999 
1000    ctx->pixel = PIXEL_ARGB(a, r, g, b);
1001 }
1002 
1003 /**
1004  * @param cyan Cyan channel of the current color.
1005  * @param magenta Magenta channel of the current color.
1006  * @param yellow Yellow channel of the current color.
1007  * @param alpha Alpha channel of the current color.
1008  *
1009  * Returns the current color for rendering text, rectangles and lines
1010  * in CMYA space.
1011  */
1012 EAPI void
imlib_context_get_color_cmya(int * cyan,int * magenta,int * yellow,int * alpha)1013 imlib_context_get_color_cmya(int *cyan, int *magenta, int *yellow, int *alpha)
1014 {
1015    CHECK_CONTEXT(ctx);
1016    *cyan = 255 - ctx->color.red;
1017    *magenta = 255 - ctx->color.green;
1018    *yellow = 255 - ctx->color.blue;
1019    *alpha = ctx->color.alpha;
1020 }
1021 
1022 /**
1023  * @param color_range Color range.
1024  *
1025  * Sets the current color range to use for rendering gradients.
1026  */
1027 EAPI void
imlib_context_set_color_range(Imlib_Color_Range color_range)1028 imlib_context_set_color_range(Imlib_Color_Range color_range)
1029 {
1030    CHECK_CONTEXT(ctx);
1031    ctx->color_range = color_range;
1032 }
1033 
1034 /**
1035  * @return The current color range.
1036  *
1037  * Returns the current color range being used for gradients.
1038  */
1039 EAPI                Imlib_Color_Range
imlib_context_get_color_range(void)1040 imlib_context_get_color_range(void)
1041 {
1042    CHECK_CONTEXT(ctx);
1043    return ctx->color_range;
1044 }
1045 
1046 /**
1047  * @param memory_function An image data memory management function.
1048  *
1049  * Sets the image data memory management function.
1050  */
1051 EAPI void
imlib_context_set_image_data_memory_function(Imlib_Image_Data_Memory_Function memory_function)1052 imlib_context_set_image_data_memory_function(Imlib_Image_Data_Memory_Function
1053                                              memory_function)
1054 {
1055    CHECK_CONTEXT(ctx);
1056    ctx->image_data_memory_func = memory_function;
1057 }
1058 
1059 /**
1060  * @param progress_function A progress function.
1061  *
1062  * Sets the progress function to be called back whilst loading
1063  * images. Set this to the function to be called, or set it to NULL to
1064  * disable progress callbacks whilst loading.
1065  */
1066 EAPI void
imlib_context_set_progress_function(Imlib_Progress_Function progress_function)1067 imlib_context_set_progress_function(Imlib_Progress_Function progress_function)
1068 {
1069    CHECK_CONTEXT(ctx);
1070    ctx->progress_func = progress_function;
1071 }
1072 
1073 /**
1074  * @return The image data memory management function.
1075  *
1076  * Returns the current image data memeory management function being used.
1077  */
1078 EAPI                Imlib_Image_Data_Memory_Function
imlib_context_get_image_data_memory_function(void)1079 imlib_context_get_image_data_memory_function(void)
1080 {
1081    CHECK_CONTEXT(ctx);
1082    return ctx->image_data_memory_func;
1083 }
1084 
1085 /**
1086  * @return The current progress function.
1087  *
1088  * Returns the current progress function being used.
1089  */
1090 EAPI                Imlib_Progress_Function
imlib_context_get_progress_function(void)1091 imlib_context_get_progress_function(void)
1092 {
1093    CHECK_CONTEXT(ctx);
1094    return ctx->progress_func;
1095 }
1096 
1097 /**
1098  * @param progress_granularity A char.
1099  *
1100  * This hints as to how often to call the progress callback. 0 means
1101  * as often as possible. 1 means whenever 15 more of the image has been
1102  * decoded, 10 means every 10% of the image decoding, 50 means every
1103  * 50% and 100 means only call at the end. Values outside of the range
1104  * 0-100 are undefined.
1105  */
1106 EAPI void
imlib_context_set_progress_granularity(char progress_granularity)1107 imlib_context_set_progress_granularity(char progress_granularity)
1108 {
1109    CHECK_CONTEXT(ctx);
1110    ctx->progress_granularity = progress_granularity;
1111 }
1112 
1113 /**
1114  * @return The current progress granularity
1115  *
1116  * Returns the current progress granularity being used.
1117  */
1118 EAPI char
imlib_context_get_progress_granularity(void)1119 imlib_context_get_progress_granularity(void)
1120 {
1121    CHECK_CONTEXT(ctx);
1122    return ctx->progress_granularity;
1123 }
1124 
1125 /**
1126  * @param image Current image.
1127  *
1128  * Sets the current image Imlib2 will be using with its function calls.
1129  */
1130 EAPI void
imlib_context_set_image(Imlib_Image image)1131 imlib_context_set_image(Imlib_Image image)
1132 {
1133    CHECK_CONTEXT(ctx);
1134    ctx->image = image;
1135 }
1136 
1137 /**
1138  * @return The current image.
1139  *
1140  * Returns the current context image.
1141  */
1142 EAPI                Imlib_Image
imlib_context_get_image(void)1143 imlib_context_get_image(void)
1144 {
1145    CHECK_CONTEXT(ctx);
1146    return ctx->image;
1147 }
1148 
1149 EAPI void
imlib_context_set_TTF_encoding(Imlib_TTF_Encoding encoding)1150 imlib_context_set_TTF_encoding(Imlib_TTF_Encoding encoding)
1151 {
1152    CHECK_CONTEXT(ctx);
1153    ctx->encoding = encoding;
1154 }
1155 
1156 EAPI                Imlib_TTF_Encoding
imlib_context_get_TTF_encoding(void)1157 imlib_context_get_TTF_encoding(void)
1158 {
1159    CHECK_CONTEXT(ctx);
1160    return ctx->encoding;
1161 }
1162 
1163 /* imlib api */
1164 
1165 /**
1166  * @return The current image cache memory usage.
1167  *
1168  * Returns the current size of the image cache in bytes.
1169  * The cache is a unified cache used for image data AND pixmaps.
1170  */
1171 EAPI int
imlib_get_cache_used(void)1172 imlib_get_cache_used(void)
1173 {
1174    CHECK_CONTEXT(ctx);
1175    return __imlib_CurrentCacheSize();
1176 }
1177 
1178 /**
1179  * @return The current image cache max size.
1180  *
1181  * Returns the current maximum size of the image cache in bytes.
1182  * The cache is a unified cache used for image data AND pixmaps.
1183  */
1184 EAPI int
imlib_get_cache_size(void)1185 imlib_get_cache_size(void)
1186 {
1187    CHECK_CONTEXT(ctx);
1188    return __imlib_GetCacheSize();
1189 }
1190 
1191 /**
1192  * @param bytes Image cache max size.
1193  *
1194  * Sets the cache size. The size is in bytes. Setting the cache size to
1195  * 0 effectively flushes the cache and keeps the cache size at 0 until
1196  * set to another value. Whenever you set the cache size Imlib2 will
1197  * flush as many old images and pixmap from the cache as needed until
1198  * the current cache usage is less than or equal to the cache size.
1199  */
1200 EAPI void
imlib_set_cache_size(int bytes)1201 imlib_set_cache_size(int bytes)
1202 {
1203    CHECK_CONTEXT(ctx);
1204    __imlib_SetCacheSize(bytes);
1205 }
1206 
1207 /**
1208  * @return The current number of colors.
1209  *
1210  * Gets the number of colors Imlib2 currently at a maximum is allowed
1211  * to allocate for rendering. The default is 256.
1212  */
1213 EAPI int
imlib_get_color_usage(void)1214 imlib_get_color_usage(void)
1215 {
1216    CHECK_CONTEXT(ctx);
1217 #ifdef BUILD_X11
1218    return (int)_max_colors;
1219 #else
1220    return 256;
1221 #endif
1222 }
1223 
1224 /**
1225  * @param max Maximum number of colors.
1226  *
1227  * Sets the maximum number of colors you would like Imlib2 to allocate
1228  * for you when rendering. The default is 256. This has no effect in
1229  * depths greater than 8 bit.
1230  */
1231 EAPI void
imlib_set_color_usage(int max)1232 imlib_set_color_usage(int max)
1233 {
1234    CHECK_CONTEXT(ctx);
1235 #ifdef BUILD_X11
1236    if (max < 2)
1237       max = 2;
1238    else if (max > 256)
1239       max = 256;
1240    _max_colors = max;
1241 #endif
1242 }
1243 
1244 /**
1245  * If you want Imlib2 to forcibly flush any cached loaders it has and
1246  * re-load them from disk (this is useful if the program just
1247  * installed a new loader and does not want to wait till Imlib2 deems
1248  * it an optimal time to rescan the loaders)
1249  */
1250 EAPI void
imlib_flush_loaders(void)1251 imlib_flush_loaders(void)
1252 {
1253    CHECK_CONTEXT(ctx);
1254    __imlib_RemoveAllLoaders();
1255 }
1256 
1257 #ifdef BUILD_X11
1258 /**
1259  * @param display The current display
1260  * @param visual The current visual
1261  * @return
1262  *
1263  * Convenience function that returns the depth of a visual for that
1264  * display.
1265  */
1266 EAPI int
imlib_get_visual_depth(Display * display,Visual * visual)1267 imlib_get_visual_depth(Display * display, Visual * visual)
1268 {
1269    CHECK_CONTEXT(ctx);
1270    CHECK_PARAM_POINTER_RETURN("imlib_get_visual_depth", "display", display, 0);
1271    CHECK_PARAM_POINTER_RETURN("imlib_get_visual_depth", "visual", visual, 0);
1272    return __imlib_XActualDepth(display, visual);
1273 }
1274 
1275 /**
1276  * @param display The current display
1277  * @param screen The screen
1278  * @param depth_return The depth of the returned visual.
1279  * @return The best visual.
1280  *
1281  * Returns the visual for the display @p display and the screen @p
1282  * screen that Imlib2 thinks
1283  * will give you the best quality output. @p depth_return should point to
1284  * an int that will be filled with the depth of that visual too.
1285  */
1286 EAPI Visual        *
imlib_get_best_visual(Display * display,int screen,int * depth_return)1287 imlib_get_best_visual(Display * display, int screen, int *depth_return)
1288 {
1289    CHECK_CONTEXT(ctx);
1290    CHECK_PARAM_POINTER_RETURN("imlib_get_best_visual", "display", display,
1291                               NULL);
1292    CHECK_PARAM_POINTER_RETURN("imlib_get_best_visual", "depth_return",
1293                               depth_return, NULL);
1294    return __imlib_BestVisual(display, screen, depth_return);
1295 }
1296 #endif
1297 
1298 /**
1299  * @param file Image file.
1300  * @return An image handle.
1301  *
1302  * Loads an image from disk located at the path specified by
1303  * @p file. Please see the section \ref loading for more
1304  * detail. Returns an image handle on success or NULL on failure.
1305  */
1306 EAPI                Imlib_Image
imlib_load_image(const char * file)1307 imlib_load_image(const char *file)
1308 {
1309    Imlib_Image         im = NULL;
1310    Imlib_Image         prev_ctxt_image;
1311 
1312    CHECK_CONTEXT(ctx);
1313    CHECK_PARAM_POINTER_RETURN("imlib_load_image", "file", file, NULL);
1314    prev_ctxt_image = ctx->image;
1315    im = __imlib_LoadImage(file, NULL,
1316                           (ImlibProgressFunction) ctx->progress_func,
1317                           ctx->progress_granularity, 0, 0, NULL);
1318    ctx->image = prev_ctxt_image;
1319    return (Imlib_Image) im;
1320 }
1321 
1322 /**
1323  * @param file Image file.
1324  * @return An image handle.
1325  *
1326  * Loads an image from disk located at the path specified by
1327  * @p file. This forces the image data to be decoded at load time too,
1328  * instead of decoding being deferred until it is needed. Returns an
1329  * image handle on success or NULL on failure.
1330  */
1331 EAPI                Imlib_Image
imlib_load_image_immediately(const char * file)1332 imlib_load_image_immediately(const char *file)
1333 {
1334    Imlib_Image         im = NULL;
1335    Imlib_Image         prev_ctxt_image;
1336 
1337    CHECK_CONTEXT(ctx);
1338    CHECK_PARAM_POINTER_RETURN("imlib_load_image_immediately", "file", file,
1339                               NULL);
1340    prev_ctxt_image = ctx->image;
1341    im = __imlib_LoadImage(file, NULL,
1342                           (ImlibProgressFunction) ctx->progress_func,
1343                           ctx->progress_granularity, 1, 0, NULL);
1344    ctx->image = prev_ctxt_image;
1345    return (Imlib_Image) im;
1346 }
1347 
1348 /**
1349  * @param file Image file.
1350  * @return An image handle.
1351  *
1352  * Loads the image without looking in the cache first. Returns an
1353  * image handle on success or NULL on failure.
1354  */
1355 EAPI                Imlib_Image
imlib_load_image_without_cache(const char * file)1356 imlib_load_image_without_cache(const char *file)
1357 {
1358    Imlib_Image         im = NULL;
1359    Imlib_Image         prev_ctxt_image;
1360 
1361    CHECK_CONTEXT(ctx);
1362    CHECK_PARAM_POINTER_RETURN("imlib_load_image_without_cache", "file",
1363                               file, NULL);
1364    prev_ctxt_image = ctx->image;
1365    im = __imlib_LoadImage(file, NULL,
1366                           (ImlibProgressFunction) ctx->progress_func,
1367                           ctx->progress_granularity, 0, 1, NULL);
1368    ctx->image = prev_ctxt_image;
1369    return (Imlib_Image) im;
1370 }
1371 
1372 /**
1373  * @param file Image file.
1374  * @return An image handle.
1375  *
1376  * Loads the image without deferred image data decoding (i.e. it is
1377  * decoded straight away) and without looking in the cache. Returns an
1378  * image handle on success or NULL on failure.
1379  */
1380 EAPI                Imlib_Image
imlib_load_image_immediately_without_cache(const char * file)1381 imlib_load_image_immediately_without_cache(const char *file)
1382 {
1383    Imlib_Image         im = NULL;
1384    Imlib_Image         prev_ctxt_image;
1385 
1386    CHECK_CONTEXT(ctx);
1387    CHECK_PARAM_POINTER_RETURN("imlib_load_image_immediately_without_cache",
1388                               "file", file, NULL);
1389    prev_ctxt_image = ctx->image;
1390    im = __imlib_LoadImage(file, NULL,
1391                           (ImlibProgressFunction) ctx->progress_func,
1392                           ctx->progress_granularity, 1, 1, NULL);
1393    ctx->image = prev_ctxt_image;
1394    return (Imlib_Image) im;
1395 }
1396 
1397 /**
1398  * @param fd Image file descriptor.
1399  * @param file Image file.
1400  * @return An image handle.
1401  *
1402  * Loads the image without deferred image data decoding (i.e. it is
1403  * decoded straight away) and without looking in the cache. Returns an
1404  * image handle on success or NULL on failure.
1405  * fd will be closed after calling this function.
1406  */
1407 EAPI                Imlib_Image
imlib_load_image_fd(int fd,const char * file)1408 imlib_load_image_fd(int fd, const char *file)
1409 {
1410    Imlib_Image         im = NULL;
1411    Imlib_Image         prev_ctxt_image;
1412    FILE               *fp;
1413 
1414    CHECK_CONTEXT(ctx);
1415    CHECK_PARAM_POINTER_RETURN("imlib_load_image_fd", "file", file, NULL);
1416    fp = fdopen(fd, "rb");
1417    if (fp)
1418      {
1419         prev_ctxt_image = ctx->image;
1420         im = __imlib_LoadImage(file, fp,
1421                                (ImlibProgressFunction) ctx->progress_func,
1422                                ctx->progress_granularity, 1, 1, NULL);
1423         fclose(fp);
1424         ctx->image = prev_ctxt_image;
1425      }
1426    else
1427      {
1428         close(fd);
1429      }
1430    return (Imlib_Image) im;
1431 }
1432 
1433 /**
1434  * @param file Image file.
1435  * @param error_return The returned error.
1436  * @return An image handle.
1437  *
1438  * Loads an image at the path @p file on disk. If it succeeds it returns
1439  * a valid image handle, if not NULL is returned and @p error_return
1440  * is set to the detail of the error.
1441  */
1442 EAPI                Imlib_Image
imlib_load_image_with_error_return(const char * file,Imlib_Load_Error * error_return)1443 imlib_load_image_with_error_return(const char *file,
1444                                    Imlib_Load_Error * error_return)
1445 {
1446    Imlib_Image         im = NULL;
1447    ImlibLoadError      er;
1448    Imlib_Image         prev_ctxt_image;
1449 
1450    CHECK_CONTEXT(ctx);
1451    CHECK_PARAM_POINTER_RETURN("imlib_load_image_with_error_return", "file",
1452                               file, NULL);
1453    prev_ctxt_image = ctx->image;
1454    im = __imlib_LoadImage(file, NULL,
1455                           (ImlibProgressFunction) ctx->progress_func,
1456                           ctx->progress_granularity, 1, 0, &er);
1457    ctx->image = prev_ctxt_image;
1458    if (im)
1459       *error_return = IMLIB_LOAD_ERROR_NONE;
1460    else
1461      {
1462         if (er == IMLIB_LOAD_ERROR_NONE)
1463            *error_return = IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT;
1464         else
1465            *error_return = (Imlib_Load_Error) er;
1466      }
1467    return im;
1468 }
1469 
1470 /**
1471  * Frees the image that is set as the current image in Imlib2's context.
1472  */
1473 EAPI void
imlib_free_image(void)1474 imlib_free_image(void)
1475 {
1476    CHECK_CONTEXT(ctx);
1477    CHECK_PARAM_POINTER("imlib_free_image", "image", ctx->image);
1478    __imlib_FreeImage(ctx->image);
1479    ctx->image = NULL;
1480 }
1481 
1482 /**
1483  * Frees the current image in Imlib2's context AND removes it from the
1484  * cache.
1485  */
1486 EAPI void
imlib_free_image_and_decache(void)1487 imlib_free_image_and_decache(void)
1488 {
1489    ImlibImage         *im;
1490 
1491    CHECK_CONTEXT(ctx);
1492    CHECK_PARAM_POINTER("imlib_free_image_and_decache", "image", ctx->image);
1493    CAST_IMAGE(im, ctx->image);
1494    SET_FLAG(im->flags, F_INVALID);
1495    __imlib_FreeImage(im);
1496    ctx->image = NULL;
1497 }
1498 
1499 /**
1500  * Returns the width in pixels of the current image in Imlib2's context.
1501  */
1502 EAPI int
imlib_image_get_width(void)1503 imlib_image_get_width(void)
1504 {
1505    ImlibImage         *im;
1506 
1507    CHECK_CONTEXT(ctx);
1508    CHECK_PARAM_POINTER_RETURN("imlib_image_get_width", "image", ctx->image, 0);
1509    CAST_IMAGE(im, ctx->image);
1510    return im->w;
1511 }
1512 
1513 /**
1514  * Returns the height in pixels of the current image in Imlib2's context.
1515  */
1516 EAPI int
imlib_image_get_height(void)1517 imlib_image_get_height(void)
1518 {
1519    ImlibImage         *im;
1520 
1521    CHECK_CONTEXT(ctx);
1522    CHECK_PARAM_POINTER_RETURN("imlib_image_get_height", "image", ctx->image, 0);
1523    CAST_IMAGE(im, ctx->image);
1524    return im->h;
1525 }
1526 
1527 /**
1528  * @return The current filename.
1529  *
1530  * Returns the filename for the file that is set as the current
1531  * context. The pointer returned is only valid as long as no operations
1532  * cause the filename of the image to change. Saving the file with a
1533  * different name would cause this. It is suggested you duplicate the
1534  * string if you wish to continue to use the string for later
1535  * processing. Do not free the string pointer returned by this
1536  * function.
1537  */
1538 EAPI const char    *
imlib_image_get_filename(void)1539 imlib_image_get_filename(void)
1540 {
1541    ImlibImage         *im;
1542 
1543    CHECK_CONTEXT(ctx);
1544    CHECK_PARAM_POINTER_RETURN("imlib_image_get_filename", "image", ctx->image,
1545                               0);
1546    CAST_IMAGE(im, ctx->image);
1547    /* strdup() the returned value if you want to alter it! */
1548    return (const char *)(im->file);
1549 }
1550 
1551 /**
1552  * @return A pointer to the image data.
1553  *
1554  * Returns a pointer to the image data in the image set as the image
1555  * for the current context. When you get this pointer it is assumed you
1556  * are planning on writing to the data, thus once you do this the image
1557  * can no longer be used for caching - in fact all images cached from
1558  * this one will also be affected when you put the data back. If this
1559  * matters it is suggested you clone the image first before playing
1560  * with the image data. The image data is returned in the format of a
1561  * DATA32 (32 bits) per pixel in a linear array ordered from the top
1562  * left of the image to the bottom right going from left to right each
1563  * line. Each pixel has the upper 8 bits as the alpha channel and the
1564  * lower 8 bits are the blue channel - so a pixel's bits are ARGB (from
1565  * most to least significant, 8 bits per channel). You must put the
1566  * data back at some point.
1567  */
1568 EAPI DATA32        *
imlib_image_get_data(void)1569 imlib_image_get_data(void)
1570 {
1571    ImlibImage         *im;
1572 
1573    CHECK_CONTEXT(ctx);
1574    CHECK_PARAM_POINTER_RETURN("imlib_image_get_data", "image", ctx->image,
1575                               NULL);
1576    CAST_IMAGE(im, ctx->image);
1577    if (__imlib_LoadImageData(im))
1578       return NULL;
1579    __imlib_DirtyImage(im);
1580    return im->data;
1581 }
1582 
1583 /**
1584  * @return A pointer to the image data.
1585  *
1586  * Functions the same way as imlib_image_get_data(), but returns a
1587  * pointer expecting the program to NOT write to the data returned (it
1588  * is for inspection purposes only). Writing to this data has undefined
1589  * results. The data does not need to be put back.
1590  */
1591 EAPI DATA32        *
imlib_image_get_data_for_reading_only(void)1592 imlib_image_get_data_for_reading_only(void)
1593 {
1594    ImlibImage         *im;
1595 
1596    CHECK_CONTEXT(ctx);
1597    CHECK_PARAM_POINTER_RETURN("imlib_image_get_data_for_reading_only",
1598                               "image", ctx->image, NULL);
1599    CAST_IMAGE(im, ctx->image);
1600    if (__imlib_LoadImageData(im))
1601       return NULL;
1602    return im->data;
1603 }
1604 
1605 /**
1606  * @param data The pointer to the image data.
1607  *
1608  * Puts back @p data when it was obtained by
1609  * imlib_image_get_data(). @p data must be the same pointer returned
1610  * by imlib_image_get_data(). This operated on the current context
1611  * image.
1612  */
1613 EAPI void
imlib_image_put_back_data(DATA32 * data)1614 imlib_image_put_back_data(DATA32 * data)
1615 {
1616    ImlibImage         *im;
1617 
1618    CHECK_CONTEXT(ctx);
1619    CHECK_PARAM_POINTER("imlib_image_put_back_data", "image", ctx->image);
1620    CHECK_PARAM_POINTER("imlib_image_put_back_data", "data", data);
1621    CAST_IMAGE(im, ctx->image);
1622    __imlib_DirtyImage(im);
1623    data = NULL;
1624 }
1625 
1626 /**
1627  * @return Current alpha channel flag.
1628  *
1629  * Returns 1 if the current context image has an alpha channel, or 0
1630  * if it does not (the alpha data space is still there and available -
1631  * just "unused").
1632  */
1633 EAPI char
imlib_image_has_alpha(void)1634 imlib_image_has_alpha(void)
1635 {
1636    ImlibImage         *im;
1637 
1638    CHECK_CONTEXT(ctx);
1639    CHECK_PARAM_POINTER_RETURN("imlib_image_has_alpha", "image", ctx->image, 0);
1640    CAST_IMAGE(im, ctx->image);
1641    if (IMAGE_HAS_ALPHA(im))
1642       return 1;
1643    return 0;
1644 }
1645 
1646 /**
1647  * By default Imlib2 will not check the timestamp of an image on disk
1648  * and compare it with the image in its cache - this is to minimize
1649  * disk activity when using the cache. Call this function and it will
1650  * flag the current context image as being liable to change on disk
1651  * and Imlib2 will check the timestamp of the image file on disk and
1652  * compare it with the cached image when it next needs to use this
1653  * image in the cache.
1654  */
1655 EAPI void
imlib_image_set_changes_on_disk(void)1656 imlib_image_set_changes_on_disk(void)
1657 {
1658    ImlibImage         *im;
1659 
1660    CHECK_CONTEXT(ctx);
1661    CHECK_PARAM_POINTER("imlib_image_set_never_changes_on_disk", "image",
1662                        ctx->image);
1663    CAST_IMAGE(im, ctx->image);
1664    SET_FLAG(im->flags, F_ALWAYS_CHECK_DISK);
1665 }
1666 
1667 /**
1668  * @param border The border of the image.
1669  *
1670  * Fills the Imlib_Border structure to which @p border points to with the
1671  * values of the border of the current context image. The border is the
1672  * area at the edge of the image that does not scale with the rest of
1673  * the image when resized - the borders remain constant in size. This
1674  * is useful for scaling bevels at the edge of images differently to
1675  * the image center.
1676  */
1677 EAPI void
imlib_image_get_border(Imlib_Border * border)1678 imlib_image_get_border(Imlib_Border * border)
1679 {
1680    ImlibImage         *im;
1681 
1682    CHECK_CONTEXT(ctx);
1683    CHECK_PARAM_POINTER("imlib_image_get_border", "image", ctx->image);
1684    CHECK_PARAM_POINTER("imlib_image_get_border", "border", border);
1685    CAST_IMAGE(im, ctx->image);
1686    border->left = im->border.left;
1687    border->right = im->border.right;
1688    border->top = im->border.top;
1689    border->bottom = im->border.bottom;
1690 }
1691 
1692 /**
1693  * @param border The border of the image.
1694  *
1695  * Sets the border of the current context image to the values contained
1696  * in the Imlib_Border structure @p border points to.
1697  */
1698 EAPI void
imlib_image_set_border(Imlib_Border * border)1699 imlib_image_set_border(Imlib_Border * border)
1700 {
1701    ImlibImage         *im;
1702 
1703    CHECK_CONTEXT(ctx);
1704    CHECK_PARAM_POINTER("imlib_image_set_border", "image", ctx->image);
1705    CHECK_PARAM_POINTER("imlib_image_set_border", "border", border);
1706    CAST_IMAGE(im, ctx->image);
1707    if ((im->border.left == border->left)
1708        && (im->border.right == border->right)
1709        && (im->border.top == border->top)
1710        && (im->border.bottom == border->bottom))
1711       return;
1712    im->border.left = MAX(0, border->left);
1713    im->border.right = MAX(0, border->right);
1714    im->border.top = MAX(0, border->top);
1715    im->border.bottom = MAX(0, border->bottom);
1716 #ifdef BUILD_X11
1717    __imlib_DirtyPixmapsForImage(im);
1718 #endif
1719 }
1720 
1721 /**
1722  * @param format Format of the image.
1723  *
1724  * Sets the format of the current image. This is used for when you
1725  * wish to save an image in a different format that it was loaded in,
1726  * or if the image currently has no file format associated with it.
1727  */
1728 EAPI void
imlib_image_set_format(const char * format)1729 imlib_image_set_format(const char *format)
1730 {
1731    ImlibImage         *im;
1732 
1733    CHECK_CONTEXT(ctx);
1734    CHECK_PARAM_POINTER("imlib_image_set_format", "image", ctx->image);
1735    CHECK_PARAM_POINTER("imlib_image_set_format", "format", format);
1736    CAST_IMAGE(im, ctx->image);
1737    free(im->format);
1738    im->format = (format) ? strdup(format) : NULL;
1739    if (!(im->flags & F_FORMAT_IRRELEVANT))
1740      {
1741         __imlib_DirtyImage(im);
1742      }
1743 }
1744 
1745 /**
1746  * @param irrelevant Irrelevant format flag.
1747  *
1748  * Sets if the format value of the current image is irrelevant for
1749  * caching purposes - by default it is. pass irrelevant as 1 to make it
1750  * irrelevant and 0 to make it relevant for caching.
1751  */
1752 EAPI void
imlib_image_set_irrelevant_format(char irrelevant)1753 imlib_image_set_irrelevant_format(char irrelevant)
1754 {
1755    ImlibImage         *im;
1756 
1757    CHECK_CONTEXT(ctx);
1758    CHECK_PARAM_POINTER("imlib_image_set_irrelevant_format", "image",
1759                        ctx->image);
1760    CAST_IMAGE(im, ctx->image);
1761    if (irrelevant)
1762      {
1763         SET_FLAG(im->flags, F_FORMAT_IRRELEVANT);
1764      }
1765    else
1766      {
1767         UNSET_FLAG(im->flags, F_FORMAT_IRRELEVANT);
1768      }
1769 }
1770 
1771 /**
1772  * @param irrelevant Irrelevant border flag.
1773  *
1774  * Sets if the border of the current image is irrelevant for caching
1775  * purposes. By default it is. Set irrelevant to 1 to make it
1776  * irrelevant, and 0 to make it relevant.
1777  */
1778 EAPI void
imlib_image_set_irrelevant_border(char irrelevant)1779 imlib_image_set_irrelevant_border(char irrelevant)
1780 {
1781    ImlibImage         *im;
1782 
1783    CHECK_CONTEXT(ctx);
1784    CHECK_PARAM_POINTER("imlib_image_set_irrelevant_border", "image",
1785                        ctx->image);
1786    CAST_IMAGE(im, ctx->image);
1787    if (irrelevant)
1788      {
1789         SET_FLAG(im->flags, F_BORDER_IRRELEVANT);
1790      }
1791    else
1792      {
1793         UNSET_FLAG(im->flags, F_BORDER_IRRELEVANT);
1794      }
1795 }
1796 
1797 /**
1798  * @param irrelevant Irrelevant alpha flag.
1799  *
1800  * Sets if the alpha channel status of the current image (i.e. if
1801  * there is or is not one) is important for caching purposes. By
1802  * default it is not. Set irrelevant to 1 to make it irrelevant and 0
1803  * to make it relevant.
1804  */
1805 EAPI void
imlib_image_set_irrelevant_alpha(char irrelevant)1806 imlib_image_set_irrelevant_alpha(char irrelevant)
1807 {
1808    ImlibImage         *im;
1809 
1810    CHECK_CONTEXT(ctx);
1811    CHECK_PARAM_POINTER("imlib_image_set_irrelevant_alpha", "image", ctx->image);
1812    CAST_IMAGE(im, ctx->image);
1813    if (irrelevant)
1814      {
1815         SET_FLAG(im->flags, F_ALPHA_IRRELEVANT);
1816      }
1817    else
1818      {
1819         UNSET_FLAG(im->flags, F_ALPHA_IRRELEVANT);
1820      }
1821 }
1822 
1823 /**
1824  * @return Current image format.
1825  *
1826  * Returns the current image's format. Do not free this
1827  * string. Duplicate it if you need it for later use.
1828  */
1829 EAPI char          *
imlib_image_format(void)1830 imlib_image_format(void)
1831 {
1832    ImlibImage         *im;
1833 
1834    CHECK_CONTEXT(ctx);
1835    CHECK_PARAM_POINTER_RETURN("imlib_image_format", "image", ctx->image, NULL);
1836    CAST_IMAGE(im, ctx->image);
1837    return im->format;
1838 }
1839 
1840 /**
1841  * @param has_alpha Alpha flag.
1842  *
1843  * Sets the alpha flag for the current image. Set @p has_alpha to 1 to
1844  * enable the alpha channel in the current image, or 0 to disable it.
1845  */
1846 EAPI void
imlib_image_set_has_alpha(char has_alpha)1847 imlib_image_set_has_alpha(char has_alpha)
1848 {
1849    ImlibImage         *im;
1850 
1851    CHECK_CONTEXT(ctx);
1852    CHECK_PARAM_POINTER("imlib_image_set_has_alpha", "image", ctx->image);
1853    CAST_IMAGE(im, ctx->image);
1854    if (has_alpha)
1855       SET_FLAG(im->flags, F_HAS_ALPHA);
1856    else
1857       UNSET_FLAG(im->flags, F_HAS_ALPHA);
1858 }
1859 
1860 #ifdef BUILD_X11
1861 /**
1862  * @param pixmap_return The returned pixmap.
1863  * @param mask_return The returned mask.
1864  *
1865  * Creates a pixmap of the current image (and a mask if the image has
1866  * an alpha value) and return the id's of the pixmap and mask to
1867  * @p pixmap_return and @p mask_return pixmap id's. You must free these
1868  * pixmaps using Imlib2's free function imlib_free_pixmap_and_mask().
1869  */
1870 EAPI void
imlib_render_pixmaps_for_whole_image(Pixmap * pixmap_return,Pixmap * mask_return)1871 imlib_render_pixmaps_for_whole_image(Pixmap * pixmap_return,
1872                                      Pixmap * mask_return)
1873 {
1874    ImlibImage         *im;
1875 
1876    CHECK_CONTEXT(ctx);
1877    CHECK_PARAM_POINTER("imlib_render_pixmaps_for_whole_image", "image",
1878                        ctx->image);
1879    CHECK_PARAM_POINTER("imlib_render_pixmaps_for_whole_image",
1880                        "pixmap_return", pixmap_return);
1881    CAST_IMAGE(im, ctx->image);
1882    if (__imlib_LoadImageData(im))
1883       return;
1884    __imlib_CreatePixmapsForImage(ctx->display, ctx->drawable, ctx->visual,
1885                                  ctx->depth, ctx->colormap, im, pixmap_return,
1886                                  mask_return, 0, 0, im->w, im->h, im->w,
1887                                  im->h, 0, ctx->dither, ctx->dither_mask,
1888                                  ctx->mask_alpha_threshold,
1889                                  ctx->color_modifier);
1890 }
1891 
1892 /**
1893  * @param pixmap_return The returned pixmap.
1894  * @param mask_return The returned mask.
1895  * @param width Width of the pixmap.
1896  * @param height Height of the pixmap.
1897  *
1898  * Works just like imlib_render_pixmaps_for_whole_image(), but will
1899  * scale the output result to the width @p width and height @p height
1900  * specified. Scaling
1901  * is done before depth conversion so pixels used for dithering don't
1902  * grow large.
1903  */
1904 EAPI void
imlib_render_pixmaps_for_whole_image_at_size(Pixmap * pixmap_return,Pixmap * mask_return,int width,int height)1905 imlib_render_pixmaps_for_whole_image_at_size(Pixmap * pixmap_return,
1906                                              Pixmap * mask_return, int width,
1907                                              int height)
1908 {
1909    ImlibImage         *im;
1910 
1911    CHECK_CONTEXT(ctx);
1912    CHECK_PARAM_POINTER("imlib_render_pixmaps_for_whole_image_at_size",
1913                        "image", ctx->image);
1914    CHECK_PARAM_POINTER("imlib_render_pixmaps_for_whole_image_at_size",
1915                        "pixmap_return", pixmap_return);
1916    CAST_IMAGE(im, ctx->image);
1917    if (__imlib_LoadImageData(im))
1918       return;
1919    __imlib_CreatePixmapsForImage(ctx->display, ctx->drawable, ctx->visual,
1920                                  ctx->depth, ctx->colormap, im, pixmap_return,
1921                                  mask_return, 0, 0, im->w, im->h, width,
1922                                  height, ctx->anti_alias, ctx->dither,
1923                                  ctx->dither_mask, ctx->mask_alpha_threshold,
1924                                  ctx->color_modifier);
1925 }
1926 
1927 /**
1928  * @param pixmap The pixmap.
1929  *
1930  * Frees @p pixmap (and any mask generated in association with that
1931  * pixmap). The pixmap will remain cached until the image the pixmap
1932  * was generated from is dirtied or decached, or the cache is flushed.
1933  */
1934 EAPI void
imlib_free_pixmap_and_mask(Pixmap pixmap)1935 imlib_free_pixmap_and_mask(Pixmap pixmap)
1936 {
1937    CHECK_CONTEXT(ctx);
1938    __imlib_FreePixmap(ctx->display, pixmap);
1939 }
1940 
1941 /**
1942  * @param x X coordinate of the pixel.
1943  * @param y Y coordinate of the pixel.
1944  *
1945  * Renders the current image onto the current drawable at the (@p x, @p y)
1946  * pixel location specified without scaling.
1947  */
1948 EAPI void
imlib_render_image_on_drawable(int x,int y)1949 imlib_render_image_on_drawable(int x, int y)
1950 {
1951    ImlibImage         *im;
1952 
1953    CHECK_CONTEXT(ctx);
1954    CHECK_PARAM_POINTER("imlib_render_image_on_drawable", "image", ctx->image);
1955    CAST_IMAGE(im, ctx->image);
1956    if (__imlib_LoadImageData(im))
1957       return;
1958    __imlib_RenderImage(ctx->display, im, ctx->drawable, ctx->mask,
1959                        ctx->visual, ctx->colormap, ctx->depth, 0, 0, im->w,
1960                        im->h, x, y, im->w, im->h, 0, ctx->dither, ctx->blend,
1961                        ctx->dither_mask, ctx->mask_alpha_threshold,
1962                        ctx->color_modifier, ctx->operation);
1963 }
1964 
1965 /**
1966  * @param x X coordinate of the pixel.
1967  * @param y Y coordinate of the pixel.
1968  * @param width Width of the rendered image.
1969  * @param height Height of the rendered image.
1970  *
1971  * Renders the current image onto the current drawable at the (@p x, @p y)
1972  * location specified AND scale the image to the width @p width and height
1973  * @p height.
1974  */
1975 EAPI void
imlib_render_image_on_drawable_at_size(int x,int y,int width,int height)1976 imlib_render_image_on_drawable_at_size(int x, int y, int width, int height)
1977 {
1978    ImlibImage         *im;
1979 
1980    CHECK_CONTEXT(ctx);
1981    CHECK_PARAM_POINTER("imlib_render_image_on_drawable_at_size", "image",
1982                        ctx->image);
1983    CAST_IMAGE(im, ctx->image);
1984    if (__imlib_LoadImageData(im))
1985       return;
1986    __imlib_RenderImage(ctx->display, im, ctx->drawable, ctx->mask,
1987                        ctx->visual, ctx->colormap, ctx->depth, 0, 0, im->w,
1988                        im->h, x, y, width, height, ctx->anti_alias,
1989                        ctx->dither, ctx->blend, ctx->dither_mask,
1990                        ctx->mask_alpha_threshold, ctx->color_modifier,
1991                        ctx->operation);
1992 }
1993 
1994 /**
1995  * @param source_x X coordinate of the source image.
1996  * @param source_y Y coordinate of the source image.
1997  * @param source_width Width of the source image.
1998  * @param source_height Height of the source image.
1999  * @param x X coordinate of the destination image.
2000  * @param y Y coordinate of the destination image.
2001  * @param width Width of the destination image.
2002  * @param height Height of the destination image.
2003  *
2004  * Renders the source (@p source_x, @p source_y, @p source_width, @p source_height) pixel
2005  * rectangle from the
2006  * current image onto the current drawable at the (@p x, @p y) location scaled
2007  * to the width @p width and height @p height.
2008  */
2009 EAPI void
imlib_render_image_part_on_drawable_at_size(int source_x,int source_y,int source_width,int source_height,int x,int y,int width,int height)2010 imlib_render_image_part_on_drawable_at_size(int source_x, int source_y,
2011                                             int source_width,
2012                                             int source_height, int x, int y,
2013                                             int width, int height)
2014 {
2015    ImlibImage         *im;
2016 
2017    CHECK_CONTEXT(ctx);
2018    CHECK_PARAM_POINTER("imlib_render_image_part_on_drawable_at_size", "image",
2019                        ctx->image);
2020    CAST_IMAGE(im, ctx->image);
2021    if (__imlib_LoadImageData(im))
2022       return;
2023    __imlib_RenderImage(ctx->display, im, ctx->drawable, 0, ctx->visual,
2024                        ctx->colormap, ctx->depth, source_x, source_y,
2025                        source_width, source_height, x, y, width, height,
2026                        ctx->anti_alias, ctx->dither, ctx->blend, 0,
2027                        0, ctx->color_modifier, ctx->operation);
2028 }
2029 
2030 EAPI                DATA32
imlib_render_get_pixel_color(void)2031 imlib_render_get_pixel_color(void)
2032 {
2033    CHECK_CONTEXT(ctx);
2034    return __imlib_RenderGetPixel(ctx->display, ctx->drawable, ctx->visual,
2035                                  ctx->colormap, ctx->depth,
2036                                  (DATA8) ctx->color.red,
2037                                  (DATA8) ctx->color.green,
2038                                  (DATA8) ctx->color.blue);
2039 }
2040 
2041 #endif
2042 
2043 /**
2044  * @param source_image The source image.
2045  * @param merge_alpha Alpha flag.
2046  * @param source_x X coordinate of the source image.
2047  * @param source_y Y coordinate of the source image.
2048  * @param source_width Width of the source image.
2049  * @param source_height Height of the source image.
2050  * @param destination_x X coordinate of the destination image.
2051  * @param destination_y Y coordinate of the destination image.
2052  * @param destination_width Width of the destination image.
2053  * @param destination_height Height of the destination image.
2054  *
2055  * Blends the source rectangle (@p source_x, @p source_y, @p
2056  * source_width, @p source_height) from
2057  * @p source_image onto the current image at the destination (@p
2058  * destination_x, @p destination_y) location
2059  * scaled to the width @p destination_width and height @p
2060  * destination_height. If @p merge_alpha is set to 1
2061  * it will also modify the destination image alpha channel, otherwise
2062  * the destination alpha channel is left untouched.
2063  */
2064 EAPI void
imlib_blend_image_onto_image(Imlib_Image source_image,char merge_alpha,int source_x,int source_y,int source_width,int source_height,int destination_x,int destination_y,int destination_width,int destination_height)2065 imlib_blend_image_onto_image(Imlib_Image source_image, char merge_alpha,
2066                              int source_x, int source_y, int source_width,
2067                              int source_height, int destination_x,
2068                              int destination_y, int destination_width,
2069                              int destination_height)
2070 {
2071    ImlibImage         *im_src, *im_dst;
2072    int                 aa;
2073 
2074    CHECK_CONTEXT(ctx);
2075    CHECK_PARAM_POINTER("imlib_blend_image_onto_image", "source_image",
2076                        source_image);
2077    CHECK_PARAM_POINTER("imlib_blend_image_onto_image", "image", ctx->image);
2078    CAST_IMAGE(im_src, source_image);
2079    CAST_IMAGE(im_dst, ctx->image);
2080    if (__imlib_LoadImageData(im_src))
2081       return;
2082    if (__imlib_LoadImageData(im_dst))
2083       return;
2084    __imlib_DirtyImage(im_dst);
2085    /* FIXME: hack to get around infinite loops for scaling down too far */
2086    aa = ctx->anti_alias;
2087    if ((abs(destination_width) < (source_width >> 7))
2088        || (abs(destination_height) < (source_height >> 7)))
2089       aa = 0;
2090    __imlib_BlendImageToImage(im_src, im_dst, aa, ctx->blend,
2091                              merge_alpha, source_x, source_y, source_width,
2092                              source_height, destination_x, destination_y,
2093                              destination_width, destination_height,
2094                              ctx->color_modifier, ctx->operation,
2095                              ctx->cliprect.x, ctx->cliprect.y,
2096                              ctx->cliprect.w, ctx->cliprect.h);
2097 }
2098 
2099 /**
2100  * @param width The width of the image.
2101  * @param height The height of the image.
2102  * @return A new blank image.
2103  *
2104  * Creates a new blank image of size @p width and @p height. The contents of
2105  * this image at creation time are undefined (they could be garbage
2106  * memory). You are free to do whatever you like with this image. It
2107  * is not cached. On success an image handle is returned - on failure
2108  * NULL is returned.
2109  **/
2110 EAPI                Imlib_Image
imlib_create_image(int width,int height)2111 imlib_create_image(int width, int height)
2112 {
2113    DATA32             *data;
2114 
2115    CHECK_CONTEXT(ctx);
2116    if (!IMAGE_DIMENSIONS_OK(width, height))
2117       return NULL;
2118    data = malloc(width * height * sizeof(DATA32));
2119    if (data)
2120       return (Imlib_Image) __imlib_CreateImage(width, height, data);
2121    return NULL;
2122 }
2123 
2124 /**
2125  * @param width The width of the image.
2126  * @param height The height of the image.
2127  * @param data The data.
2128  * @return A valid image, otherwise NULL.
2129  *
2130  * Creates an image from the image data specified with the width @p width and
2131  * the height @p height specified. The image data @p data must be in the same format as
2132  * imlib_image_get_data() would return. You are responsible for
2133  * freeing this image data once the image is freed - Imlib2 will not
2134  * do that for you. This is useful for when you already have static
2135  * buffers of the same format Imlib2 uses (many video grabbing devices
2136  * use such a format) and wish to use Imlib2 to render the results
2137  * onto another image, or X drawable. You should free the image when
2138  * you are done with it. Imlib2 returns a valid image handle on
2139  * success or NULL on failure
2140  *
2141  **/
2142 EAPI                Imlib_Image
imlib_create_image_using_data(int width,int height,DATA32 * data)2143 imlib_create_image_using_data(int width, int height, DATA32 * data)
2144 {
2145    ImlibImage         *im;
2146 
2147    CHECK_CONTEXT(ctx);
2148    CHECK_PARAM_POINTER_RETURN("imlib_create_image_using_data", "data", data,
2149                               NULL);
2150    if (!IMAGE_DIMENSIONS_OK(width, height))
2151       return NULL;
2152    im = __imlib_CreateImage(width, height, data);
2153    if (im)
2154       SET_FLAG(im->flags, F_DONT_FREE_DATA);
2155    return (Imlib_Image) im;
2156 }
2157 
2158 /**
2159  * @param width The width of the image.
2160  * @param height The height of the image.
2161  * @param data The data.
2162  * @param func The memory management function.
2163  * @return A valid image, otherwise NULL.
2164  *
2165  * Creates an image from the image data specified with the width @p width and
2166  * the height @p height specified. The image data @p data must be in the same format as
2167  * imlib_image_get_data() would return. The memory management function @p func is
2168  * responsible for freeing this image data once the image is freed. Imlib2 returns a
2169  * valid image handle on success or NULL on failure.
2170  *
2171  **/
2172 EAPI                Imlib_Image
imlib_create_image_using_data_and_memory_function(int width,int height,DATA32 * data,Imlib_Image_Data_Memory_Function func)2173    imlib_create_image_using_data_and_memory_function
2174    (int width, int height, DATA32 * data, Imlib_Image_Data_Memory_Function func)
2175 {
2176    ImlibImage         *im;
2177 
2178    CHECK_CONTEXT(ctx);
2179    CHECK_PARAM_POINTER_RETURN
2180       ("imlib_create_image_using_data_and_memory_function", "data", data, NULL);
2181    if (!IMAGE_DIMENSIONS_OK(width, height))
2182       return NULL;
2183    im = __imlib_CreateImage(width, height, data);
2184    if (im)
2185       im->data_memory_func = func;
2186 
2187    return (Imlib_Image) im;
2188 }
2189 
2190 /**
2191  * @param width The width of the image.
2192  * @param height The height of the image.
2193  * @param data The data.
2194  * @return A valid image, otherwise NULL.
2195  *
2196  * Works the same way as imlib_create_image_using_data() but Imlib2
2197  * copies the image data to the image structure. You may now do
2198  * whatever you wish with the original data as it will not be needed
2199  * anymore. Imlib2 returns a valid image handle on success or NULL on
2200  * failure.
2201  *
2202  **/
2203 EAPI                Imlib_Image
imlib_create_image_using_copied_data(int width,int height,DATA32 * data)2204 imlib_create_image_using_copied_data(int width, int height, DATA32 * data)
2205 {
2206    ImlibImage         *im;
2207 
2208    CHECK_CONTEXT(ctx);
2209    CHECK_PARAM_POINTER_RETURN("imlib_create_image_using_copied_data", "data",
2210                               data, NULL);
2211    if (!IMAGE_DIMENSIONS_OK(width, height))
2212       return NULL;
2213    im = __imlib_CreateImage(width, height, NULL);
2214    if (!im)
2215       return NULL;
2216    im->data = malloc(width * height * sizeof(DATA32));
2217    if (data)
2218      {
2219         memcpy(im->data, data, width * height * sizeof(DATA32));
2220         return (Imlib_Image) im;
2221      }
2222    else
2223       __imlib_FreeImage(im);
2224    return NULL;
2225 }
2226 
2227 #ifdef BUILD_X11
2228 /**
2229  * @param mask A mask.
2230  * @param x The top left x coordinate of the rectangle.
2231  * @param y The top left y coordinate of the rectangle.
2232  * @param width The width of the rectangle.
2233  * @param height The height of the rectangle.
2234  * @param need_to_grab_x Grab flag.
2235  * @return a valid image, otherwise NULL.
2236  *
2237  * Return an image (using the mask @p mask to determine the alpha channel)
2238  * from the current drawable.
2239  * If @p mask is 0 it will not create a useful alpha channel in the image.
2240  * If @p mask is 1 the mask will be set to the shape mask of the drawable.
2241  * It will create an image from the
2242  * (@p x, @p y, @p width , @p height) rectangle in the drawable. If @p
2243  * need_to_grab_x is 1 it will also grab the X Server to avoid possible race
2244  * conditions in grabbing. If you have not already grabbed the server
2245  * you MUST set this to 1. Imlib2 returns a valid image handle on
2246  * success or NULL on failure.
2247  *
2248  **/
2249 EAPI                Imlib_Image
imlib_create_image_from_drawable(Pixmap mask,int x,int y,int width,int height,char need_to_grab_x)2250 imlib_create_image_from_drawable(Pixmap mask, int x, int y, int width,
2251                                  int height, char need_to_grab_x)
2252 {
2253    ImlibImage         *im;
2254    char                domask = 0;
2255 
2256    CHECK_CONTEXT(ctx);
2257    if (!IMAGE_DIMENSIONS_OK(width, height))
2258       return NULL;
2259    if (mask)
2260      {
2261         domask = 1;
2262         if (mask == (Pixmap) 1)
2263            mask = None;
2264      }
2265    im = __imlib_CreateImage(width, height, NULL);
2266    im->data = malloc(width * height * sizeof(DATA32));
2267    if (__imlib_GrabDrawableToRGBA(im->data, 0, 0, width, height, ctx->display,
2268                                   ctx->drawable, mask, ctx->visual,
2269                                   ctx->colormap, ctx->depth, x, y, width,
2270                                   height, &domask, need_to_grab_x))
2271      {
2272         if (domask)
2273            SET_FLAG(im->flags, F_HAS_ALPHA);
2274         else
2275            UNSET_FLAG(im->flags, F_HAS_ALPHA);
2276      }
2277    else
2278      {
2279         __imlib_FreeImage(im);
2280         im = NULL;
2281      }
2282 
2283    return (Imlib_Image) im;
2284 }
2285 
2286 /**
2287  * @param image An image.
2288  * @param mask A mask.
2289  * @param x The top left x coordinate of the rectangle.
2290  * @param y The top left y coordinate of the rectangle.
2291  * @param width The width of the rectangle.
2292  * @param height The height of the rectangle.
2293  * @param need_to_grab_x Grab flag.
2294  * @return a valid image, otherwise NULL.
2295  *
2296  *
2297  **/
2298 EAPI                Imlib_Image
imlib_create_image_from_ximage(XImage * image,XImage * mask,int x,int y,int width,int height,char need_to_grab_x)2299 imlib_create_image_from_ximage(XImage * image, XImage * mask, int x, int y,
2300                                int width, int height, char need_to_grab_x)
2301 {
2302    ImlibImage         *im;
2303 
2304    CHECK_CONTEXT(ctx);
2305    if (!IMAGE_DIMENSIONS_OK(width, height))
2306       return NULL;
2307    im = __imlib_CreateImage(width, height, NULL);
2308    im->data = malloc(width * height * sizeof(DATA32));
2309    __imlib_GrabXImageToRGBA(im->data, 0, 0, width, height,
2310                             ctx->display, image, mask, ctx->visual,
2311                             ctx->depth, x, y, width, height, need_to_grab_x);
2312    return (Imlib_Image) im;
2313 }
2314 
2315 /**
2316  * @param mask A mask.
2317  * @param source_x The top left x coordinate of the rectangle.
2318  * @param source_y The top left y coordinate of the rectangle.
2319  * @param source_width The width of the rectangle.
2320  * @param source_height The height of the rectangle.
2321  * @param destination_width The width of the returned image.
2322  * @param destination_height The height of the returned image.
2323  * @param need_to_grab_x Grab flag.
2324  * @param get_mask_from_shape A char.
2325  * @return A valid image, otherwise NULL.
2326  *
2327  * Creates an image from the current drawable (optionally using the
2328  * @p mask pixmap specified to determine alpha transparency) and scale
2329  * the grabbed data first before converting to an actual image (to
2330  * minimize reads from the frame buffer which can be slow). The source
2331  * (@p source_x, @p source_y, @p source_width, @p source_height) rectangle will be grabbed, scaled to the
2332  * destination @p destination_width and @p destination_height, then converted to an image. If
2333  * @p need_to_grab_x is set to 1, X is grabbed (set this to 1 unless you
2334  * have already grabbed the server) and if @p get_mask_from_shape and the
2335  * current drawable is a window its shape is used for determining the
2336  * alpha channel. If successful this function will return a valid
2337  * image handle, otherwise NULL is returned.
2338  *
2339  **/
2340 EAPI                Imlib_Image
imlib_create_scaled_image_from_drawable(Pixmap mask,int source_x,int source_y,int source_width,int source_height,int destination_width,int destination_height,char need_to_grab_x,char get_mask_from_shape)2341 imlib_create_scaled_image_from_drawable(Pixmap mask, int source_x,
2342                                         int source_y, int source_width,
2343                                         int source_height,
2344                                         int destination_width,
2345                                         int destination_height,
2346                                         char need_to_grab_x,
2347                                         char get_mask_from_shape)
2348 {
2349    ImlibImage         *im;
2350    char                domask = 0, tmpmask = 0;
2351    int                 x, xx;
2352    XGCValues           gcv;
2353    GC                  gc = 0, mgc = 0;
2354    Pixmap              p, m;
2355 
2356    CHECK_CONTEXT(ctx);
2357    if (!IMAGE_DIMENSIONS_OK(source_width, source_height))
2358       return NULL;
2359    if (!IMAGE_DIMENSIONS_OK(destination_width, destination_height))
2360       return NULL;
2361    if ((mask) || (get_mask_from_shape))
2362       domask = 1;
2363 
2364    p = XCreatePixmap(ctx->display, ctx->drawable, destination_width,
2365                      source_height, ctx->depth);
2366 
2367    gcv.foreground = 0;
2368    gcv.subwindow_mode = IncludeInferiors;
2369    gcv.graphics_exposures = False;
2370    gc = XCreateGC(ctx->display, ctx->drawable,
2371                   GCSubwindowMode | GCGraphicsExposures, &gcv);
2372 
2373    if ((domask) && (!mask))
2374      {
2375         XRectangle         *rect;
2376         int                 rect_num, rect_ord;
2377 
2378         rect = XShapeGetRectangles(ctx->display, ctx->drawable, ShapeBounding,
2379                                    &rect_num, &rect_ord);
2380 
2381         if (rect && (rect_num == 1 &&
2382                      rect[0].x == 0 && rect[0].y == 0 &&
2383                      rect[0].width == source_width &&
2384                      rect[0].height == source_height))
2385           {
2386              domask = 0;
2387              XFree(rect);
2388           }
2389         else
2390           {
2391              tmpmask = 1;
2392              mask =
2393                 XCreatePixmap(ctx->display, ctx->drawable, source_width,
2394                               source_height, 1);
2395              mgc = XCreateGC(ctx->display, mask,
2396                              GCForeground | GCGraphicsExposures, &gcv);
2397              XFillRectangle(ctx->display, mask, mgc, 0, 0, source_width,
2398                             source_height);
2399              if (rect)
2400                {
2401                   XSetForeground(ctx->display, mgc, 1);
2402                   for (x = 0; x < rect_num; x++)
2403                      XFillRectangle(ctx->display, mask, mgc, rect[x].x,
2404                                     rect[x].y, rect[x].width, rect[x].height);
2405                   XFree(rect);
2406                }
2407           }
2408      }
2409 
2410    if ((destination_width == source_width) &&
2411        (destination_height == source_height))
2412      {
2413         XCopyArea(ctx->display, ctx->drawable, p, gc, source_x, source_y,
2414                   source_width, source_height, 0, 0);
2415         m = mask;
2416      }
2417    else
2418      {
2419         if (domask)
2420           {
2421              m = XCreatePixmap(ctx->display, ctx->drawable, destination_width,
2422                                source_height, 1);
2423              if (!mgc)
2424                 mgc = XCreateGC(ctx->display, m,
2425                                 GCForeground | GCGraphicsExposures, &gcv);
2426           }
2427         else
2428            m = None;
2429 
2430         for (x = 0; x < destination_width; x++)
2431           {
2432              xx = (source_width * x) / destination_width;
2433              XCopyArea(ctx->display, ctx->drawable, p, gc,
2434                        source_x + xx, source_y, 1, source_height, x, 0);
2435              if (m != None)
2436                 XCopyArea(ctx->display, mask, m, mgc,
2437                           xx, 0, 1, source_height, x, 0);
2438           }
2439         for (x = 0; x < destination_height; x++)
2440           {
2441              xx = (source_height * x) / destination_height;
2442              XCopyArea(ctx->display, p, p, gc,
2443                        0, xx, destination_width, 1, 0, x);
2444              if (m != None)
2445                 XCopyArea(ctx->display, m, m, mgc,
2446                           0, xx, destination_width, 1, 0, x);
2447           }
2448      }
2449 
2450    im = __imlib_CreateImage(destination_width, destination_height, NULL);
2451    im->data = malloc(destination_width * destination_height * sizeof(DATA32));
2452    __imlib_GrabDrawableToRGBA(im->data, 0, 0, destination_width,
2453                               source_height, ctx->display, p, m,
2454                               ctx->visual, ctx->colormap, ctx->depth, 0, 0,
2455                               destination_width, destination_height, &domask,
2456                               need_to_grab_x);
2457    if (domask)
2458       SET_FLAG(im->flags, F_HAS_ALPHA);
2459    else
2460       UNSET_FLAG(im->flags, F_HAS_ALPHA);
2461 
2462    if (mgc)
2463       XFreeGC(ctx->display, mgc);
2464    if (m != None && m != mask)
2465       XFreePixmap(ctx->display, m);
2466    if (tmpmask)
2467       XFreePixmap(ctx->display, mask);
2468    XFreeGC(ctx->display, gc);
2469    XFreePixmap(ctx->display, p);
2470 
2471    return (Imlib_Image) im;
2472 }
2473 
2474 /**
2475  * @param mask A mask.
2476  * @param x The top left x coordinate of the rectangle.
2477  * @param y The top left y coordinate of the rectangle.
2478  * @param width The width of the rectangle.
2479  * @param height The height of the rectangle.
2480  * @param destination_x The x coordinate of the new location.
2481  * @param destination_y The x coordinate of the new location.
2482  * @param need_to_grab_x Grab flag.
2483  * @return A char.
2484  *
2485  * Grabs a section of the current drawable (optionally using the pixmap @p mask
2486  * provided as a corresponding mask for that drawable - if @p mask is 0
2487  * this is not used).
2488  * If @p mask is 1 the mask will be set to the shape mask of the drawable.
2489  * It grabs the (@p x, @p y, @p width, @p height) rectangle and
2490  * places it at the destination (@p destination_x, @p destination_y) location in the current image. If
2491  * @p need_to_grab_x is 1 it will grab and ungrab the server whilst doing
2492  * this - you need to do this if you have not already grabbed the
2493  * server.
2494  *
2495  **/
2496 EAPI char
imlib_copy_drawable_to_image(Pixmap mask,int x,int y,int width,int height,int destination_x,int destination_y,char need_to_grab_x)2497 imlib_copy_drawable_to_image(Pixmap mask, int x, int y, int width, int height,
2498                              int destination_x, int destination_y,
2499                              char need_to_grab_x)
2500 {
2501    ImlibImage         *im;
2502    char                domask = 0;
2503    int                 pre_adj;
2504 
2505    CHECK_CONTEXT(ctx);
2506    CHECK_PARAM_POINTER_RETURN("imlib_copy_drawable_to_image", "image",
2507                               ctx->image, 0);
2508    if (mask)
2509      {
2510         domask = 1;
2511         if (mask == (Pixmap) 1)
2512            mask = None;
2513      }
2514    CAST_IMAGE(im, ctx->image);
2515 
2516    if (__imlib_LoadImageData(im))
2517       return 0;
2518 
2519    pre_adj = 0;
2520    if (x < 0)
2521      {
2522         width += x;
2523         pre_adj = x;
2524         x = 0;
2525      }
2526    if (width < 0)
2527       width = 0;
2528    if (destination_x < 0)
2529      {
2530         width += destination_x;
2531         x -= destination_x - pre_adj;
2532         destination_x = 0;
2533      }
2534    if ((destination_x + width) >= im->w)
2535       width = im->w - destination_x;
2536 
2537    pre_adj = 0;
2538    if (y < 0)
2539      {
2540         height += y;
2541         pre_adj = y;
2542         y = 0;
2543      }
2544    if (height < 0)
2545       height = 0;
2546    if (destination_y < 0)
2547      {
2548         height += destination_y;
2549         y -= destination_y - pre_adj;
2550         destination_y = 0;
2551      }
2552    if ((destination_y + height) >= im->h)
2553       height = im->h - destination_y;
2554 
2555    if ((width <= 0) || (height <= 0))
2556       return 0;
2557    __imlib_DirtyImage(im);
2558    return __imlib_GrabDrawableToRGBA(im->data, destination_x, destination_y,
2559                                      im->w, im->h, ctx->display,
2560                                      ctx->drawable, mask, ctx->visual,
2561                                      ctx->colormap, ctx->depth, x, y, width,
2562                                      height, &domask, need_to_grab_x);
2563 }
2564 #endif
2565 
2566 /**
2567  * @return A valid image, otherwise NULL.
2568  *
2569  * Creates an exact duplicate of the current image and returns a valid
2570  * image handle on success, or NULL on failure.
2571  *
2572  **/
2573 EAPI                Imlib_Image
imlib_clone_image(void)2574 imlib_clone_image(void)
2575 {
2576    ImlibImage         *im, *im_old;
2577 
2578    CHECK_CONTEXT(ctx);
2579    CHECK_PARAM_POINTER_RETURN("imlib_clone_image", "image", ctx->image, NULL);
2580    CAST_IMAGE(im_old, ctx->image);
2581    if (__imlib_LoadImageData(im_old))
2582       return NULL;
2583    /* Note: below check should've ensured by original image allocation,
2584     * but better safe than sorry. */
2585    if (!IMAGE_DIMENSIONS_OK(im_old->w, im_old->h))
2586       return NULL;
2587    im = __imlib_CreateImage(im_old->w, im_old->h, NULL);
2588    if (!(im))
2589       return NULL;
2590    im->data = malloc(im->w * im->h * sizeof(DATA32));
2591    if (!(im->data))
2592      {
2593         __imlib_FreeImage(im);
2594         return NULL;
2595      }
2596    memcpy(im->data, im_old->data, im->w * im->h * sizeof(DATA32));
2597    im->flags = im_old->flags;
2598    SET_FLAG(im->flags, F_UNCACHEABLE);
2599    im->moddate = im_old->moddate;
2600    im->border = im_old->border;
2601    im->loader = im_old->loader;
2602    if (im_old->format)
2603       im->format = strdup(im_old->format);
2604    if (im_old->file)
2605       im->file = strdup(im_old->file);
2606    return (Imlib_Image) im;
2607 }
2608 
2609 /**
2610  * @param x The top left x coordinate of the rectangle.
2611  * @param y The top left y coordinate of the rectangle.
2612  * @param width The width of the rectangle.
2613  * @param height The height of the rectangle.
2614  * @return A valid image, otherwise NULL.
2615  *
2616  * Creates a duplicate of a (@p x, @p y, @p width, @p height) rectangle in the
2617  * current image and returns a valid image handle on success, or NULL
2618  * on failure.
2619  *
2620  **/
2621 EAPI                Imlib_Image
imlib_create_cropped_image(int x,int y,int width,int height)2622 imlib_create_cropped_image(int x, int y, int width, int height)
2623 {
2624    ImlibImage         *im, *im_old;
2625 
2626    CHECK_CONTEXT(ctx);
2627    CHECK_PARAM_POINTER_RETURN("imlib_create_cropped_image", "image",
2628                               ctx->image, NULL);
2629    if (!IMAGE_DIMENSIONS_OK(abs(width), abs(height)))
2630       return NULL;
2631    CAST_IMAGE(im_old, ctx->image);
2632    if (__imlib_LoadImageData(im_old))
2633       return NULL;
2634    im = __imlib_CreateImage(abs(width), abs(height), NULL);
2635    im->data = malloc(abs(width * height) * sizeof(DATA32));
2636    if (!(im->data))
2637      {
2638         __imlib_FreeImage(im);
2639         return NULL;
2640      }
2641    if (IMAGE_HAS_ALPHA(im_old))
2642      {
2643         SET_FLAG(im->flags, F_HAS_ALPHA);
2644         __imlib_BlendImageToImage(im_old, im, 0, 0, 1, x, y, abs(width),
2645                                   abs(height), 0, 0, width, height, NULL,
2646                                   (ImlibOp) IMLIB_OP_COPY,
2647                                   ctx->cliprect.x, ctx->cliprect.y,
2648                                   ctx->cliprect.w, ctx->cliprect.h);
2649      }
2650    else
2651      {
2652         __imlib_BlendImageToImage(im_old, im, 0, 0, 0, x, y, abs(width),
2653                                   abs(height), 0, 0, width, height, NULL,
2654                                   (ImlibOp) IMLIB_OP_COPY,
2655                                   ctx->cliprect.x, ctx->cliprect.y,
2656                                   ctx->cliprect.w, ctx->cliprect.h);
2657      }
2658    return (Imlib_Image) im;
2659 }
2660 
2661 /**
2662  * @param source_x The top left x coordinate of the source rectangle.
2663  * @param source_y The top left y coordinate of the source rectangle.
2664  * @param source_width The width of the source rectangle.
2665  * @param source_height The height of the source rectangle.
2666  * @param destination_width The width of the destination image.
2667  * @param destination_height The height of the destination image.
2668  * @return A valid image, otherwise NULL.
2669  *
2670  * Works the same as imlib_create_cropped_image() but will scale the
2671  * new image to the new destination @p destination_width and
2672  * @p destination_height whilst cropping.
2673  *
2674  **/
2675 EAPI                Imlib_Image
imlib_create_cropped_scaled_image(int source_x,int source_y,int source_width,int source_height,int destination_width,int destination_height)2676 imlib_create_cropped_scaled_image(int source_x, int source_y,
2677                                   int source_width, int source_height,
2678                                   int destination_width, int destination_height)
2679 {
2680    ImlibImage         *im, *im_old;
2681 
2682    CHECK_CONTEXT(ctx);
2683    CHECK_PARAM_POINTER_RETURN("imlib_create_cropped_scaled_image", "image",
2684                               ctx->image, NULL);
2685    if (!IMAGE_DIMENSIONS_OK(abs(destination_width), abs(destination_height)))
2686       return NULL;
2687    CAST_IMAGE(im_old, ctx->image);
2688    if (__imlib_LoadImageData(im_old))
2689       return NULL;
2690    im = __imlib_CreateImage(abs(destination_width), abs(destination_height),
2691                             NULL);
2692    im->data =
2693       malloc(abs(destination_width * destination_height) * sizeof(DATA32));
2694    if (!(im->data))
2695      {
2696         __imlib_FreeImage(im);
2697         return NULL;
2698      }
2699    if (IMAGE_HAS_ALPHA(im_old))
2700      {
2701         SET_FLAG(im->flags, F_HAS_ALPHA);
2702         __imlib_BlendImageToImage(im_old, im, ctx->anti_alias, 0, 1, source_x,
2703                                   source_y, source_width, source_height, 0, 0,
2704                                   destination_width, destination_height, NULL,
2705                                   (ImlibOp) IMLIB_OP_COPY,
2706                                   ctx->cliprect.x, ctx->cliprect.y,
2707                                   ctx->cliprect.w, ctx->cliprect.h);
2708      }
2709    else
2710      {
2711         __imlib_BlendImageToImage(im_old, im, ctx->anti_alias, 0, 0, source_x,
2712                                   source_y, source_width, source_height, 0, 0,
2713                                   destination_width, destination_height, NULL,
2714                                   (ImlibOp) IMLIB_OP_COPY,
2715                                   ctx->cliprect.x, ctx->cliprect.y,
2716                                   ctx->cliprect.w, ctx->cliprect.h);
2717      }
2718    return (Imlib_Image) im;
2719 }
2720 
2721 /**
2722  * @param updates An updates list.
2723  * @return Duplicate of @p updates.
2724  *
2725  * Creates a duplicate of the updates list passed into the function.
2726  **/
2727 EAPI                Imlib_Updates
imlib_updates_clone(Imlib_Updates updates)2728 imlib_updates_clone(Imlib_Updates updates)
2729 {
2730    ImlibUpdate        *u;
2731 
2732    CHECK_CONTEXT(ctx);
2733    u = (ImlibUpdate *) updates;
2734    return (Imlib_Updates) __imlib_DupUpdates(u);
2735 }
2736 
2737 /**
2738  * @param updates An updates list.
2739  * @param x The top left x coordinate of the rectangle.
2740  * @param y The top left y coordinate of the rectangle.
2741  * @param w The width of the rectangle.
2742  * @param h The height of the rectangle.
2743  * @return The updates handle.
2744  *
2745  * Appends an update rectangle to the updates list passed in (if the
2746  * updates is NULL it will create a new updates list) and returns a
2747  * handle to the modified updates list (the handle may be modified so
2748  * only use the new updates handle returned).
2749  **/
2750 EAPI                Imlib_Updates
imlib_update_append_rect(Imlib_Updates updates,int x,int y,int w,int h)2751 imlib_update_append_rect(Imlib_Updates updates, int x, int y, int w, int h)
2752 {
2753    ImlibUpdate        *u;
2754 
2755    CHECK_CONTEXT(ctx);
2756    u = (ImlibUpdate *) updates;
2757    return (Imlib_Updates) __imlib_AddUpdate(u, x, y, w, h);
2758 }
2759 
2760 /**
2761  * @param updates An updates list.
2762  * @param w The width of the rectangle.
2763  * @param h The height of the rectangle.
2764  * @return The updates handle.
2765  *
2766  * Takes an updates list, and modifies it by merging overlapped
2767  * rectangles and lots of tiny rectangles into larger rectangles to
2768  * minimize the number of rectangles in the list for optimized
2769  * redrawing. The new updates handle is now valid and the old one
2770  * passed in is not.
2771  **/
2772 EAPI                Imlib_Updates
imlib_updates_merge(Imlib_Updates updates,int w,int h)2773 imlib_updates_merge(Imlib_Updates updates, int w, int h)
2774 {
2775    ImlibUpdate        *u;
2776 
2777    CHECK_CONTEXT(ctx);
2778    u = (ImlibUpdate *) updates;
2779    return (Imlib_Updates) __imlib_MergeUpdate(u, w, h, 0);
2780 }
2781 
2782 /**
2783  * @param updates An updates list.
2784  * @param w The width of the rectangle.
2785  * @param h The height of the rectangle.
2786  * @return The updates handle.
2787  *
2788  * Works almost exactly as imlib_updates_merge() but is more lenient
2789  * on the spacing between update rectangles - if they are very close it
2790  * amalgamates 2 smaller rectangles into 1 larger one.
2791  **/
2792 EAPI                Imlib_Updates
imlib_updates_merge_for_rendering(Imlib_Updates updates,int w,int h)2793 imlib_updates_merge_for_rendering(Imlib_Updates updates, int w, int h)
2794 {
2795    ImlibUpdate        *u;
2796 
2797    CHECK_CONTEXT(ctx);
2798    u = (ImlibUpdate *) updates;
2799    return (Imlib_Updates) __imlib_MergeUpdate(u, w, h, 3);
2800 }
2801 
2802 /**
2803  * @param updates An updates list.
2804  *
2805  * Frees an updates list.
2806  **/
2807 EAPI void
imlib_updates_free(Imlib_Updates updates)2808 imlib_updates_free(Imlib_Updates updates)
2809 {
2810    ImlibUpdate        *u;
2811 
2812    CHECK_CONTEXT(ctx);
2813    u = (ImlibUpdate *) updates;
2814    __imlib_FreeUpdates(u);
2815 }
2816 
2817 /**
2818  * @param updates An updates list.
2819  * @return The next updates.
2820  *
2821  * Gets the next update in the updates list relative to the one passed
2822  * in.
2823  **/
2824 EAPI                Imlib_Updates
imlib_updates_get_next(Imlib_Updates updates)2825 imlib_updates_get_next(Imlib_Updates updates)
2826 {
2827    ImlibUpdate        *u;
2828 
2829    CHECK_CONTEXT(ctx);
2830    u = (ImlibUpdate *) updates;
2831    return (Imlib_Updates) (u->next);
2832 }
2833 
2834 /**
2835  * @param updates An updates list.
2836  * @param x_return The top left x coordinate of the update.
2837  * @param y_return The top left y coordinate of the update.
2838  * @param width_return The width of the update.
2839  * @param height_return The height of the update.
2840  *
2841  * Returns the coordinates of an update.
2842  **/
2843 EAPI void
imlib_updates_get_coordinates(Imlib_Updates updates,int * x_return,int * y_return,int * width_return,int * height_return)2844 imlib_updates_get_coordinates(Imlib_Updates updates, int *x_return,
2845                               int *y_return, int *width_return,
2846                               int *height_return)
2847 {
2848    ImlibUpdate        *u;
2849 
2850    CHECK_CONTEXT(ctx);
2851    CHECK_PARAM_POINTER("imlib_updates_get_coordinates", "updates", updates);
2852    u = (ImlibUpdate *) updates;
2853    if (x_return)
2854       *x_return = u->x;
2855    if (y_return)
2856       *y_return = u->y;
2857    if (width_return)
2858       *width_return = u->w;
2859    if (height_return)
2860       *height_return = u->h;
2861 }
2862 
2863 /**
2864  * @param updates An updates list.
2865  * @param x The top left x coordinate of the update.
2866  * @param y The top left y coordinate of the update.
2867  * @param width The width of the update.
2868  * @param height The height of the update.
2869  *
2870  * Modifies the coordinates of an update in @p update.
2871  **/
2872 EAPI void
imlib_updates_set_coordinates(Imlib_Updates updates,int x,int y,int width,int height)2873 imlib_updates_set_coordinates(Imlib_Updates updates, int x, int y, int width,
2874                               int height)
2875 {
2876    ImlibUpdate        *u;
2877 
2878    CHECK_CONTEXT(ctx);
2879    CHECK_PARAM_POINTER("imlib_updates_set_coordinates", "updates", updates);
2880    u = (ImlibUpdate *) updates;
2881    u->x = x;
2882    u->y = y;
2883    u->w = width;
2884    u->h = height;
2885 }
2886 
2887 #ifdef BUILD_X11
2888 /**
2889  * @param updates An updates list.
2890  * @param x The top left x coordinate of the update.
2891  * @param y The top left y coordinate of the update.
2892  *
2893  * Given an updates list (preferable already merged for rendering)
2894  * this will render the corresponding parts of the image to the current
2895  * drawable at an offset of @p x, @p y in the drawable.
2896  **/
2897 EAPI void
imlib_render_image_updates_on_drawable(Imlib_Updates updates,int x,int y)2898 imlib_render_image_updates_on_drawable(Imlib_Updates updates, int x, int y)
2899 {
2900    ImlibUpdate        *u;
2901    ImlibImage         *im;
2902    int                 ximcs;
2903 
2904    CHECK_CONTEXT(ctx);
2905    CHECK_PARAM_POINTER("imlib_render_image_updates_on_drawable", "image",
2906                        ctx->image);
2907    CAST_IMAGE(im, ctx->image);
2908    u = (ImlibUpdate *) updates;
2909    if (!updates)
2910       return;
2911    if (__imlib_LoadImageData(im))
2912       return;
2913    ximcs = __imlib_GetXImageCacheCountMax(ctx->display);        /* Save */
2914    if (ximcs == 0)              /* Only if we don't set this up elsewhere */
2915       __imlib_SetXImageCacheCountMax(ctx->display, 10);
2916    for (; u; u = u->next)
2917      {
2918         __imlib_RenderImage(ctx->display, im, ctx->drawable, 0, ctx->visual,
2919                             ctx->colormap, ctx->depth, u->x, u->y, u->w, u->h,
2920                             x + u->x, y + u->y, u->w, u->h, 0, ctx->dither, 0,
2921                             0, 0, ctx->color_modifier, OP_COPY);
2922      }
2923    if (ximcs == 0)
2924       __imlib_SetXImageCacheCountMax(ctx->display, ximcs);
2925 }
2926 #endif
2927 
2928 /**
2929  * @return The initialized updates list.
2930  *
2931  * Initializes an updates list before you add any updates to it or
2932  * merge it for rendering etc.
2933  **/
2934 EAPI                Imlib_Updates
imlib_updates_init(void)2935 imlib_updates_init(void)
2936 {
2937    CHECK_CONTEXT(ctx);
2938    return (Imlib_Updates) NULL;
2939 }
2940 
2941 /**
2942  * @param updates An updates list.
2943  * @param appended_updates The updates list to append.
2944  * @return The new updates list.
2945  *
2946  * Appends @p appended_updates to the updates list @p updates and
2947  * returns the new list.
2948  **/
2949 EAPI                Imlib_Updates
imlib_updates_append_updates(Imlib_Updates updates,Imlib_Updates appended_updates)2950 imlib_updates_append_updates(Imlib_Updates updates,
2951                              Imlib_Updates appended_updates)
2952 {
2953    ImlibUpdate        *u, *uu;
2954 
2955    CHECK_CONTEXT(ctx);
2956    u = (ImlibUpdate *) updates;
2957    uu = (ImlibUpdate *) appended_updates;
2958    if (!uu)
2959       return (Imlib_Updates) u;
2960    if (!u)
2961       return (Imlib_Updates) uu;
2962    while (u)
2963      {
2964         if (!(u->next))
2965           {
2966              u->next = uu;
2967              return updates;
2968           }
2969         u = u->next;
2970      }
2971    return (Imlib_Updates) u;
2972 }
2973 
2974 /**
2975  * Flips/mirrors the current image horizontally.
2976  **/
2977 EAPI void
imlib_image_flip_horizontal(void)2978 imlib_image_flip_horizontal(void)
2979 {
2980    ImlibImage         *im;
2981 
2982    CHECK_CONTEXT(ctx);
2983    CHECK_PARAM_POINTER("imlib_image_flip_horizontal", "image", ctx->image);
2984    CAST_IMAGE(im, ctx->image);
2985    if (__imlib_LoadImageData(im))
2986       return;
2987    __imlib_DirtyImage(im);
2988    __imlib_FlipImageHoriz(im);
2989 }
2990 
2991 /**
2992  * Flips/mirrors the current image vertically.
2993  **/
2994 EAPI void
imlib_image_flip_vertical(void)2995 imlib_image_flip_vertical(void)
2996 {
2997    ImlibImage         *im;
2998 
2999    CHECK_CONTEXT(ctx);
3000    CHECK_PARAM_POINTER("imlib_image_flip_vertical", "image", ctx->image);
3001    CAST_IMAGE(im, ctx->image);
3002    if (__imlib_LoadImageData(im))
3003       return;
3004    __imlib_DirtyImage(im);
3005    __imlib_FlipImageVert(im);
3006 }
3007 
3008 /**
3009  * Flips/mirrors the current image diagonally (good for quick and dirty
3010  * 90 degree rotations if used before to after a horizontal or vertical
3011  * flip).
3012  **/
3013 EAPI void
imlib_image_flip_diagonal(void)3014 imlib_image_flip_diagonal(void)
3015 {
3016    ImlibImage         *im;
3017 
3018    CHECK_CONTEXT(ctx);
3019    CHECK_PARAM_POINTER("imlib_image_flip_diagonal", "image", ctx->image);
3020    CAST_IMAGE(im, ctx->image);
3021    if (__imlib_LoadImageData(im))
3022       return;
3023    __imlib_DirtyImage(im);
3024    __imlib_FlipImageDiagonal(im, 0);
3025 }
3026 
3027 /**
3028  * @param orientation The orientation.
3029  *
3030  * Performs 90 degree rotations on the current image. Passing in
3031  * @p orientation does not rotate, 1 rotates clockwise by 90 degree, 2,
3032  * rotates clockwise by 180 degrees, 3 rotates clockwise by 270
3033  * degrees.
3034  **/
3035 EAPI void
imlib_image_orientate(int orientation)3036 imlib_image_orientate(int orientation)
3037 {
3038    ImlibImage         *im;
3039 
3040    CHECK_CONTEXT(ctx);
3041    CHECK_PARAM_POINTER("imlib_image_orientate", "image", ctx->image);
3042    CAST_IMAGE(im, ctx->image);
3043    if (__imlib_LoadImageData(im))
3044       return;
3045    __imlib_DirtyImage(im);
3046    switch (orientation)
3047      {
3048      default:
3049      case 0:
3050         break;
3051      case 1:
3052         __imlib_FlipImageDiagonal(im, 1);
3053         break;
3054      case 2:
3055         __imlib_FlipImageBoth(im);
3056         break;
3057      case 3:
3058         __imlib_FlipImageDiagonal(im, 2);
3059         break;
3060      case 4:
3061         __imlib_FlipImageHoriz(im);
3062         break;
3063      case 5:
3064         __imlib_FlipImageDiagonal(im, 3);
3065         break;
3066      case 6:
3067         __imlib_FlipImageVert(im);
3068         break;
3069      case 7:
3070         __imlib_FlipImageDiagonal(im, 0);
3071         break;
3072      }
3073 }
3074 
3075 /**
3076  * @param radius The radius.
3077  *
3078  * Blurs the current image. A @p radius value of 0 has no effect, 1 and above
3079  * determine the blur matrix radius that determine how much to blur the
3080  * image.
3081  **/
3082 EAPI void
imlib_image_blur(int radius)3083 imlib_image_blur(int radius)
3084 {
3085    ImlibImage         *im;
3086 
3087    CHECK_CONTEXT(ctx);
3088    CHECK_PARAM_POINTER("imlib_image_blur", "image", ctx->image);
3089    CAST_IMAGE(im, ctx->image);
3090    if (__imlib_LoadImageData(im))
3091       return;
3092    __imlib_DirtyImage(im);
3093    __imlib_BlurImage(im, radius);
3094 }
3095 
3096 /**
3097  * @param radius The radius.
3098  *
3099  * Sharpens the current image. The @p radius value affects how much to sharpen
3100  * by.
3101  **/
3102 EAPI void
imlib_image_sharpen(int radius)3103 imlib_image_sharpen(int radius)
3104 {
3105    ImlibImage         *im;
3106 
3107    CHECK_CONTEXT(ctx);
3108    CAST_IMAGE(im, ctx->image);
3109    CHECK_PARAM_POINTER("imlib_image_sharpen", "image", ctx->image);
3110    if (__imlib_LoadImageData(im))
3111       return;
3112    __imlib_DirtyImage(im);
3113    __imlib_SharpenImage(im, radius);
3114 }
3115 
3116 /**
3117  * Modifies an image so it will tile seamlessly horizontally if used
3118  * as a tile (i.e. drawn multiple times horizontally).
3119  **/
3120 EAPI void
imlib_image_tile_horizontal(void)3121 imlib_image_tile_horizontal(void)
3122 {
3123    ImlibImage         *im;
3124 
3125    CHECK_CONTEXT(ctx);
3126    CHECK_PARAM_POINTER("imlib_image_tile_horizontal", "image", ctx->image);
3127    CAST_IMAGE(im, ctx->image);
3128    if (__imlib_LoadImageData(im))
3129       return;
3130    __imlib_DirtyImage(im);
3131    __imlib_TileImageHoriz(im);
3132 }
3133 
3134 /**
3135  * Modifies an image so it will tile seamlessly vertically if used as
3136  * a tile (i.e. drawn multiple times vertically).
3137  **/
3138 EAPI void
imlib_image_tile_vertical(void)3139 imlib_image_tile_vertical(void)
3140 {
3141    ImlibImage         *im;
3142 
3143    CHECK_CONTEXT(ctx);
3144    CHECK_PARAM_POINTER("imlib_image_tile_vertical", "image", ctx->image);
3145    CAST_IMAGE(im, ctx->image);
3146    if (__imlib_LoadImageData(im))
3147       return;
3148    __imlib_DirtyImage(im);
3149    __imlib_TileImageVert(im);
3150 }
3151 
3152 /**
3153  * Modifies an image so it will tile seamlessly horizontally and
3154  * vertically if used as a tile (i.e. drawn multiple times horizontally
3155  * and vertically).
3156  **/
3157 EAPI void
imlib_image_tile(void)3158 imlib_image_tile(void)
3159 {
3160    ImlibImage         *im;
3161 
3162    CHECK_CONTEXT(ctx);
3163    CHECK_PARAM_POINTER("imlib_image_tile", "image", ctx->image);
3164    CAST_IMAGE(im, ctx->image);
3165    if (__imlib_LoadImageData(im))
3166       return;
3167    __imlib_DirtyImage(im);
3168    __imlib_TileImageHoriz(im);
3169    __imlib_TileImageVert(im);
3170 }
3171 
3172 /**
3173  * @param font_name The font name with the size.
3174  * @return NULL if no font found.
3175  *
3176  * Loads a truetype font from the first directory in the font path that
3177  * contains that font. The font name @p font_name format is "font_name/size". For
3178  * example. If there is a font file called blum.ttf somewhere in the
3179  * font path you might use "blum/20" to load a 20 pixel sized font of
3180  * blum. If the font cannot be found NULL is returned.
3181  *
3182  **/
3183 EAPI                Imlib_Font
imlib_load_font(const char * font_name)3184 imlib_load_font(const char *font_name)
3185 {
3186    return __imlib_font_load_joined(font_name);
3187 }
3188 
3189 /**
3190  * Removes the current font from any fallback chain it's in and frees it.
3191  **/
3192 EAPI void
imlib_free_font(void)3193 imlib_free_font(void)
3194 {
3195    CHECK_CONTEXT(ctx);
3196    CHECK_PARAM_POINTER("imlib_free_font", "font", ctx->font);
3197    imlib_remove_font_from_fallback_chain(ctx->font);
3198    __imlib_font_free(ctx->font);
3199    ctx->font = NULL;
3200 }
3201 
3202 /**
3203  * @param font A previously loaded font.
3204  * @param fallback_font A previously loaded font to be chained to the given font.
3205  * @return 0 on success.
3206  *
3207  * This arranges for the given fallback font to be used if a glyph does not
3208  * exist in the given font when text is being rendered.
3209  * Fonts can be arranged in an aribitrarily long chain and attempts will be
3210  * made in order on the chain.
3211  * Cycles in the chain are not possible since the given fallback font is
3212  * removed from any chain it's already in.
3213  * A fallback font may be a member of only one chain. Adding it as the
3214  * fallback font to another font will remove it from it's first fallback chain.
3215  *
3216  * @deprecated This function may be removed.
3217  **/
3218 EAPI int
imlib_insert_font_into_fallback_chain(Imlib_Font font,Imlib_Font fallback_font)3219 imlib_insert_font_into_fallback_chain(Imlib_Font font, Imlib_Font fallback_font)
3220 {
3221    CHECK_PARAM_POINTER_RETURN("imlib_insert_font_into_fallback_chain",
3222                               "font", font, 1);
3223    CHECK_PARAM_POINTER_RETURN("imlib_insert_font_into_fallback_chain",
3224                               "fallback_font", fallback_font, 1);
3225    return __imlib_font_insert_into_fallback_chain_imp(font, fallback_font);
3226 }
3227 
3228 /**
3229  * @param fallback_font A font previously added to a fallback chain.
3230  * @return 0 on success.
3231  *
3232  * This removes the given font from any fallback chain it may be in.
3233  * Removing this font joins its previous and next font together in the fallback
3234  * chain.
3235  *
3236  * @deprecated This function may be removed.
3237  **/
3238 EAPI void
imlib_remove_font_from_fallback_chain(Imlib_Font fallback_font)3239 imlib_remove_font_from_fallback_chain(Imlib_Font fallback_font)
3240 {
3241    CHECK_PARAM_POINTER("imlib_remove_font_from_fallback_chain",
3242                        "fallback_font", fallback_font);
3243    __imlib_font_remove_from_fallback_chain_imp(fallback_font);
3244 }
3245 
3246 /**
3247  * @deprecated This function may be removed.
3248  **/
3249 EAPI                Imlib_Font
imlib_get_prev_font_in_fallback_chain(Imlib_Font fn)3250 imlib_get_prev_font_in_fallback_chain(Imlib_Font fn)
3251 {
3252    CHECK_PARAM_POINTER_RETURN("imlib_get_prev_font_in_fallback_chain",
3253                               "fn", fn, 0);
3254    return ((ImlibFont *) fn)->fallback_prev;
3255 }
3256 
3257 /**
3258  * @deprecated This function may be removed.
3259  **/
3260 EAPI                Imlib_Font
imlib_get_next_font_in_fallback_chain(Imlib_Font fn)3261 imlib_get_next_font_in_fallback_chain(Imlib_Font fn)
3262 {
3263    CHECK_PARAM_POINTER_RETURN("imlib_get_next_font_in_fallback_chain",
3264                               "fn", fn, 0);
3265    return ((ImlibFont *) fn)->fallback_next;
3266 }
3267 
3268 /**
3269  * @param x The x coordinate of the top left  corner.
3270  * @param y The y coordinate of the top left  corner.
3271  * @param text A null-byte terminated string.
3272  *
3273  * Draws the null-byte terminated string @p text using the current font on
3274  * the current image at the (@p x, @p y) location (@p x, @p y denoting the top left
3275  * corner of the font string)
3276  **/
3277 EAPI void
imlib_text_draw(int x,int y,const char * text)3278 imlib_text_draw(int x, int y, const char *text)
3279 {
3280    CHECK_CONTEXT(ctx);
3281    imlib_text_draw_with_return_metrics(x, y, text, NULL, NULL, NULL, NULL);
3282 }
3283 
3284 /**
3285  * @param x The x coordinate of the top left  corner.
3286  * @param y The y coordinate of the top left  corner.
3287  * @param text A null-byte terminated string.
3288  * @param width_return The width of the string.
3289  * @param height_return The height of the string.
3290  * @param horizontal_advance_return Horizontal offset.
3291  * @param vertical_advance_return Vertical offset.
3292  *
3293  * Works just like imlib_text_draw() but also returns the width and
3294  * height of the string drawn, and @p horizontal_advance_return returns
3295  * the number of pixels you should advance horizontally to draw another
3296  * string (useful if you are drawing a line of text word by word) and
3297  * @p vertical_advance_return does the same for the vertical direction
3298  * (i.e. drawing text line by line).
3299  **/
3300 EAPI void
imlib_text_draw_with_return_metrics(int x,int y,const char * text,int * width_return,int * height_return,int * horizontal_advance_return,int * vertical_advance_return)3301 imlib_text_draw_with_return_metrics(int x, int y, const char *text,
3302                                     int *width_return, int *height_return,
3303                                     int *horizontal_advance_return,
3304                                     int *vertical_advance_return)
3305 {
3306    ImlibImage         *im;
3307    ImlibFont          *fn;
3308    int                 dir;
3309 
3310    CHECK_CONTEXT(ctx);
3311    CHECK_PARAM_POINTER("imlib_text_draw_with_return_metrics", "font",
3312                        ctx->font);
3313    CHECK_PARAM_POINTER("imlib_text_draw_with_return_metrics", "image",
3314                        ctx->image);
3315    CHECK_PARAM_POINTER("imlib_text_draw_with_return_metrics", "text", text);
3316    CAST_IMAGE(im, ctx->image);
3317    if (__imlib_LoadImageData(im))
3318       return;
3319    fn = (ImlibFont *) ctx->font;
3320    __imlib_DirtyImage(im);
3321 
3322    dir = ctx->direction;
3323    if (ctx->direction == IMLIB_TEXT_TO_ANGLE && ctx->angle == 0.0)
3324       dir = IMLIB_TEXT_TO_RIGHT;
3325 
3326    __imlib_render_str(im, fn, x, y, text, ctx->pixel, dir,
3327                       ctx->angle, width_return, height_return, 0,
3328                       horizontal_advance_return, vertical_advance_return,
3329                       ctx->operation,
3330                       ctx->cliprect.x, ctx->cliprect.y,
3331                       ctx->cliprect.w, ctx->cliprect.h);
3332 }
3333 
3334 /**
3335  * @param text A string.
3336  * @param width_return The width of the text.
3337  * @param height_return The height of the text.
3338  *
3339  * Gets the width and height in pixels the @p text string would use up
3340  * if drawn with the current font.
3341  **/
3342 EAPI void
imlib_get_text_size(const char * text,int * width_return,int * height_return)3343 imlib_get_text_size(const char *text, int *width_return, int *height_return)
3344 {
3345    ImlibFont          *fn;
3346    int                 w, h;
3347    int                 dir;
3348 
3349    CHECK_CONTEXT(ctx);
3350    CHECK_PARAM_POINTER("imlib_get_text_size", "font", ctx->font);
3351    CHECK_PARAM_POINTER("imlib_get_text_size", "text", text);
3352    fn = (ImlibFont *) ctx->font;
3353 
3354    dir = ctx->direction;
3355    if (ctx->direction == IMLIB_TEXT_TO_ANGLE && ctx->angle == 0.0)
3356       dir = IMLIB_TEXT_TO_RIGHT;
3357 
3358    __imlib_font_query_size(fn, text, &w, &h);
3359 
3360    switch (dir)
3361      {
3362      case IMLIB_TEXT_TO_RIGHT:
3363      case IMLIB_TEXT_TO_LEFT:
3364         if (width_return)
3365            *width_return = w;
3366         if (height_return)
3367            *height_return = h;
3368         break;
3369      case IMLIB_TEXT_TO_DOWN:
3370      case IMLIB_TEXT_TO_UP:
3371         if (width_return)
3372            *width_return = h;
3373         if (height_return)
3374            *height_return = w;
3375         break;
3376      case IMLIB_TEXT_TO_ANGLE:
3377         if (width_return || height_return)
3378           {
3379              double              sa, ca;
3380 
3381              sa = sin(ctx->angle);
3382              ca = cos(ctx->angle);
3383 
3384              if (width_return)
3385                {
3386                   double              x1, x2, xt;
3387 
3388                   x1 = x2 = 0.0;
3389                   xt = ca * w;
3390                   if (xt < x1)
3391                      x1 = xt;
3392                   if (xt > x2)
3393                      x2 = xt;
3394                   xt = -(sa * h);
3395                   if (xt < x1)
3396                      x1 = xt;
3397                   if (xt > x2)
3398                      x2 = xt;
3399                   xt = ca * w - sa * h;
3400                   if (xt < x1)
3401                      x1 = xt;
3402                   if (xt > x2)
3403                      x2 = xt;
3404                   *width_return = (int)(x2 - x1);
3405                }
3406              if (height_return)
3407                {
3408                   double              y1, y2, yt;
3409 
3410                   y1 = y2 = 0.0;
3411                   yt = sa * w;
3412                   if (yt < y1)
3413                      y1 = yt;
3414                   if (yt > y2)
3415                      y2 = yt;
3416                   yt = ca * h;
3417                   if (yt < y1)
3418                      y1 = yt;
3419                   if (yt > y2)
3420                      y2 = yt;
3421                   yt = sa * w + ca * h;
3422                   if (yt < y1)
3423                      y1 = yt;
3424                   if (yt > y2)
3425                      y2 = yt;
3426                   *height_return = (int)(y2 - y1);
3427                }
3428           }
3429         break;
3430      default:
3431         break;
3432      }
3433 }
3434 
3435 /**
3436  * @param text A string.
3437  * @param horizontal_advance_return Horizontal offset.
3438  * @param vertical_advance_return Vertical offset.
3439  *
3440  * Gets the advance horizontally and vertically in pixels the next
3441  * text string would need to be placed at for the current font. The
3442  * advances are not adjusted for rotation so you will have to translate
3443  * the advances (which are calculated as if the text was drawn
3444  * horizontally from left to right) depending on the text orientation.
3445  **/
3446 EAPI void
imlib_get_text_advance(const char * text,int * horizontal_advance_return,int * vertical_advance_return)3447 imlib_get_text_advance(const char *text, int *horizontal_advance_return,
3448                        int *vertical_advance_return)
3449 {
3450    ImlibFont          *fn;
3451    int                 w, h;
3452 
3453    CHECK_CONTEXT(ctx);
3454    CHECK_PARAM_POINTER("imlib_get_text_advance", "font", ctx->font);
3455    CHECK_PARAM_POINTER("imlib_get_text_advance", "text", text);
3456    fn = (ImlibFont *) ctx->font;
3457    __imlib_font_query_advance(fn, text, &w, &h);
3458    if (horizontal_advance_return)
3459       *horizontal_advance_return = w;
3460    if (vertical_advance_return)
3461       *vertical_advance_return = h;
3462 }
3463 
3464 /**
3465  * @param text A string.
3466  * @return The inset value of @text.
3467  *
3468  * Returns the inset of the first character of @p text
3469  * in using the current font and returns that value in pixels.
3470  *
3471  **/
3472 EAPI int
imlib_get_text_inset(const char * text)3473 imlib_get_text_inset(const char *text)
3474 {
3475    ImlibFont          *fn;
3476 
3477    CHECK_CONTEXT(ctx);
3478    CHECK_PARAM_POINTER_RETURN("imlib_get_text_advance", "font", ctx->font, 0);
3479    CHECK_PARAM_POINTER_RETURN("imlib_get_text_advance", "text", text, 0);
3480    fn = (ImlibFont *) ctx->font;
3481    return __imlib_font_query_inset(fn, text);
3482 }
3483 
3484 /**
3485  * @param path A directory path.
3486  *
3487  * Adds the directory @p path to the end of the current list of
3488  * directories to scan for fonts.
3489  **/
3490 EAPI void
imlib_add_path_to_font_path(const char * path)3491 imlib_add_path_to_font_path(const char *path)
3492 {
3493    CHECK_CONTEXT(ctx);
3494    CHECK_PARAM_POINTER("imlib_add_path_to_font_path", "path", path);
3495    if (!__imlib_font_path_exists(path))
3496       __imlib_font_add_font_path(path);
3497 }
3498 
3499 /**
3500  * @param path A directory path.
3501  *
3502  * Removes all directories in the font path that match @p path.
3503  **/
3504 EAPI void
imlib_remove_path_from_font_path(const char * path)3505 imlib_remove_path_from_font_path(const char *path)
3506 {
3507    CHECK_CONTEXT(ctx);
3508    CHECK_PARAM_POINTER("imlib_remove_path_from_font_path", "path", path);
3509    __imlib_font_del_font_path(path);
3510 }
3511 
3512 /**
3513  * @param number_return Number of paths in the list.
3514  * @return A list of strings.
3515  *
3516  * Returns a list of strings that are the directories in the font
3517  * path. Do not free this list or change it in any way. If you add or
3518  * delete members of the font path this list will be invalid. If you
3519  * intend to use this list later duplicate it for your own use. The
3520  * number of elements in the array of strings is put into
3521  * @p number_return.
3522  *
3523  **/
3524 EAPI char         **
imlib_list_font_path(int * number_return)3525 imlib_list_font_path(int *number_return)
3526 {
3527    CHECK_CONTEXT(ctx);
3528    CHECK_PARAM_POINTER_RETURN("imlib_list_font_path", "number_return",
3529                               number_return, NULL);
3530    return __imlib_font_list_font_path(number_return);
3531 }
3532 
3533 /**
3534  * @param text A string.
3535  * @param x The x offset.
3536  * @param y The y offset.
3537  * @param char_x_return The x coordinate of the character.
3538  * @param char_y_return The x coordinate of the character.
3539  * @param char_width_return The width of the character.
3540  * @param char_height_return The height of the character.
3541  * @return -1 if no character found.
3542  *
3543  * Returns the character number in the string @p text using the current
3544  * font at the (@p x, @p y) pixel location which is an offset relative to the
3545  * top left of that string. -1 is returned if there is no character
3546  * there. If there is a character, @p char_x_return, @p char_y_return,
3547  * @p char_width_return and @p char_height_return (respectively the
3548  * character x, y, width and height)  are also filled in.
3549  *
3550  **/
3551 EAPI int
imlib_text_get_index_and_location(const char * text,int x,int y,int * char_x_return,int * char_y_return,int * char_width_return,int * char_height_return)3552 imlib_text_get_index_and_location(const char *text, int x, int y,
3553                                   int *char_x_return, int *char_y_return,
3554                                   int *char_width_return,
3555                                   int *char_height_return)
3556 {
3557    ImlibFont          *fn;
3558    int                 w, h, cx, cy, cw, ch, cp, xx, yy;
3559    int                 dir;
3560 
3561    CHECK_CONTEXT(ctx);
3562    CHECK_PARAM_POINTER_RETURN("imlib_text_get_index_and_location", "font",
3563                               ctx->font, -1);
3564    CHECK_PARAM_POINTER_RETURN("imlib_text_get_index_and_location", "text",
3565                               text, -1);
3566    fn = (ImlibFont *) ctx->font;
3567 
3568    dir = ctx->direction;
3569    if (ctx->direction == IMLIB_TEXT_TO_ANGLE && ctx->angle == 0.0)
3570       dir = IMLIB_TEXT_TO_RIGHT;
3571 
3572    imlib_get_text_size(text, &w, &h);
3573 
3574    switch (dir)
3575      {
3576      case IMLIB_TEXT_TO_RIGHT:
3577         xx = x;
3578         yy = y;
3579         break;
3580      case IMLIB_TEXT_TO_LEFT:
3581         xx = w - x;
3582         yy = h - y;
3583         break;
3584      case IMLIB_TEXT_TO_DOWN:
3585         xx = y;
3586         yy = w - x;
3587         break;
3588      case IMLIB_TEXT_TO_UP:
3589         xx = h - y;
3590         yy = x;
3591         break;
3592      default:
3593         return -1;
3594      }
3595 
3596    cp = __imlib_font_query_text_at_pos(fn, text, xx, yy, &cx, &cy, &cw, &ch);
3597 
3598    switch (dir)
3599      {
3600      case IMLIB_TEXT_TO_RIGHT:
3601         if (char_x_return)
3602            *char_x_return = cx;
3603         if (char_y_return)
3604            *char_y_return = cy;
3605         if (char_width_return)
3606            *char_width_return = cw;
3607         if (char_height_return)
3608            *char_height_return = ch;
3609         return cp;
3610         break;
3611      case IMLIB_TEXT_TO_LEFT:
3612         cx = 1 + w - cx - cw;
3613         if (char_x_return)
3614            *char_x_return = cx;
3615         if (char_y_return)
3616            *char_y_return = cy;
3617         if (char_width_return)
3618            *char_width_return = cw;
3619         if (char_height_return)
3620            *char_height_return = ch;
3621         return cp;
3622         break;
3623      case IMLIB_TEXT_TO_DOWN:
3624         if (char_x_return)
3625            *char_x_return = cy;
3626         if (char_y_return)
3627            *char_y_return = cx;
3628         if (char_width_return)
3629            *char_width_return = ch;
3630         if (char_height_return)
3631            *char_height_return = cw;
3632         return cp;
3633         break;
3634      case IMLIB_TEXT_TO_UP:
3635         cy = 1 + h - cy - ch;
3636         if (char_x_return)
3637            *char_x_return = cy;
3638         if (char_y_return)
3639            *char_y_return = cx;
3640         if (char_width_return)
3641            *char_width_return = ch;
3642         if (char_height_return)
3643            *char_height_return = cw;
3644         return cp;
3645         break;
3646      default:
3647         return -1;
3648         break;
3649      }
3650    return -1;
3651 }
3652 
3653 /**
3654  * @param text A string.
3655  * @param index The index of @text.
3656  * @param char_x_return The x coordinate of the character.
3657  * @param char_y_return The y coordinate of the character.
3658  * @param char_width_return The width of the character.
3659  * @param char_height_return The height of the character.
3660  *
3661  * Gets the geometry of the character at index @p index in the @p text
3662  * string using the current font.
3663  **/
3664 EAPI void
imlib_text_get_location_at_index(const char * text,int index,int * char_x_return,int * char_y_return,int * char_width_return,int * char_height_return)3665 imlib_text_get_location_at_index(const char *text, int index,
3666                                  int *char_x_return, int *char_y_return,
3667                                  int *char_width_return,
3668                                  int *char_height_return)
3669 {
3670    ImlibFont          *fn;
3671    int                 cx, cy, cw, ch, w, h;
3672 
3673    CHECK_CONTEXT(ctx);
3674    CHECK_PARAM_POINTER("imlib_text_get_index_and_location", "font", ctx->font);
3675    CHECK_PARAM_POINTER("imlib_text_get_index_and_location", "text", text);
3676    fn = (ImlibFont *) ctx->font;
3677 
3678    __imlib_font_query_char_coords(fn, text, index, &cx, &cy, &cw, &ch);
3679 
3680    imlib_get_text_size(text, &w, &h);
3681 
3682    switch (ctx->direction)
3683      {
3684      case IMLIB_TEXT_TO_RIGHT:
3685         if (char_x_return)
3686            *char_x_return = cx;
3687         if (char_y_return)
3688            *char_y_return = cy;
3689         if (char_width_return)
3690            *char_width_return = cw;
3691         if (char_height_return)
3692            *char_height_return = ch;
3693         return;
3694         break;
3695      case IMLIB_TEXT_TO_LEFT:
3696         cx = 1 + w - cx - cw;
3697         if (char_x_return)
3698            *char_x_return = cx;
3699         if (char_y_return)
3700            *char_y_return = cy;
3701         if (char_width_return)
3702            *char_width_return = cw;
3703         if (char_height_return)
3704            *char_height_return = ch;
3705         return;
3706         break;
3707      case IMLIB_TEXT_TO_DOWN:
3708         if (char_x_return)
3709            *char_x_return = cy;
3710         if (char_y_return)
3711            *char_y_return = cx;
3712         if (char_width_return)
3713            *char_width_return = ch;
3714         if (char_height_return)
3715            *char_height_return = cw;
3716         return;
3717         break;
3718      case IMLIB_TEXT_TO_UP:
3719         cy = 1 + h - cy - ch;
3720         if (char_x_return)
3721            *char_x_return = cy;
3722         if (char_y_return)
3723            *char_y_return = cx;
3724         if (char_width_return)
3725            *char_width_return = ch;
3726         if (char_height_return)
3727            *char_height_return = cw;
3728         return;
3729         break;
3730      default:
3731         return;
3732         break;
3733      }
3734 }
3735 
3736 /**
3737  * @param number_return Number of fonts in the list.
3738  * @return A list of fonts.
3739  *
3740  * Returns a list of fonts imlib2 can find in its font path.
3741  *
3742  **/
3743 EAPI char         **
imlib_list_fonts(int * number_return)3744 imlib_list_fonts(int *number_return)
3745 {
3746    CHECK_CONTEXT(ctx);
3747    CHECK_PARAM_POINTER_RETURN("imlib_list_fonts", "number_return",
3748                               number_return, NULL);
3749    return __imlib_font_list_fonts(number_return);
3750 }
3751 
3752 /**
3753  * @param font_list The font list.
3754  * @param number Number of fonts in the list.
3755  *
3756  * Frees the font list returned by imlib_list_fonts().
3757  *
3758  **/
3759 EAPI void
imlib_free_font_list(char ** font_list,int number)3760 imlib_free_font_list(char **font_list, int number)
3761 {
3762    __imlib_FileFreeDirList(font_list, number);
3763 }
3764 
3765 /**
3766  * @return The font cache size.
3767  *
3768  * Returns the font cache size in bytes.
3769  *
3770  **/
3771 EAPI int
imlib_get_font_cache_size(void)3772 imlib_get_font_cache_size(void)
3773 {
3774    CHECK_CONTEXT(ctx);
3775    return __imlib_font_cache_get();
3776 }
3777 
3778 /**
3779  * @param bytes The font cache size.
3780  *
3781  * Sets the font cache in bytes. Whenever you set the font cache size
3782  * Imlib2 will flush fonts from the cache until the memory used by
3783  * fonts is less than or equal to the font cache size. Setting the size
3784  * to 0 effectively frees all speculatively cached fonts.
3785  **/
3786 EAPI void
imlib_set_font_cache_size(int bytes)3787 imlib_set_font_cache_size(int bytes)
3788 {
3789    CHECK_CONTEXT(ctx);
3790    __imlib_font_cache_set(bytes);
3791 }
3792 
3793 /**
3794  * Causes a flush of all speculatively cached fonts from the font
3795  * cache.
3796  **/
3797 EAPI void
imlib_flush_font_cache(void)3798 imlib_flush_font_cache(void)
3799 {
3800    CHECK_CONTEXT(ctx);
3801    __imlib_font_flush();
3802 }
3803 
3804 /**
3805  * @return The font's ascent.
3806  *
3807  * Returns the current font's ascent value in pixels.
3808  *
3809  **/
3810 EAPI int
imlib_get_font_ascent(void)3811 imlib_get_font_ascent(void)
3812 {
3813    CHECK_CONTEXT(ctx);
3814    CHECK_PARAM_POINTER_RETURN("imlib_get_font_ascent", "font", ctx->font, 0);
3815    return __imlib_font_ascent_get(ctx->font);
3816 }
3817 
3818 /**
3819  * @return The font's descent.
3820  *
3821  * Returns the current font's descent value in pixels.
3822  *
3823  **/
3824 EAPI int
imlib_get_font_descent(void)3825 imlib_get_font_descent(void)
3826 {
3827    CHECK_CONTEXT(ctx);
3828    CHECK_PARAM_POINTER_RETURN("imlib_get_font_ascent", "font", ctx->font, 0);
3829    return __imlib_font_descent_get(ctx->font);
3830 }
3831 
3832 /**
3833  * @return The font's maximum ascent.
3834  *
3835  * Returns the current font's maximum ascent extent.
3836  *
3837  **/
3838 EAPI int
imlib_get_maximum_font_ascent(void)3839 imlib_get_maximum_font_ascent(void)
3840 {
3841    CHECK_CONTEXT(ctx);
3842    CHECK_PARAM_POINTER_RETURN("imlib_get_font_ascent", "font", ctx->font, 0);
3843    return __imlib_font_max_ascent_get(ctx->font);
3844 }
3845 
3846 /**
3847  * @return The font's maximum descent.
3848  *
3849  * Returns the current font's maximum descent extent.
3850  *
3851  **/
3852 EAPI int
imlib_get_maximum_font_descent(void)3853 imlib_get_maximum_font_descent(void)
3854 {
3855    CHECK_CONTEXT(ctx);
3856    CHECK_PARAM_POINTER_RETURN("imlib_get_font_ascent", "font", ctx->font, 0);
3857    return __imlib_font_max_descent_get(ctx->font);
3858 }
3859 
3860 /**
3861  * @return Valid handle.
3862  *
3863  * Creates a new empty color modifier and returns a
3864  * valid handle on success. NULL is returned on failure.
3865  *
3866  **/
3867 EAPI                Imlib_Color_Modifier
imlib_create_color_modifier(void)3868 imlib_create_color_modifier(void)
3869 {
3870    CHECK_CONTEXT(ctx);
3871    return (Imlib_Color_Modifier) __imlib_CreateCmod();
3872 }
3873 
3874 /**
3875  * Frees the current color modifier.
3876  **/
3877 EAPI void
imlib_free_color_modifier(void)3878 imlib_free_color_modifier(void)
3879 {
3880    CHECK_CONTEXT(ctx);
3881    CHECK_PARAM_POINTER("imlib_free_color_modifier", "color_modifier",
3882                        ctx->color_modifier);
3883    __imlib_FreeCmod((ImlibColorModifier *) ctx->color_modifier);
3884    ctx->color_modifier = NULL;
3885 }
3886 
3887 /**
3888  * @param gamma_value Value of gamma.
3889  *
3890  * Modifies the current color modifier by adjusting the gamma by the
3891  * value specified @p gamma_value. The color modifier is modified not set, so calling
3892  * this repeatedly has cumulative effects. A gamma of 1.0 is normal
3893  * linear, 2.0 brightens and 0.5 darkens etc. Negative values are not
3894  * allowed.
3895  **/
3896 EAPI void
imlib_modify_color_modifier_gamma(double gamma_value)3897 imlib_modify_color_modifier_gamma(double gamma_value)
3898 {
3899    CHECK_CONTEXT(ctx);
3900    CHECK_PARAM_POINTER("imlib_modify_color_modifier_gamma", "color_modifier",
3901                        ctx->color_modifier);
3902    __imlib_CmodModGamma((ImlibColorModifier *) ctx->color_modifier,
3903                         gamma_value);
3904 }
3905 
3906 /**
3907  * @param brightness_value Value of brightness.
3908  *
3909  * Modifies the current color modifier by adjusting the brightness by
3910  * the value @p brightness_value. The color modifier is modified not set, so
3911  * calling this repeatedly has cumulative effects. brightness values
3912  * of 0 do not affect anything. -1.0 will make things completely black
3913  * and 1.0 will make things all white. Values in-between vary
3914  * brightness linearly.
3915  **/
3916 EAPI void
imlib_modify_color_modifier_brightness(double brightness_value)3917 imlib_modify_color_modifier_brightness(double brightness_value)
3918 {
3919    CHECK_CONTEXT(ctx);
3920    CHECK_PARAM_POINTER("imlib_modify_color_modifier_brightness",
3921                        "color_modifier", ctx->color_modifier);
3922    __imlib_CmodModBrightness((ImlibColorModifier *) ctx->color_modifier,
3923                              brightness_value);
3924 }
3925 
3926 /**
3927  * @param contrast_value Value of contrast.
3928  *
3929  * Modifies the current color modifier by adjusting the contrast by
3930  * the value @p contrast_value. The color modifier is modified not set, so
3931  * calling this repeatedly has cumulative effects. Contrast of 1.0 does
3932  * nothing. 0.0 will merge to gray, 2.0 will double contrast etc.
3933  **/
3934 EAPI void
imlib_modify_color_modifier_contrast(double contrast_value)3935 imlib_modify_color_modifier_contrast(double contrast_value)
3936 {
3937    CHECK_CONTEXT(ctx);
3938    CHECK_PARAM_POINTER("imlib_modify_color_modifier_contrast",
3939                        "color_modifier", ctx->color_modifier);
3940    __imlib_CmodModContrast((ImlibColorModifier *) ctx->color_modifier,
3941                            contrast_value);
3942 }
3943 
3944 /**
3945  * @param red_table An array of #DATA8.
3946  * @param green_table An array of #DATA8.
3947  * @param blue_table An array of #DATA8.
3948  * @param alpha_table An array of #DATA8.
3949  *
3950  * Explicitly copies the mapping tables from the table pointers passed
3951  * into this function into those of the current color modifier. Tables
3952  * are 256 entry arrays of DATA8 which are a mapping of that channel
3953  * value to a new channel value. A normal mapping would be linear (v[0]
3954  * = 0, v[10] = 10, v[50] = 50, v[200] = 200, v[255] = 255).
3955  **/
3956 EAPI void
imlib_set_color_modifier_tables(DATA8 * red_table,DATA8 * green_table,DATA8 * blue_table,DATA8 * alpha_table)3957 imlib_set_color_modifier_tables(DATA8 * red_table, DATA8 * green_table,
3958                                 DATA8 * blue_table, DATA8 * alpha_table)
3959 {
3960    CHECK_CONTEXT(ctx);
3961    CHECK_PARAM_POINTER("imlib_set_color_modifier_tables", "color_modifier",
3962                        ctx->color_modifier);
3963    __imlib_CmodSetTables((ImlibColorModifier *) ctx->color_modifier,
3964                          red_table, green_table, blue_table, alpha_table);
3965 }
3966 
3967 /**
3968  * @param red_table: an array of #DATA8.
3969  * @param green_table: an array of #DATA8.
3970  * @param blue_table: an array of #DATA8.
3971  * @param alpha_table: an array of #DATA8.
3972  *
3973  * Copies the table values from the current color modifier into the
3974  * pointers to mapping tables specified. They must have 256 entries and
3975  * be DATA8 format.
3976  **/
3977 EAPI void
imlib_get_color_modifier_tables(DATA8 * red_table,DATA8 * green_table,DATA8 * blue_table,DATA8 * alpha_table)3978 imlib_get_color_modifier_tables(DATA8 * red_table, DATA8 * green_table,
3979                                 DATA8 * blue_table, DATA8 * alpha_table)
3980 {
3981    CHECK_CONTEXT(ctx);
3982    CHECK_PARAM_POINTER("imlib_get_color_modifier_tables", "color_modifier",
3983                        ctx->color_modifier);
3984    __imlib_CmodGetTables((ImlibColorModifier *) ctx->color_modifier,
3985                          red_table, green_table, blue_table, alpha_table);
3986 }
3987 
3988 /**
3989  * Resets the current color modifier to have linear mapping tables.
3990  **/
3991 EAPI void
imlib_reset_color_modifier(void)3992 imlib_reset_color_modifier(void)
3993 {
3994    CHECK_CONTEXT(ctx);
3995    CHECK_PARAM_POINTER("imlib_rset_color_modifier", "color_modifier",
3996                        ctx->color_modifier);
3997    __imlib_CmodReset((ImlibColorModifier *) ctx->color_modifier);
3998 }
3999 
4000 /**
4001  * Uses the current color modifier and modifies the current image using
4002  * the mapping tables in the current color modifier.
4003  **/
4004 EAPI void
imlib_apply_color_modifier(void)4005 imlib_apply_color_modifier(void)
4006 {
4007    ImlibImage         *im;
4008 
4009    CHECK_CONTEXT(ctx);
4010    CHECK_PARAM_POINTER("imlib_apply_color_modifier", "image", ctx->image);
4011    CHECK_PARAM_POINTER("imlib_apply_color_modifier", "color_modifier",
4012                        ctx->color_modifier);
4013    CAST_IMAGE(im, ctx->image);
4014    if (__imlib_LoadImageData(im))
4015       return;
4016    __imlib_DirtyImage(im);
4017    __imlib_DataCmodApply(im->data, im->w, im->h, 0, &(im->flags),
4018                          (ImlibColorModifier *) ctx->color_modifier);
4019 }
4020 
4021 /**
4022  * @param x The x coordinate of the left edge of the rectangle.
4023  * @param y  The y coordinate of the top edge of the rectangle.
4024  * @param width  The width of the rectangle.
4025  * @param height  The height of the rectangle.
4026  *
4027  * Works the same way as imlib_apply_color_modifier() but only modifies
4028  * a selected rectangle in the current image.
4029  **/
4030 EAPI void
imlib_apply_color_modifier_to_rectangle(int x,int y,int width,int height)4031 imlib_apply_color_modifier_to_rectangle(int x, int y, int width, int height)
4032 {
4033    ImlibImage         *im;
4034 
4035    CHECK_CONTEXT(ctx);
4036    CHECK_PARAM_POINTER("imlib_apply_color_modifier_to_rectangle", "image",
4037                        ctx->image);
4038    CHECK_PARAM_POINTER("imlib_apply_color_modifier_to_rectangle",
4039                        "color_modifier", ctx->color_modifier);
4040    CAST_IMAGE(im, ctx->image);
4041    if (x < 0)
4042      {
4043         width += x;
4044         x = 0;
4045      }
4046    if (width <= 0)
4047       return;
4048    if ((x + width) > im->w)
4049       width = (im->w - x);
4050    if (width <= 0)
4051       return;
4052    if (y < 0)
4053      {
4054         height += y;
4055         y = 0;
4056      }
4057    if (height <= 0)
4058       return;
4059    if ((y + height) > im->h)
4060       height = (im->h - y);
4061    if (height <= 0)
4062       return;
4063    if (__imlib_LoadImageData(im))
4064       return;
4065    __imlib_DirtyImage(im);
4066    __imlib_DataCmodApply(im->data + (y * im->w) + x, width, height,
4067                          im->w - width, &(im->flags),
4068                          (ImlibColorModifier *) ctx->color_modifier);
4069 }
4070 
4071 EAPI                Imlib_Updates
imlib_image_draw_pixel(int x,int y,char make_updates)4072 imlib_image_draw_pixel(int x, int y, char make_updates)
4073 {
4074    ImlibImage         *im;
4075 
4076    CHECK_CONTEXT(ctx);
4077    CHECK_PARAM_POINTER_RETURN("imlib_image_draw_pixel", "image", ctx->image,
4078                               NULL);
4079    CAST_IMAGE(im, ctx->image);
4080    if (__imlib_LoadImageData(im))
4081       return NULL;
4082    __imlib_DirtyImage(im);
4083    return (Imlib_Updates) __imlib_Point_DrawToImage(x, y, ctx->pixel, im,
4084                                                     ctx->cliprect.x,
4085                                                     ctx->cliprect.y,
4086                                                     ctx->cliprect.w,
4087                                                     ctx->cliprect.h,
4088                                                     ctx->operation, ctx->blend,
4089                                                     make_updates);
4090 }
4091 
4092 /**
4093  * @param x1 The x coordinate of the first point.
4094  * @param y1 The y coordinate of the first point.
4095  * @param x2 The x coordinate of the second point.
4096  * @param y2 The y coordinate of the second point.
4097  * @param make_updates: a char.
4098  * @return An updates list.
4099  *
4100  * Draws a line using the current color on the current image from
4101  * coordinates (@p x1, @p y1) to (@p x2, @p y2). If @p make_updates is 1 it will also
4102  * return an update you can use for an updates list, otherwise it
4103  * returns NULL.
4104  *
4105  **/
4106 EAPI                Imlib_Updates
imlib_image_draw_line(int x1,int y1,int x2,int y2,char make_updates)4107 imlib_image_draw_line(int x1, int y1, int x2, int y2, char make_updates)
4108 {
4109    ImlibImage         *im;
4110 
4111    CHECK_CONTEXT(ctx);
4112    CHECK_PARAM_POINTER_RETURN("imlib_image_draw_line", "image", ctx->image,
4113                               NULL);
4114    CAST_IMAGE(im, ctx->image);
4115    if (__imlib_LoadImageData(im))
4116       return NULL;
4117    __imlib_DirtyImage(im);
4118    return (Imlib_Updates) __imlib_Line_DrawToImage(x1, y1, x2, y2, ctx->pixel,
4119                                                    im, ctx->cliprect.x,
4120                                                    ctx->cliprect.y,
4121                                                    ctx->cliprect.w,
4122                                                    ctx->cliprect.h,
4123                                                    ctx->operation, ctx->blend,
4124                                                    ctx->anti_alias,
4125                                                    make_updates);
4126 }
4127 
4128 /**
4129  * @param x The top left x coordinate of the rectangle.
4130  * @param y The top left y coordinate of the rectangle.
4131  * @param width The width of the rectangle.
4132  * @param height The height of the rectangle.
4133  *
4134  * Draws the outline of a rectangle on the current image at the (@p x,
4135  * @p y)
4136  * coordinates with a size of @p width and @p height pixels, using the
4137  * current color.
4138  **/
4139 EAPI void
imlib_image_draw_rectangle(int x,int y,int width,int height)4140 imlib_image_draw_rectangle(int x, int y, int width, int height)
4141 {
4142    ImlibImage         *im;
4143 
4144    CHECK_CONTEXT(ctx);
4145    CHECK_PARAM_POINTER("imlib_image_draw_rectangle", "image", ctx->image);
4146    CAST_IMAGE(im, ctx->image);
4147    if (__imlib_LoadImageData(im))
4148       return;
4149    __imlib_DirtyImage(im);
4150    __imlib_Rectangle_DrawToImage(x, y, width, height, ctx->pixel,
4151                                  im, ctx->cliprect.x, ctx->cliprect.y,
4152                                  ctx->cliprect.w, ctx->cliprect.h,
4153                                  ctx->operation, ctx->blend);
4154 }
4155 
4156 /**
4157  * @param x The top left x coordinate of the rectangle.
4158  * @param y The top left y coordinate of the rectangle.
4159  * @param width The width of the rectangle.
4160  * @param height The height of the rectangle.
4161  *
4162  * Draws a filled rectangle on the current image at the (@p x, @p y)
4163  * coordinates with a size of @p width and @p height pixels, using the
4164  * current color.
4165  **/
4166 EAPI void
imlib_image_fill_rectangle(int x,int y,int width,int height)4167 imlib_image_fill_rectangle(int x, int y, int width, int height)
4168 {
4169    ImlibImage         *im;
4170 
4171    CHECK_CONTEXT(ctx);
4172    CHECK_PARAM_POINTER("imlib_image_fill_rectangle", "image", ctx->image);
4173    CAST_IMAGE(im, ctx->image);
4174    if (__imlib_LoadImageData(im))
4175       return;
4176    __imlib_DirtyImage(im);
4177    __imlib_Rectangle_FillToImage(x, y, width, height, ctx->pixel,
4178                                  im, ctx->cliprect.x, ctx->cliprect.y,
4179                                  ctx->cliprect.w, ctx->cliprect.h,
4180                                  ctx->operation, ctx->blend);
4181 }
4182 
4183 /**
4184  * @param image_source An image.
4185  * @param x The x coordinate.
4186  * @param y The y coordinate.
4187  *
4188  * Copies the alpha channel of the source image @p image_source to the
4189  * (@p x, @p y) coordinates
4190  * of the current image, replacing the alpha channel there.
4191  **/
4192 EAPI void
imlib_image_copy_alpha_to_image(Imlib_Image image_source,int x,int y)4193 imlib_image_copy_alpha_to_image(Imlib_Image image_source, int x, int y)
4194 {
4195    ImlibImage         *im, *im2;
4196 
4197    CHECK_CONTEXT(ctx);
4198    CHECK_PARAM_POINTER("imlib_image_copy_alpha_to_image", "image_source",
4199                        image_source);
4200    CHECK_PARAM_POINTER("imlib_image_copy_alpha_to_image", "image_destination",
4201                        ctx->image);
4202    CAST_IMAGE(im, image_source);
4203    CAST_IMAGE(im2, ctx->image);
4204    if (__imlib_LoadImageData(im))
4205       return;
4206    if (__imlib_LoadImageData(im2))
4207       return;
4208    __imlib_DirtyImage(im);
4209    __imlib_copy_alpha_data(im, im2, 0, 0, im->w, im->h, x, y);
4210 }
4211 
4212 /**
4213  * @param image_source An image.
4214  * @param x The top left x coordinate of the rectangle.
4215  * @param y The top left y coordinate of the rectangle.
4216  * @param width The width of the rectangle.
4217  * @param height The height of the rectangle.
4218  * @param destination_x The top left x coordinate of the destination rectangle.
4219  * @param destination_y The top left x coordinate of the destination rectangle.
4220  *
4221  * Copies the source (@p x, @p y, @p width, @p height) rectangle alpha channel from
4222  * the source image @p image_source and replaces the alpha channel on the destination
4223  * image at the (@p destination_x, @p destination_y) coordinates.
4224  **/
4225 EAPI void
imlib_image_copy_alpha_rectangle_to_image(Imlib_Image image_source,int x,int y,int width,int height,int destination_x,int destination_y)4226 imlib_image_copy_alpha_rectangle_to_image(Imlib_Image image_source, int x,
4227                                           int y, int width, int height,
4228                                           int destination_x, int destination_y)
4229 {
4230    ImlibImage         *im, *im2;
4231 
4232    CHECK_CONTEXT(ctx);
4233    CHECK_PARAM_POINTER("imlib_image_copy_alpha_rectangle_to_image",
4234                        "image_source", image_source);
4235    CHECK_PARAM_POINTER("imlib_image_copy_alpha_rectangle_to_image",
4236                        "image_destination", ctx->image);
4237    CAST_IMAGE(im, image_source);
4238    CAST_IMAGE(im2, ctx->image);
4239    if (__imlib_LoadImageData(im))
4240       return;
4241    if (__imlib_LoadImageData(im2))
4242       return;
4243    __imlib_DirtyImage(im);
4244    __imlib_copy_alpha_data(im, im2, x, y, width, height, destination_x,
4245                            destination_y);
4246 }
4247 
4248 /**
4249  * @param x The top left x coordinate of the rectangle.
4250  * @param y The top left y coordinate of the rectangle.
4251  * @param width The width of the rectangle.
4252  * @param height The height of the rectangle.
4253  * @param delta_x Distance along the x coordinates.
4254  * @param delta_y Distance along the y coordinates.
4255  *
4256  * Scrolls a rectangle of size @p width, @p height at the (@p x, @p y)
4257  * location within the current image
4258  * by the @p delta_x, @p delta_y distance (in pixels).
4259  **/
4260 EAPI void
imlib_image_scroll_rect(int x,int y,int width,int height,int delta_x,int delta_y)4261 imlib_image_scroll_rect(int x, int y, int width, int height, int delta_x,
4262                         int delta_y)
4263 {
4264    ImlibImage         *im;
4265    int                 xx, yy, w, h, nx, ny;
4266 
4267    CHECK_CONTEXT(ctx);
4268    CHECK_PARAM_POINTER("imlib_image_scroll_rect", "image", ctx->image);
4269    CAST_IMAGE(im, ctx->image);
4270    if (__imlib_LoadImageData(im))
4271       return;
4272    if (delta_x > 0)
4273      {
4274         xx = x;
4275         nx = x + delta_x;
4276         w = width - delta_x;
4277      }
4278    else
4279      {
4280         xx = x - delta_x;
4281         nx = x;
4282         w = width + delta_x;
4283      }
4284    if (delta_y > 0)
4285      {
4286         yy = y;
4287         ny = y + delta_y;
4288         h = height - delta_y;
4289      }
4290    else
4291      {
4292         yy = y - delta_y;
4293         ny = y;
4294         h = height + delta_y;
4295      }
4296    __imlib_DirtyImage(im);
4297    __imlib_copy_image_data(im, xx, yy, w, h, nx, ny);
4298 }
4299 
4300 /**
4301  * @param x The top left x coordinate of the rectangle.
4302  * @param y The top left y coordinate of the rectangle.
4303  * @param width The width of the rectangle.
4304  * @param height The height of the rectangle.
4305  * @param new_x The top left x coordinate of the new location.
4306  * @param new_y The top left y coordinate of the new location.
4307  *
4308  * Copies a rectangle of size @p width, @p height at the (@p x, @p y) location
4309  * specified in the current image to a new location (@p new_x, @p new_y) in the same
4310  * image.
4311  **/
4312 EAPI void
imlib_image_copy_rect(int x,int y,int width,int height,int new_x,int new_y)4313 imlib_image_copy_rect(int x, int y, int width, int height, int new_x, int new_y)
4314 {
4315    ImlibImage         *im;
4316 
4317    CHECK_CONTEXT(ctx);
4318    CHECK_PARAM_POINTER("imlib_image_copy_rect", "image", ctx->image);
4319    CAST_IMAGE(im, ctx->image);
4320    if (__imlib_LoadImageData(im))
4321       return;
4322    __imlib_DirtyImage(im);
4323    __imlib_copy_image_data(im, x, y, width, height, new_x, new_y);
4324 }
4325 
4326 /**
4327  * @return valid handle.
4328  *
4329  * Creates a new empty color range and returns a valid handle to that
4330  * color range.
4331  **/
4332 EAPI                Imlib_Color_Range
imlib_create_color_range(void)4333 imlib_create_color_range(void)
4334 {
4335    CHECK_CONTEXT(ctx);
4336    return (Imlib_Color_Range) __imlib_CreateRange();
4337 }
4338 
4339 /**
4340  * Frees the current color range.
4341  **/
4342 EAPI void
imlib_free_color_range(void)4343 imlib_free_color_range(void)
4344 {
4345    CHECK_CONTEXT(ctx);
4346    CHECK_PARAM_POINTER("imlib_free_color_range", "color_range",
4347                        ctx->color_range);
4348    __imlib_FreeRange((ImlibRange *) ctx->color_range);
4349    ctx->color_range = NULL;
4350 }
4351 
4352 /**
4353  * @param distance_away Distance from the previous color.
4354  *
4355  * Adds the current color to the current color range at a @p distance_away
4356  * distance from the previous color in the range (if it's the first
4357  * color in the range this is irrelevant).
4358  **/
4359 EAPI void
imlib_add_color_to_color_range(int distance_away)4360 imlib_add_color_to_color_range(int distance_away)
4361 {
4362    CHECK_CONTEXT(ctx);
4363    CHECK_PARAM_POINTER("imlib_add_color_to_color_range", "color_range",
4364                        ctx->color_range);
4365    __imlib_AddRangeColor((ImlibRange *) ctx->color_range, ctx->color.red,
4366                          ctx->color.green, ctx->color.blue, ctx->color.alpha,
4367                          distance_away);
4368 }
4369 
4370 /**
4371  * @param x The x coordinate of the left edge of the rectangle.
4372  * @param y The y coordinate of the top edge of the rectangle.
4373  * @param width The width of the rectangle.
4374  * @param height The height of the rectangle.
4375  * @param angle Angle of gradient.
4376  *
4377  * Fills a rectangle of width @p width and height @p height at the (@p x, @p y) location
4378  * specified in the current image with a linear gradient of the
4379  * current color range at an angle of @p angle degrees with 0 degrees
4380  * being vertical from top to bottom going clockwise from there.
4381  **/
4382 EAPI void
imlib_image_fill_color_range_rectangle(int x,int y,int width,int height,double angle)4383 imlib_image_fill_color_range_rectangle(int x, int y, int width, int height,
4384                                        double angle)
4385 {
4386    ImlibImage         *im;
4387 
4388    CHECK_CONTEXT(ctx);
4389    CHECK_PARAM_POINTER("imlib_image_fill_color_range_rectangle", "image",
4390                        ctx->image);
4391    CHECK_PARAM_POINTER("imlib_image_fill_color_range_rectangle",
4392                        "color_range", ctx->color_range);
4393    CAST_IMAGE(im, ctx->image);
4394    if (__imlib_LoadImageData(im))
4395       return;
4396    __imlib_DirtyImage(im);
4397    __imlib_DrawGradient(im, x, y, width, height,
4398                         (ImlibRange *) ctx->color_range, angle,
4399                         ctx->operation,
4400                         ctx->cliprect.x, ctx->cliprect.y,
4401                         ctx->cliprect.w, ctx->cliprect.h);
4402 }
4403 
4404 /**
4405  * @param x The x coordinate of the left edge of the rectangle.
4406  * @param y The y coordinate of the top edge of the rectangle.
4407  * @param width The width of the rectangle.
4408  * @param height The height of the rectangle.
4409  * @param angle Angle of gradient.
4410  *
4411  * Fills a rectangle of width @p width and height @p height at the (@p
4412  * x, @p y) location
4413  * specified in the current image with a linear gradient in HSVA color
4414  * space of the current color range at an angle of @p angle degrees with
4415  * 0 degrees being vertical from top to bottom going clockwise from
4416  * there.
4417  **/
4418 EAPI void
imlib_image_fill_hsva_color_range_rectangle(int x,int y,int width,int height,double angle)4419 imlib_image_fill_hsva_color_range_rectangle(int x, int y, int width, int height,
4420                                             double angle)
4421 {
4422    ImlibImage         *im;
4423 
4424    CHECK_CONTEXT(ctx);
4425    CHECK_PARAM_POINTER("imlib_image_fill_color_range_rectangle", "image",
4426                        ctx->image);
4427    CHECK_PARAM_POINTER("imlib_image_fill_color_range_rectangle",
4428                        "color_range", ctx->color_range);
4429    CAST_IMAGE(im, ctx->image);
4430    if (__imlib_LoadImageData(im))
4431       return;
4432    __imlib_DirtyImage(im);
4433    __imlib_DrawHsvaGradient(im, x, y, width, height,
4434                             (ImlibRange *) ctx->color_range, angle,
4435                             ctx->operation,
4436                             ctx->cliprect.x, ctx->cliprect.y,
4437                             ctx->cliprect.w, ctx->cliprect.h);
4438 }
4439 
4440 /**
4441  * @param x The x coordinate of the pixel.
4442  * @param y The y coordinate of the pixel.
4443  * @param color_return The returned color.
4444  *
4445  * Fills the @p color_return color structure with the color of the pixel
4446  * in the current image that is at the (@p x, @p y) location specified.
4447  **/
4448 EAPI void
imlib_image_query_pixel(int x,int y,Imlib_Color * color_return)4449 imlib_image_query_pixel(int x, int y, Imlib_Color * color_return)
4450 {
4451    ImlibImage         *im;
4452    DATA32             *p;
4453 
4454    CHECK_CONTEXT(ctx);
4455    CHECK_PARAM_POINTER("imlib_image_query_pixel", "image", ctx->image);
4456    CHECK_PARAM_POINTER("imlib_image_query_pixel", "color_return", color_return);
4457    CAST_IMAGE(im, ctx->image);
4458    if (__imlib_LoadImageData(im))
4459       return;
4460    if ((x < 0) || (x >= im->w) || (y < 0) || (y >= im->h))
4461      {
4462         color_return->red = 0;
4463         color_return->green = 0;
4464         color_return->blue = 0;
4465         color_return->alpha = 0;
4466         return;
4467      }
4468    p = im->data + (im->w * y) + x;
4469    color_return->red = ((*p) >> 16) & 0xff;
4470    color_return->green = ((*p) >> 8) & 0xff;
4471    color_return->blue = (*p) & 0xff;
4472    color_return->alpha = ((*p) >> 24) & 0xff;
4473 }
4474 
4475 /**
4476  * @param x The x coordinate of the pixel.
4477  * @param y The y coordinate of the pixel.
4478  * @param hue The returned hue channel.
4479  * @param saturation The returned saturation channel.
4480  * @param value The returned value channel.
4481  * @param alpha The returned alpha channel.
4482  *
4483  * Gets the HSVA color of the pixel from the current image that is at
4484  * the (@p x, @p y) location specified.
4485  **/
4486 EAPI void
imlib_image_query_pixel_hsva(int x,int y,float * hue,float * saturation,float * value,int * alpha)4487 imlib_image_query_pixel_hsva(int x, int y, float *hue, float *saturation,
4488                              float *value, int *alpha)
4489 {
4490    ImlibImage         *im;
4491    DATA32             *p;
4492    int                 r, g, b;
4493 
4494    CHECK_CONTEXT(ctx);
4495    CHECK_PARAM_POINTER("imlib_image_query_pixel", "image", ctx->image);
4496    CAST_IMAGE(im, ctx->image);
4497    if (__imlib_LoadImageData(im))
4498       return;
4499    if ((x < 0) || (x >= im->w) || (y < 0) || (y >= im->h))
4500      {
4501         *hue = 0;
4502         *saturation = 0;
4503         *value = 0;
4504         *alpha = 0;
4505         return;
4506      }
4507    p = im->data + (im->w * y) + x;
4508    r = ((*p) >> 16) & 0xff;
4509    g = ((*p) >> 8) & 0xff;
4510    b = (*p) & 0xff;
4511    *alpha = ((*p) >> 24) & 0xff;
4512 
4513    __imlib_rgb_to_hsv(r, g, b, hue, saturation, value);
4514 }
4515 
4516 /**
4517  * @param x The x coordinate of the pixel.
4518  * @param y The y coordinate of the pixel.
4519  * @param hue The returned hue channel.
4520  * @param lightness The returned lightness channel.
4521  * @param saturation The returned saturation channel.
4522  * @param alpha The returned alpha channel.
4523  *
4524  * Gets the HLSA color of the pixel from the current image that is at
4525  * the (@p x, @p y) location specified.
4526  **/
4527 EAPI void
imlib_image_query_pixel_hlsa(int x,int y,float * hue,float * lightness,float * saturation,int * alpha)4528 imlib_image_query_pixel_hlsa(int x, int y, float *hue, float *lightness,
4529                              float *saturation, int *alpha)
4530 {
4531    ImlibImage         *im;
4532    DATA32             *p;
4533    int                 r, g, b;
4534 
4535    CHECK_CONTEXT(ctx);
4536    CHECK_PARAM_POINTER("imlib_image_query_pixel", "image", ctx->image);
4537    CAST_IMAGE(im, ctx->image);
4538    if (__imlib_LoadImageData(im))
4539       return;
4540    if ((x < 0) || (x >= im->w) || (y < 0) || (y >= im->h))
4541      {
4542         *hue = 0;
4543         *lightness = 0;
4544         *saturation = 0;
4545         *alpha = 0;
4546         return;
4547      }
4548    p = im->data + (im->w * y) + x;
4549    r = ((*p) >> 16) & 0xff;
4550    g = ((*p) >> 8) & 0xff;
4551    b = (*p) & 0xff;
4552    *alpha = ((*p) >> 24) & 0xff;
4553 
4554    __imlib_rgb_to_hls(r, g, b, hue, lightness, saturation);
4555 }
4556 
4557 /**
4558  * @param x Tthe x coordinate of the pixel.
4559  * @param y The y coordinate of the pixel.
4560  * @param cyan The returned cyan channel.
4561  * @param magenta The returned magenta channel.
4562  * @param yellow The returned yellow channel.
4563  * @param alpha The returned alpha channel.
4564  *
4565  * Gets the CMYA color of the pixel from the current image that is at
4566  * the (@p x, @p y) location specified.
4567  *
4568  **/
4569 EAPI void
imlib_image_query_pixel_cmya(int x,int y,int * cyan,int * magenta,int * yellow,int * alpha)4570 imlib_image_query_pixel_cmya(int x, int y, int *cyan, int *magenta, int *yellow,
4571                              int *alpha)
4572 {
4573    ImlibImage         *im;
4574    DATA32             *p;
4575 
4576    CHECK_CONTEXT(ctx);
4577    CHECK_PARAM_POINTER("imlib_image_query_pixel", "image", ctx->image);
4578    CAST_IMAGE(im, ctx->image);
4579    if (__imlib_LoadImageData(im))
4580       return;
4581    if ((x < 0) || (x >= im->w) || (y < 0) || (y >= im->h))
4582      {
4583         *cyan = 0;
4584         *magenta = 0;
4585         *yellow = 0;
4586         *alpha = 0;
4587         return;
4588      }
4589    p = im->data + (im->w * y) + x;
4590    *cyan = 255 - (((*p) >> 16) & 0xff);
4591    *magenta = 255 - (((*p) >> 8) & 0xff);
4592    *yellow = 255 - ((*p) & 0xff);
4593    *alpha = ((*p) >> 24) & 0xff;
4594 }
4595 
4596 /**
4597  * @param key A string.
4598  * @param data A pointer.
4599  * @param value A value.
4600  * @param destructor_function An Imlib internal function.
4601  *
4602  * Attaches data to the current image with the string key of @p key, and
4603  * the data of @p data and an integer of @p value. The
4604  * @p destructor_function function, if not NULL is called when this
4605  * image is freed so the destructor can free @p data, if this is needed.
4606  **/
4607 EAPI void
imlib_image_attach_data_value(const char * key,void * data,int value,Imlib_Internal_Data_Destructor_Function destructor_function)4608 imlib_image_attach_data_value(const char *key, void *data, int value,
4609                               Imlib_Internal_Data_Destructor_Function
4610                               destructor_function)
4611 {
4612    ImlibImage         *im;
4613 
4614    CHECK_CONTEXT(ctx);
4615    CHECK_PARAM_POINTER("imlib_image_attach_data_value", "image", ctx->image);
4616    CHECK_PARAM_POINTER("imlib_image_attach_data_value", "key", key);
4617    CAST_IMAGE(im, ctx->image);
4618    __imlib_AttachTag(im, key, value, data,
4619                      (ImlibDataDestructorFunction) destructor_function);
4620 }
4621 
4622 /**
4623  * @param key A string.
4624  * @return The attached data as a pointer, or NULL if none.
4625  *
4626  * Gets the data attached to the current image with the key @p key
4627  * specified. NULL is returned if no data could be found with that key
4628  * on the current image.
4629  *
4630  **/
4631 EAPI void          *
imlib_image_get_attached_data(const char * key)4632 imlib_image_get_attached_data(const char *key)
4633 {
4634    ImlibImageTag      *t;
4635    ImlibImage         *im;
4636 
4637    CHECK_CONTEXT(ctx);
4638    CHECK_PARAM_POINTER_RETURN("imlib_image_get_attached_data", "image",
4639                               ctx->image, NULL);
4640    CHECK_PARAM_POINTER_RETURN("imlib_image_get_attached_data", "key", key,
4641                               NULL);
4642    CAST_IMAGE(im, ctx->image);
4643    t = __imlib_GetTag(im, key);
4644    if (t)
4645       return t->data;
4646    return NULL;
4647 }
4648 
4649 /**
4650  * @param key A string.
4651  * @return The attached value as an integer, or 0 if none.
4652  *
4653  * Returns the value attached to the current image with the specified
4654  * key @p key. If none could be found 0 is returned.
4655  *
4656  **/
4657 EAPI int
imlib_image_get_attached_value(const char * key)4658 imlib_image_get_attached_value(const char *key)
4659 {
4660    ImlibImageTag      *t;
4661    ImlibImage         *im;
4662 
4663    CHECK_CONTEXT(ctx);
4664    CHECK_PARAM_POINTER_RETURN("imlib_image_get_attached_value", "image",
4665                               ctx->image, 0);
4666    CHECK_PARAM_POINTER_RETURN("imlib_image_get_attached_value", "key", key, 0);
4667    CAST_IMAGE(im, ctx->image);
4668    t = __imlib_GetTag(im, key);
4669    if (t)
4670       return t->val;
4671    return 0;
4672 }
4673 
4674 /**
4675  * @param key A string.
4676  *
4677  * Detaches the data & value attached with the specified key @p key from the
4678  * current image.
4679  **/
4680 EAPI void
imlib_image_remove_attached_data_value(const char * key)4681 imlib_image_remove_attached_data_value(const char *key)
4682 {
4683    ImlibImage         *im;
4684 
4685    CHECK_CONTEXT(ctx);
4686    CHECK_PARAM_POINTER("imlib_image_remove_attached_data_value", "image",
4687                        ctx->image);
4688    CHECK_PARAM_POINTER("imlib_image_remove_attached_data_value", "key", key);
4689    CAST_IMAGE(im, ctx->image);
4690    __imlib_RemoveTag(im, key);
4691 }
4692 
4693 /**
4694  * @param key A string.
4695  *
4696  * Removes the data and value attached to the current image with the
4697  * specified key @p key and also calls the destructor function that was
4698  * supplied when attaching it (see imlib_image_attach_data_value()).
4699  **/
4700 EAPI void
imlib_image_remove_and_free_attached_data_value(const char * key)4701 imlib_image_remove_and_free_attached_data_value(const char *key)
4702 {
4703    ImlibImageTag      *t;
4704    ImlibImage         *im;
4705 
4706    CHECK_CONTEXT(ctx);
4707    CHECK_PARAM_POINTER("imlib_image_remove_and_free_attached_data_value",
4708                        "image", ctx->image);
4709    CHECK_PARAM_POINTER("imlib_image_remove_and_free_attached_data_value",
4710                        "key", key);
4711    CAST_IMAGE(im, ctx->image);
4712    t = __imlib_RemoveTag(im, key);
4713    __imlib_FreeTag(im, t);
4714 }
4715 
4716 /**
4717  * @param filename The file name.
4718  *
4719  * Saves the current image in the format specified by the current
4720  * image's format settings to the filename @p filename.
4721  **/
4722 EAPI void
imlib_save_image(const char * filename)4723 imlib_save_image(const char *filename)
4724 {
4725    ImlibImage         *im;
4726    Imlib_Image         prev_ctxt_image;
4727 
4728    CHECK_CONTEXT(ctx);
4729    CHECK_PARAM_POINTER("imlib_save_image", "image", ctx->image);
4730    CHECK_PARAM_POINTER("imlib_save_image", "filename", filename);
4731    CAST_IMAGE(im, ctx->image);
4732    if (__imlib_LoadImageData(im))
4733       return;
4734    prev_ctxt_image = ctx->image;
4735    __imlib_SaveImage(im, filename, (ImlibProgressFunction) ctx->progress_func,
4736                      ctx->progress_granularity, NULL);
4737    ctx->image = prev_ctxt_image;
4738 }
4739 
4740 /**
4741  * @param filename The file name.
4742  * @param error_return The returned error.
4743  *
4744  * Works the same way imlib_save_image() works, but will set the
4745  * @p error_return to an error value if the save fails.
4746  **/
4747 EAPI void
imlib_save_image_with_error_return(const char * filename,Imlib_Load_Error * error_return)4748 imlib_save_image_with_error_return(const char *filename,
4749                                    Imlib_Load_Error * error_return)
4750 {
4751    ImlibImage         *im;
4752    Imlib_Image         prev_ctxt_image;
4753 
4754    CHECK_CONTEXT(ctx);
4755    CHECK_PARAM_POINTER("imlib_save_image_with_error_return", "image",
4756                        ctx->image);
4757    CHECK_PARAM_POINTER("imlib_save_image_with_error_return", "filename",
4758                        filename);
4759    CHECK_PARAM_POINTER("imlib_save_image_with_error_return", "error_return",
4760                        error_return);
4761    CAST_IMAGE(im, ctx->image);
4762    if (__imlib_LoadImageData(im))
4763       return;
4764    prev_ctxt_image = ctx->image;
4765    __imlib_SaveImage(im, filename, (ImlibProgressFunction) ctx->progress_func,
4766                      ctx->progress_granularity, error_return);
4767    ctx->image = prev_ctxt_image;
4768 }
4769 
4770 /**
4771  * @param angle An angle in radians.
4772  * @return A new image, or NULL.
4773  *
4774  * Creates an new copy of the current image, but rotated by @p angle
4775  * radians. On success it returns a valid image handle, otherwise
4776  * NULL.
4777  **/
4778 EAPI                Imlib_Image
imlib_create_rotated_image(double angle)4779 imlib_create_rotated_image(double angle)
4780 {
4781    ImlibImage         *im, *im_old;
4782    int                 x, y, dx, dy, sz;
4783    double              x1, y1, d;
4784 
4785    CHECK_CONTEXT(ctx);
4786    CHECK_PARAM_POINTER_RETURN("imlib_create_rotated_image", "image",
4787                               ctx->image, NULL);
4788    CAST_IMAGE(im_old, ctx->image);
4789    if (__imlib_LoadImageData(im_old))
4790       return NULL;
4791 
4792    d = hypot((double)(im_old->w + 4), (double)(im_old->h + 4)) / sqrt(2.0);
4793 
4794    x1 = (double)(im_old->w) / 2.0 - sin(angle + atan(1.0)) * d;
4795    y1 = (double)(im_old->h) / 2.0 - cos(angle + atan(1.0)) * d;
4796 
4797    sz = (int)(d * sqrt(2.0));
4798    x = (int)(x1 * _ROTATE_PREC_MAX);
4799    y = (int)(y1 * _ROTATE_PREC_MAX);
4800    dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
4801    dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
4802 
4803    if (!IMAGE_DIMENSIONS_OK(sz, sz))
4804       return NULL;
4805 
4806    im = __imlib_CreateImage(sz, sz, NULL);
4807    im->data = calloc(sz * sz, sizeof(DATA32));
4808    if (!(im->data))
4809      {
4810         __imlib_FreeImage(im);
4811         return NULL;
4812      }
4813 
4814    if (ctx->anti_alias)
4815      {
4816 #ifdef DO_MMX_ASM
4817         if (__imlib_get_cpuid() & CPUID_MMX)
4818            __imlib_mmx_RotateAA(im_old->data, im->data, im_old->w, im_old->w,
4819                                 im_old->h, im->w, sz, sz, x, y, dx, dy, -dy,
4820                                 dx);
4821         else
4822 #endif
4823            __imlib_RotateAA(im_old->data, im->data, im_old->w, im_old->w,
4824                             im_old->h, im->w, sz, sz, x, y, dx, dy, -dy, dx);
4825      }
4826    else
4827      {
4828         __imlib_RotateSample(im_old->data, im->data, im_old->w, im_old->w,
4829                              im_old->h, im->w, sz, sz, x, y, dx, dy, -dy, dx);
4830      }
4831    SET_FLAG(im->flags, F_HAS_ALPHA);
4832 
4833    return (Imlib_Image) im;
4834 }
4835 
4836 void
imlib_rotate_image_from_buffer(double angle,Imlib_Image source_image)4837 imlib_rotate_image_from_buffer(double angle, Imlib_Image source_image)
4838 {
4839    ImlibImage         *im, *im_old;
4840    int                 x, y, dx, dy, sz;
4841    double              x1, y1, d;
4842 
4843    CHECK_CONTEXT(ctx);
4844    // source image (to rotate)
4845    CHECK_PARAM_POINTER("imlib_rotate_image_from_buffer", "source_image",
4846                        source_image);
4847    CAST_IMAGE(im_old, source_image);
4848 
4849    // current context image
4850    CHECK_PARAM_POINTER("imlib_rotate_image_from_buffer", "image", ctx->image);
4851    CAST_IMAGE(im, ctx->image);
4852 
4853    if (__imlib_LoadImageData(im_old))
4854       return;
4855 
4856    d = hypot((double)(im_old->w + 4), (double)(im_old->h + 4)) / sqrt(2.0);
4857 
4858    x1 = (double)(im_old->w) / 2.0 - sin(angle + atan(1.0)) * d;
4859    y1 = (double)(im_old->h) / 2.0 - cos(angle + atan(1.0)) * d;
4860 
4861    sz = (int)(d * sqrt(2.0));
4862    x = (int)(x1 * _ROTATE_PREC_MAX);
4863    y = (int)(y1 * _ROTATE_PREC_MAX);
4864    dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
4865    dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
4866 
4867    if ((im->w != im->h) || ((im->w < sz) && (im->h < sz)))
4868       return;                   // If size is wrong
4869    else
4870       sz = im->w;               // update sz with real width
4871 
4872 #if 0                           /* Not necessary 'cause destination is context */
4873    im = __imlib_CreateImage(sz, sz, NULL);
4874    im->data = calloc(sz * sz, sizeof(DATA32));
4875    if (!(im->data))
4876      {
4877         __imlib_FreeImage(im);
4878         return;
4879      }
4880 #endif
4881 
4882    if (ctx->anti_alias)
4883      {
4884 #ifdef DO_MMX_ASM
4885         if (__imlib_get_cpuid() & CPUID_MMX)
4886            __imlib_mmx_RotateAA(im_old->data, im->data, im_old->w, im_old->w,
4887                                 im_old->h, im->w, sz, sz, x, y, dx, dy, -dy,
4888                                 dx);
4889         else
4890 #endif
4891            __imlib_RotateAA(im_old->data, im->data, im_old->w, im_old->w,
4892                             im_old->h, im->w, sz, sz, x, y, dx, dy, -dy, dx);
4893      }
4894    else
4895      {
4896         __imlib_RotateSample(im_old->data, im->data, im_old->w, im_old->w,
4897                              im_old->h, im->w, sz, sz, x, y, dx, dy, -dy, dx);
4898      }
4899    SET_FLAG(im->flags, F_HAS_ALPHA);
4900 
4901    return;
4902 }
4903 
4904 /**
4905  * @param source_image The image source.
4906  * @param merge_alpha A char.
4907  * @param source_x The source x coordinate.
4908  * @param source_y The source y coordinate.
4909  * @param source_width The source width.
4910  * @param source_height The source height.
4911  * @param destination_x The destination x coordinate.
4912  * @param destination_y The destination y coordinate.
4913  * @param angle_x An angle.
4914  * @param angle_y An angle.
4915  *
4916  * Works just like imlib_blend_image_onto_image_skewed() except you
4917  * cannot skew an image (@p v_angle_x and @p v_angle_y are 0).
4918  **/
4919 EAPI void
imlib_blend_image_onto_image_at_angle(Imlib_Image source_image,char merge_alpha,int source_x,int source_y,int source_width,int source_height,int destination_x,int destination_y,int angle_x,int angle_y)4920 imlib_blend_image_onto_image_at_angle(Imlib_Image source_image,
4921                                       char merge_alpha, int source_x,
4922                                       int source_y, int source_width,
4923                                       int source_height, int destination_x,
4924                                       int destination_y, int angle_x,
4925                                       int angle_y)
4926 {
4927    ImlibImage         *im_src, *im_dst;
4928 
4929    CHECK_CONTEXT(ctx);
4930    CHECK_PARAM_POINTER("imlib_blend_image_onto_image_at_angle",
4931                        "source_image", source_image);
4932    CHECK_PARAM_POINTER("imlib_blend_image_onto_image_at_angle", "image",
4933                        ctx->image);
4934    CAST_IMAGE(im_src, source_image);
4935    CAST_IMAGE(im_dst, ctx->image);
4936    if (__imlib_LoadImageData(im_src))
4937       return;
4938    if (__imlib_LoadImageData(im_dst))
4939       return;
4940    __imlib_DirtyImage(im_dst);
4941    __imlib_BlendImageToImageSkewed(im_src, im_dst, ctx->anti_alias,
4942                                    ctx->blend, merge_alpha, source_x,
4943                                    source_y, source_width, source_height,
4944                                    destination_x, destination_y, angle_x,
4945                                    angle_y, 0, 0, ctx->color_modifier,
4946                                    ctx->operation,
4947                                    ctx->cliprect.x, ctx->cliprect.y,
4948                                    ctx->cliprect.w, ctx->cliprect.h);
4949 }
4950 
4951 /**
4952  * @param source_image The source image.
4953  * @param merge_alpha A char
4954  * @param source_x The source x coordinate.
4955  * @param source_y The source y coordinate.
4956  * @param source_width The source width.
4957  * @param source_height The source height.
4958  * @param destination_x The destination x coordinate.
4959  * @param destination_y The destination y coordinate.
4960  * @param h_angle_x An angle.
4961  * @param h_angle_y An angle.
4962  * @param v_angle_x An angle.
4963  * @param v_angle_y An angle.
4964  *
4965  * Blends the source rectangle (@p source_x, @p source_y, @p source_width,
4966  * @p source_height) from the
4967  * @p source_image onto the current image at the destination
4968  * (@p destination_x, @p destination_y)
4969  * location. It will be rotated and scaled so that the upper right
4970  * corner will be positioned @p h_angle_x pixels to the right (or left,
4971  * if negative) and @p h_angle_y pixels down (from (@p destination_x,
4972  * @p destination_y). If
4973  * @p v_angle_x and @p v_angle_y are not 0, the image will also be skewed so
4974  * that the lower left corner will be positioned @p v_angle_x pixels to
4975  * the right and @p v_angle_y pixels down. The at_angle versions simply
4976  * have the @p v_angle_x and @p v_angle_y set to 0 so the rotation doesn't
4977  * get skewed, and the render_..._on_drawable ones seem obvious
4978  * enough; they do the same on a drawable.
4979  *
4980  * Example:
4981  * @code
4982  * imlib_blend_image_onto_image_skewed(..., 0, 0, 100, 0, 0, 100);
4983  * @endcode
4984  * will simply scale the image to be 100x100.
4985  * @code
4986  * imlib_blend_image_onto_image_skewed(..., 0, 0, 0, 100, 100, 0);
4987  * @endcode
4988  * will scale the image to be 100x100, and flip it diagonally.
4989  * @code
4990  * imlib_blend_image_onto_image_skewed(..., 100, 0, 0, 100, -100, 0);
4991  * @endcode
4992  * will scale the image and rotate it 90 degrees clockwise.
4993  * @code
4994  * imlib_blend_image_onto_image_skewed(..., 50, 0, 50, 50, -50, 50);
4995  * @endcode
4996  * will rotate the image 45 degrees clockwise, and will scale it so
4997  * its corners are at (50,0)-(100,50)-(50,100)-(0,50) i.e. it fits
4998  * into the 100x100 square, so it's scaled down to 70.7% (sqrt(2)/2).
4999  * @code
5000  * imlib_blend_image_onto_image_skewed(..., 50, 50, 100 * cos(a), 100 * sin(a), 0);
5001  * @endcode
5002  * will rotate the image `a' degrees, with its upper left corner at (50,50).
5003  **/
5004 EAPI void
imlib_blend_image_onto_image_skewed(Imlib_Image source_image,char merge_alpha,int source_x,int source_y,int source_width,int source_height,int destination_x,int destination_y,int h_angle_x,int h_angle_y,int v_angle_x,int v_angle_y)5005 imlib_blend_image_onto_image_skewed(Imlib_Image source_image,
5006                                     char merge_alpha, int source_x,
5007                                     int source_y, int source_width,
5008                                     int source_height, int destination_x,
5009                                     int destination_y, int h_angle_x,
5010                                     int h_angle_y, int v_angle_x, int v_angle_y)
5011 {
5012    ImlibImage         *im_src, *im_dst;
5013 
5014    CHECK_CONTEXT(ctx);
5015    CHECK_PARAM_POINTER("imlib_blend_image_onto_image_skewed", "source_image",
5016                        source_image);
5017    CHECK_PARAM_POINTER("imlib_blend_image_onto_image_skewed", "image",
5018                        ctx->image);
5019    CAST_IMAGE(im_src, source_image);
5020    CAST_IMAGE(im_dst, ctx->image);
5021    if (__imlib_LoadImageData(im_src))
5022       return;
5023    if (__imlib_LoadImageData(im_dst))
5024       return;
5025    __imlib_DirtyImage(im_dst);
5026    __imlib_BlendImageToImageSkewed(im_src, im_dst, ctx->anti_alias,
5027                                    ctx->blend, merge_alpha, source_x,
5028                                    source_y, source_width, source_height,
5029                                    destination_x, destination_y, h_angle_x,
5030                                    h_angle_y, v_angle_x, v_angle_y,
5031                                    ctx->color_modifier, ctx->operation,
5032                                    ctx->cliprect.x, ctx->cliprect.y,
5033                                    ctx->cliprect.w, ctx->cliprect.h);
5034 }
5035 
5036 #ifdef BUILD_X11
5037 /**
5038  * @param source_x The source x coordinate.
5039  * @param source_y The source y coordinate.
5040  * @param source_width The source width.
5041  * @param source_height The source height.
5042  * @param destination_x The destination x coordinate.
5043  * @param destination_y The destination y coordinate.
5044  * @param h_angle_x An angle.
5045  * @param h_angle_y An angle.
5046  * @param v_angle_x An angle.
5047  * @param v_angle_y An angle.
5048  *
5049  *
5050  * Works just like imlib_blend_image_onto_image_skewed(), except it
5051  * blends the image onto the current drawable instead of the current
5052  * image.
5053  **/
5054 EAPI void
imlib_render_image_on_drawable_skewed(int source_x,int source_y,int source_width,int source_height,int destination_x,int destination_y,int h_angle_x,int h_angle_y,int v_angle_x,int v_angle_y)5055 imlib_render_image_on_drawable_skewed(int source_x, int source_y,
5056                                       int source_width, int source_height,
5057                                       int destination_x, int destination_y,
5058                                       int h_angle_x, int h_angle_y,
5059                                       int v_angle_x, int v_angle_y)
5060 {
5061    ImlibImage         *im;
5062 
5063    CHECK_CONTEXT(ctx);
5064    CHECK_PARAM_POINTER("imlib_render_image_on_drawable_skewed", "image",
5065                        ctx->image);
5066    CAST_IMAGE(im, ctx->image);
5067    if (__imlib_LoadImageData(im))
5068       return;
5069    __imlib_RenderImageSkewed(ctx->display, im, ctx->drawable, ctx->mask,
5070                              ctx->visual, ctx->colormap, ctx->depth, source_x,
5071                              source_y, source_width, source_height,
5072                              destination_x, destination_y, h_angle_x,
5073                              h_angle_y, v_angle_x, v_angle_y, ctx->anti_alias,
5074                              ctx->dither, ctx->blend, ctx->dither_mask,
5075                              ctx->mask_alpha_threshold, ctx->color_modifier,
5076                              ctx->operation);
5077 }
5078 
5079 /**
5080  * @param source_x The source x coordinate.
5081  * @param source_y The source y coordinate.
5082  * @param source_width The source width.
5083  * @param source_height The source height.
5084  * @param destination_x The destination x coordinate.
5085  * @param destination_y The destination y coordinate.
5086  * @param angle_x An angle.
5087  * @param angle_y An angle.
5088  *
5089  *
5090  * Works just like imlib_render_image_on_drawable_skewed() except you
5091  * cannot skew an image (@p v_angle_x and @p v_angle_y are 0).
5092  **/
5093 EAPI void
imlib_render_image_on_drawable_at_angle(int source_x,int source_y,int source_width,int source_height,int destination_x,int destination_y,int angle_x,int angle_y)5094 imlib_render_image_on_drawable_at_angle(int source_x, int source_y,
5095                                         int source_width, int source_height,
5096                                         int destination_x, int destination_y,
5097                                         int angle_x, int angle_y)
5098 {
5099    ImlibImage         *im;
5100 
5101    CHECK_CONTEXT(ctx);
5102    CHECK_PARAM_POINTER("imlib_render_image_on_drawable_at_angle", "image",
5103                        ctx->image);
5104    CAST_IMAGE(im, ctx->image);
5105    if (__imlib_LoadImageData(im))
5106       return;
5107    __imlib_RenderImageSkewed(ctx->display, im, ctx->drawable, ctx->mask,
5108                              ctx->visual, ctx->colormap, ctx->depth, source_x,
5109                              source_y, source_width, source_height,
5110                              destination_x, destination_y, angle_x, angle_y,
5111                              0, 0, ctx->anti_alias, ctx->dither, ctx->blend,
5112                              ctx->dither_mask, ctx->mask_alpha_threshold,
5113                              ctx->color_modifier, ctx->operation);
5114 }
5115 #endif
5116 
5117 EAPI void
imlib_image_filter(void)5118 imlib_image_filter(void)
5119 {
5120    ImlibImage         *im;
5121 
5122    CHECK_CONTEXT(ctx);
5123    CHECK_PARAM_POINTER("imlib_image_filter", "image", ctx->image);
5124    CHECK_PARAM_POINTER("imlib_image_filter", "filter", ctx->filter);
5125    CAST_IMAGE(im, ctx->image);
5126    if (__imlib_LoadImageData(im))
5127       return;
5128    __imlib_DirtyImage(im);
5129    __imlib_FilterImage(im, (ImlibFilter *) ctx->filter);
5130 }
5131 
5132 EAPI                Imlib_Filter
imlib_create_filter(int initsize)5133 imlib_create_filter(int initsize)
5134 {
5135    CHECK_CONTEXT(ctx);
5136    return (Imlib_Filter) __imlib_CreateFilter(initsize);
5137 }
5138 
5139 EAPI void
imlib_free_filter(void)5140 imlib_free_filter(void)
5141 {
5142    CHECK_CONTEXT(ctx);
5143    CHECK_PARAM_POINTER("imlib_free_filter", "filter", ctx->filter);
5144    __imlib_FreeFilter((ImlibFilter *) ctx->filter);
5145    ctx->filter = NULL;
5146 }
5147 
5148 /**
5149  * @param filter Current filter.
5150  *
5151  * Sets the current filter to be used when applying filters to
5152  * images. Set this to NULL to disable filters.
5153  */
5154 EAPI void
imlib_context_set_filter(Imlib_Filter filter)5155 imlib_context_set_filter(Imlib_Filter filter)
5156 {
5157    CHECK_CONTEXT(ctx);
5158    ctx->filter = filter;
5159 }
5160 
5161 /**
5162  * @return
5163  *
5164  * Gets the current context image filter.
5165  */
5166 EAPI                Imlib_Filter
imlib_context_get_filter(void)5167 imlib_context_get_filter(void)
5168 {
5169    CHECK_CONTEXT(ctx);
5170    return ctx->filter;
5171 }
5172 
5173 EAPI void
imlib_filter_set(int xoff,int yoff,int a,int r,int g,int b)5174 imlib_filter_set(int xoff, int yoff, int a, int r, int g, int b)
5175 {
5176    ImlibFilter        *fil;
5177 
5178    CHECK_CONTEXT(ctx);
5179    CHECK_PARAM_POINTER("imlib_filter_set", "filter", ctx->filter);
5180    fil = (ImlibFilter *) ctx->filter;
5181    __imlib_FilterSetColor(&fil->alpha, xoff, yoff, a, 0, 0, 0);
5182    __imlib_FilterSetColor(&fil->red, xoff, yoff, 0, r, 0, 0);
5183    __imlib_FilterSetColor(&fil->green, xoff, yoff, 0, 0, g, 0);
5184    __imlib_FilterSetColor(&fil->blue, xoff, yoff, 0, 0, 0, b);
5185 }
5186 
5187 EAPI void
imlib_filter_set_alpha(int xoff,int yoff,int a,int r,int g,int b)5188 imlib_filter_set_alpha(int xoff, int yoff, int a, int r, int g, int b)
5189 {
5190    ImlibFilter        *fil;
5191 
5192    CHECK_CONTEXT(ctx);
5193    CHECK_PARAM_POINTER("imlib_filter_set_alpha", "filter", ctx->filter);
5194    fil = (ImlibFilter *) ctx->filter;
5195    __imlib_FilterSetColor(&fil->alpha, xoff, yoff, a, r, g, b);
5196 }
5197 
5198 EAPI void
imlib_filter_set_red(int xoff,int yoff,int a,int r,int g,int b)5199 imlib_filter_set_red(int xoff, int yoff, int a, int r, int g, int b)
5200 {
5201    ImlibFilter        *fil;
5202 
5203    CHECK_CONTEXT(ctx);
5204    CHECK_PARAM_POINTER("imlib_filter_set_red", "filter", ctx->filter);
5205    fil = (ImlibFilter *) ctx->filter;
5206    __imlib_FilterSetColor(&fil->red, xoff, yoff, a, r, g, b);
5207 }
5208 
5209 EAPI void
imlib_filter_set_green(int xoff,int yoff,int a,int r,int g,int b)5210 imlib_filter_set_green(int xoff, int yoff, int a, int r, int g, int b)
5211 {
5212    ImlibFilter        *fil;
5213 
5214    CHECK_CONTEXT(ctx);
5215    CHECK_PARAM_POINTER("imlib_filter_set_green", "filter", ctx->filter);
5216    fil = (ImlibFilter *) ctx->filter;
5217    __imlib_FilterSetColor(&fil->green, xoff, yoff, a, r, g, b);
5218 }
5219 
5220 EAPI void
imlib_filter_set_blue(int xoff,int yoff,int a,int r,int g,int b)5221 imlib_filter_set_blue(int xoff, int yoff, int a, int r, int g, int b)
5222 {
5223    ImlibFilter        *fil;
5224 
5225    CHECK_CONTEXT(ctx);
5226    CHECK_PARAM_POINTER("imlib_filter_set_blue", "filter", ctx->filter);
5227    fil = (ImlibFilter *) ctx->filter;
5228    __imlib_FilterSetColor(&fil->blue, xoff, yoff, a, r, g, b);
5229 }
5230 
5231 EAPI void
imlib_filter_constants(int a,int r,int g,int b)5232 imlib_filter_constants(int a, int r, int g, int b)
5233 {
5234    CHECK_CONTEXT(ctx);
5235    CHECK_PARAM_POINTER("imlib_filter_constants", "filter", ctx->filter);
5236    __imlib_FilterConstants((ImlibFilter *) ctx->filter, a, r, g, b);
5237 }
5238 
5239 EAPI void
imlib_filter_divisors(int a,int r,int g,int b)5240 imlib_filter_divisors(int a, int r, int g, int b)
5241 {
5242    CHECK_CONTEXT(ctx);
5243    CHECK_PARAM_POINTER("imlib_filter_divisors", "filter", ctx->filter);
5244    __imlib_FilterDivisors((ImlibFilter *) ctx->filter, a, r, g, b);
5245 }
5246 
5247 EAPI void
imlib_apply_filter(const char * script,...)5248 imlib_apply_filter(const char *script, ...)
5249 {
5250    va_list             param_list;
5251    ImlibImage         *im;
5252 
5253    CHECK_CONTEXT(ctx);
5254    __imlib_dynamic_filters_init();
5255    CAST_IMAGE(im, ctx->image);
5256    if (__imlib_LoadImageData(im))
5257       return;
5258    __imlib_DirtyImage(im);
5259    va_start(param_list, script);
5260    __imlib_script_parse(im, script, param_list);
5261    va_end(param_list);
5262 }
5263 
5264 /**
5265  * Returns a new polygon object with no points set.
5266  **/
5267 EAPI                ImlibPolygon
imlib_polygon_new(void)5268 imlib_polygon_new(void)
5269 {
5270    CHECK_CONTEXT(ctx);
5271    return (ImlibPolygon) __imlib_polygon_new();
5272 }
5273 
5274 /**
5275  * @param poly A polygon
5276  * @param x The X coordinate.
5277  * @param y The Y coordinate.
5278  *
5279  * Adds the point (@p x, @p y) to the polygon @p poly. The point will be added
5280  * to the end of the polygon's internal point list. The points are
5281  * drawn in order, from the first to the last.
5282  **/
5283 EAPI void
imlib_polygon_add_point(ImlibPolygon poly,int x,int y)5284 imlib_polygon_add_point(ImlibPolygon poly, int x, int y)
5285 {
5286    CHECK_CONTEXT(ctx);
5287    CHECK_PARAM_POINTER("imlib_polygon_add_point", "polygon", poly);
5288    __imlib_polygon_add_point((ImlibPoly) poly, x, y);
5289 }
5290 
5291 /**
5292  * @param poly A polygon.
5293  *
5294  * Frees a polygon object.
5295  **/
5296 EAPI void
imlib_polygon_free(ImlibPolygon poly)5297 imlib_polygon_free(ImlibPolygon poly)
5298 {
5299    CHECK_CONTEXT(ctx);
5300    CHECK_PARAM_POINTER("imlib_polygon_free", "polygon", poly);
5301    __imlib_polygon_free((ImlibPoly) poly);
5302 }
5303 
5304 /**
5305  * @param poly A polygon.
5306  * @param closed Closed polygon flag.
5307  *
5308  * Draws the polygon @p poly onto the current context image. Points which have
5309  * been added to the polygon are drawn in sequence, first to last. The
5310  * final point will be joined with the first point if @p closed is
5311  * non-zero.
5312  **/
5313 EAPI void
imlib_image_draw_polygon(ImlibPolygon poly,unsigned char closed)5314 imlib_image_draw_polygon(ImlibPolygon poly, unsigned char closed)
5315 {
5316    ImlibImage         *im;
5317 
5318    CHECK_CONTEXT(ctx);
5319    CHECK_PARAM_POINTER("imlib_image_draw_polygon", "image", ctx->image);
5320    CAST_IMAGE(im, ctx->image);
5321    if (__imlib_LoadImageData(im))
5322       return;
5323    __imlib_DirtyImage(im);
5324    __imlib_Polygon_DrawToImage((ImlibPoly) poly, closed, ctx->pixel,
5325                                im, ctx->cliprect.x, ctx->cliprect.y,
5326                                ctx->cliprect.w, ctx->cliprect.h,
5327                                ctx->operation, ctx->blend, ctx->anti_alias);
5328 }
5329 
5330 /**
5331  * @param poly A polygon.
5332  *
5333  * Fills the area defined by the polygon @p polyon the current context image
5334  * with the current context color.
5335  **/
5336 EAPI void
imlib_image_fill_polygon(ImlibPolygon poly)5337 imlib_image_fill_polygon(ImlibPolygon poly)
5338 {
5339    ImlibImage         *im;
5340 
5341    CHECK_CONTEXT(ctx);
5342    CHECK_PARAM_POINTER("imlib_image_fill_polygon", "image", ctx->image);
5343    CAST_IMAGE(im, ctx->image);
5344    if (__imlib_LoadImageData(im))
5345       return;
5346    __imlib_DirtyImage(im);
5347    __imlib_Polygon_FillToImage((ImlibPoly) poly, ctx->pixel,
5348                                im, ctx->cliprect.x, ctx->cliprect.y,
5349                                ctx->cliprect.w, ctx->cliprect.h,
5350                                ctx->operation, ctx->blend, ctx->anti_alias);
5351 }
5352 
5353 /**
5354  * @param poly A polygon.
5355  * @param px1 X coordinate of the upper left corner.
5356  * @param py1 Y coordinate of the upper left corner.
5357  * @param px2 X coordinate of the lower right corner.
5358  * @param py2 Y coordinate of the lower right corner.
5359  *
5360  * Calculates the bounding area of the polygon @p poly. (@p px1, @p py1) defines the
5361  * upper left corner of the bounding box and (@p px2, @p py2) defines it's
5362  * lower right corner.
5363  **/
5364 EAPI void
imlib_polygon_get_bounds(ImlibPolygon poly,int * px1,int * py1,int * px2,int * py2)5365 imlib_polygon_get_bounds(ImlibPolygon poly, int *px1, int *py1, int *px2,
5366                          int *py2)
5367 {
5368    CHECK_CONTEXT(ctx);
5369    CHECK_PARAM_POINTER("imlib_polygon_get_bounds", "polygon", poly);
5370    __imlib_polygon_get_bounds((ImlibPoly) poly, px1, py1, px2, py2);
5371 }
5372 
5373 /**
5374  * @param xc X coordinate of the center of the ellipse.
5375  * @param yc Y coordinate of the center of the ellipse.
5376  * @param a The horizontal amplitude of the ellipse.
5377  * @param b The vertical amplitude of the ellipse.
5378  *
5379  * Draws an ellipse on the current context image. The ellipse is
5380  * defined as (@p x-@p xc)^2/@p a^2 + (@p y-@p yc)^2/@p b^2 = 1. This means that the
5381  * point (@p xc, @p yc) marks the center of the ellipse, @p a defines the
5382  * horizontal amplitude of the ellipse, and @p b defines the vertical
5383  * amplitude.
5384  **/
5385 EAPI void
imlib_image_draw_ellipse(int xc,int yc,int a,int b)5386 imlib_image_draw_ellipse(int xc, int yc, int a, int b)
5387 {
5388    ImlibImage         *im;
5389 
5390    CHECK_CONTEXT(ctx);
5391    CHECK_PARAM_POINTER("imlib_draw_ellipse", "image", ctx->image);
5392    CAST_IMAGE(im, ctx->image);
5393    if (__imlib_LoadImageData(im))
5394       return;
5395    __imlib_DirtyImage(im);
5396    __imlib_Ellipse_DrawToImage(xc, yc, a, b, ctx->pixel,
5397                                im, ctx->cliprect.x, ctx->cliprect.y,
5398                                ctx->cliprect.w, ctx->cliprect.h,
5399                                ctx->operation, ctx->blend, ctx->anti_alias);
5400 }
5401 
5402 /**
5403  * @param xc X coordinate of the center of the ellipse.
5404  * @param yc Y coordinate of the center of the ellipse.
5405  * @param a The horizontal amplitude of the ellipse.
5406  * @param b The vertical amplitude of the ellipse.
5407  *
5408  * Fills an ellipse on the current context image using the current
5409  * context color. The ellipse is
5410  * defined as (@p x-@p xc)^2/@p a^2 + (@p y-@p yc)^2/@p b^2 = 1. This means that the
5411  * point (@p xc, @p yc) marks the center of the ellipse, @p a defines the
5412  * horizontal amplitude of the ellipse, and @p b defines the vertical
5413  * amplitude.
5414  **/
5415 EAPI void
imlib_image_fill_ellipse(int xc,int yc,int a,int b)5416 imlib_image_fill_ellipse(int xc, int yc, int a, int b)
5417 {
5418    ImlibImage         *im;
5419 
5420    CHECK_CONTEXT(ctx);
5421    CHECK_PARAM_POINTER("imlib_fill_ellipse", "image", ctx->image);
5422    CAST_IMAGE(im, ctx->image);
5423    if (__imlib_LoadImageData(im))
5424       return;
5425    __imlib_DirtyImage(im);
5426    __imlib_Ellipse_FillToImage(xc, yc, a, b, ctx->pixel,
5427                                im, ctx->cliprect.x, ctx->cliprect.y,
5428                                ctx->cliprect.w, ctx->cliprect.h,
5429                                ctx->operation, ctx->blend, ctx->anti_alias);
5430 }
5431 
5432 /**
5433  * @param poly A polygon
5434  * @param x The X coordinate.
5435  * @param y The Y coordinate.
5436  *
5437  * Returns non-zero if the point (@p x, @p y) is within the area defined by
5438  * the polygon @p poly.
5439  **/
5440 EAPI unsigned char
imlib_polygon_contains_point(ImlibPolygon poly,int x,int y)5441 imlib_polygon_contains_point(ImlibPolygon poly, int x, int y)
5442 {
5443    CHECK_CONTEXT(ctx);
5444    CHECK_PARAM_POINTER_RETURN("imlib_polygon_contains_point", "polygon", poly,
5445                               0);
5446    return __imlib_polygon_contains_point((ImlibPoly) poly, x, y);
5447 }
5448 
5449 EAPI void
imlib_image_clear(void)5450 imlib_image_clear(void)
5451 {
5452    ImlibImage         *im;
5453 
5454    CHECK_CONTEXT(ctx);
5455    CHECK_PARAM_POINTER("imlib_image_clear", "image", ctx->image);
5456    CAST_IMAGE(im, ctx->image);
5457    if (__imlib_LoadImageData(im))
5458       return;
5459    __imlib_DirtyImage(im);
5460    memset(im->data, 0, im->w * im->h * sizeof(DATA32));
5461 }
5462 
5463 EAPI void
imlib_image_clear_color(int r,int g,int b,int a)5464 imlib_image_clear_color(int r, int g, int b, int a)
5465 {
5466    ImlibImage         *im;
5467    int                 i, max;
5468    DATA32              col;
5469 
5470    CHECK_CONTEXT(ctx);
5471    CHECK_PARAM_POINTER("imlib_image_clear_color", "image", ctx->image);
5472    CAST_IMAGE(im, ctx->image);
5473    if (__imlib_LoadImageData(im))
5474       return;
5475    __imlib_DirtyImage(im);
5476    max = im->w * im->h;
5477    col = PIXEL_ARGB(a, r, g, b);
5478    for (i = 0; i < max; i++)
5479       im->data[i] = col;
5480 }
5481