summaryrefslogtreecommitdiff
path: root/src/gib_imlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gib_imlib.c')
-rw-r--r--src/gib_imlib.c697
1 files changed, 697 insertions, 0 deletions
diff --git a/src/gib_imlib.c b/src/gib_imlib.c
new file mode 100644
index 0000000..49eb5cb
--- /dev/null
+++ b/src/gib_imlib.c
@@ -0,0 +1,697 @@
+/* gib_imlib.c
+
+Copyright (C) 1999,2000 Tom Gilbert.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software and its documentation and acknowledgment shall be
+given in the documentation and software packages that this Software was
+used.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "gib_imlib.h"
+#include "gib_utils.h"
+
+int
+gib_imlib_load_image(Imlib_Image * im, char *filename)
+{
+ Imlib_Load_Error err;
+
+ imlib_context_set_progress_function(NULL);
+ if (!filename)
+ return (0);
+ *im = imlib_load_image_with_error_return(filename, &err);
+ if ((err) || (!im))
+ {
+ /* Check error code */
+ switch (err)
+ {
+ case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST:
+ gib_weprintf("%s - File does not exist", filename);
+ break;
+ case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY:
+ gib_weprintf("%s - Directory specified for image filename", filename);
+ break;
+ case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ:
+ gib_weprintf("%s - No read access to directory", filename);
+ break;
+ case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT:
+ gib_weprintf("%s - No Imlib2 loader for that file format", filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_TOO_LONG:
+ gib_weprintf("%s - Path specified is too long", filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT:
+ gib_weprintf("%s - Path component does not exist", filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY:
+ gib_weprintf("%s - Path component is not a directory", filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE:
+ gib_weprintf("%s - Path points outside address space", filename);
+ break;
+ case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS:
+ gib_weprintf("%s - Too many levels of symbolic links", filename);
+ break;
+ case IMLIB_LOAD_ERROR_OUT_OF_MEMORY:
+ gib_eprintf("While loading %s - Out of memory", filename);
+ break;
+ case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS:
+ gib_eprintf("While loading %s - Out of file descriptors", filename);
+ break;
+ case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE:
+ gib_weprintf("%s - Cannot write to directory", filename);
+ break;
+ case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE:
+ gib_weprintf("%s - Cannot write - out of disk space", filename);
+ break;
+ case IMLIB_LOAD_ERROR_UNKNOWN:
+ default:
+ gib_weprintf
+ ("While loading %s - Unknown error. Attempting to continue",
+ filename);
+ break;
+ }
+ return (0);
+ }
+ return (1);
+}
+
+int
+gib_imlib_image_get_width(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ return imlib_image_get_width();
+}
+
+int
+gib_imlib_image_get_height(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ return imlib_image_get_height();
+}
+
+int
+gib_imlib_image_has_alpha(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ return imlib_image_has_alpha();
+}
+
+void
+gib_imlib_free_image_and_decache(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ imlib_free_image_and_decache();
+}
+
+void
+gib_imlib_free_image(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ imlib_free_image();
+}
+
+const char *
+gib_imlib_image_get_filename(Imlib_Image im)
+{
+ if (im)
+ {
+ imlib_context_set_image(im);
+ return imlib_image_get_filename();
+ }
+ else
+ return NULL;
+}
+
+void
+gib_imlib_render_image_on_drawable(Drawable d, Imlib_Image im, int x, int y,
+ char dither, char blend, char alias)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_drawable(d);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_blend(blend);
+ imlib_context_set_angle(0);
+ imlib_render_image_on_drawable(x, y);
+}
+
+void
+gib_imlib_render_image_on_drawable_with_rotation(Drawable d, Imlib_Image im,
+ int x, int y, double angle,
+ char dither, char blend,
+ char alias)
+{
+ Imlib_Image new_im;
+
+ imlib_context_set_image(im);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_blend(blend);
+ imlib_context_set_angle(angle);
+ imlib_context_set_drawable(d);
+ new_im = imlib_create_rotated_image(angle);
+ imlib_context_set_image(new_im);
+ imlib_render_image_on_drawable(x, y);
+ imlib_free_image();
+}
+
+void
+gib_imlib_render_image_on_drawable_at_size(Drawable d, Imlib_Image im, int x,
+ int y, int w, int h, char dither,
+ char blend, char alias)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_drawable(d);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_blend(blend);
+ imlib_context_set_angle(0);
+ imlib_render_image_on_drawable_at_size(x, y, w, h);
+}
+
+void
+gib_imlib_render_image_on_drawable_at_size_with_rotation(Drawable d,
+ Imlib_Image im,
+ int x, int y, int w,
+ int h, double angle,
+ char dither,
+ char blend,
+ char alias)
+{
+ Imlib_Image new_im;
+
+ imlib_context_set_image(im);
+ imlib_context_set_drawable(d);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_blend(blend);
+ imlib_context_set_angle(angle);
+ new_im = imlib_create_rotated_image(angle);
+ imlib_context_set_image(new_im);
+ imlib_render_image_on_drawable_at_size(x, y, w, h);
+ imlib_free_image_and_decache();
+}
+
+void
+gib_imlib_render_image_part_on_drawable_at_size(Drawable d, Imlib_Image im,
+ int sx, int sy, int sw,
+ int sh, int dx, int dy,
+ int dw, int dh, char dither,
+ char blend, char alias)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_drawable(d);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_blend(blend);
+ imlib_context_set_angle(0);
+ imlib_render_image_part_on_drawable_at_size(sx, sy, sw, sh, dx, dy, dw,
+ dh);
+}
+
+void
+gib_imlib_render_image_part_on_drawable_at_size_with_rotation(Drawable d,
+ Imlib_Image im,
+ int sx, int sy,
+ int sw, int sh,
+ int dx, int dy,
+ int dw, int dh,
+ double angle,
+ char dither,
+ char blend,
+ char alias)
+{
+ Imlib_Image new_im;
+
+ imlib_context_set_image(im);
+ imlib_context_set_drawable(d);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_angle(angle);
+ imlib_context_set_blend(blend);
+ new_im = imlib_create_rotated_image(angle);
+ imlib_context_set_image(new_im);
+ imlib_render_image_part_on_drawable_at_size(sx, sy, sw, sh, dx, dy, dw,
+ dh);
+ imlib_free_image_and_decache();
+}
+
+void
+gib_imlib_image_fill_rectangle(Imlib_Image im, int x, int y, int w, int h,
+ int r, int g, int b, int a)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_color(r, g, b, a);
+ imlib_image_fill_rectangle(x, y, w, h);
+}
+
+void
+gib_imlib_image_fill_polygon(Imlib_Image im, ImlibPolygon poly, int r, int g,
+ int b, int a, unsigned char alias, int cx,
+ int cy, int cw, int ch)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_color(r, g, b, a);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_cliprect(cx, cy, cw, ch);
+ imlib_image_fill_polygon(poly);
+ imlib_context_set_cliprect(0, 0, 0, 0);
+}
+
+void
+gib_imlib_image_draw_polygon(Imlib_Image im, ImlibPolygon poly, int r, int g,
+ int b, int a, unsigned char closed,
+ unsigned char alias, int cx, int cy, int cw,
+ int ch)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_color(r, g, b, a);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_cliprect(cx, cy, cw, ch);
+ imlib_image_draw_polygon(poly, closed);
+ imlib_context_set_cliprect(0, 0, 0, 0);
+}
+
+
+void
+gib_imlib_image_draw_rectangle(Imlib_Image im, int x, int y, int w, int h,
+ int r, int g, int b, int a)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_color(r, g, b, a);
+ imlib_image_draw_rectangle(x, y, w, h);
+}
+
+
+void
+gib_imlib_text_draw(Imlib_Image im, Imlib_Font fn, gib_style * s, int x,
+ int y, char *text, Imlib_Text_Direction dir, int r, int g,
+ int b, int a)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_font(fn);
+ imlib_context_set_direction(dir);
+ if (s)
+ {
+ int min_x = 0, min_y = 0;
+ gib_style_bit *bb;
+ gib_list *l;
+
+ /* here we shift the draw to accomodate bits with negative offsets,
+ * which would be drawn at negative coords otherwise */
+ l = s->bits;
+ while (l)
+ {
+ bb = (gib_style_bit *) l->data;
+ if (bb)
+ {
+ if (bb->x_offset < min_x)
+ min_x = bb->x_offset;
+ if (bb->y_offset < min_y)
+ min_y = bb->y_offset;
+ }
+ l = l->next;
+ }
+ x -= min_x;
+ y -= min_y;
+
+ /* Now draw the bits */
+ l = s->bits;
+ while (l)
+ {
+ bb = (gib_style_bit *) l->data;
+ if (bb)
+ {
+ if ((bb->r + bb->g + bb->b + bb->a) == 0)
+ imlib_context_set_color(r, g, b, a);
+ else
+ imlib_context_set_color(bb->r, bb->g, bb->b, bb->a);
+ imlib_text_draw(x + bb->x_offset, y + bb->y_offset, text);
+ }
+ l = l->next;
+ }
+ }
+ else
+ {
+ imlib_context_set_color(r, g, b, a);
+ imlib_text_draw(x, y, text);
+ }
+}
+
+char **
+gib_imlib_list_fonts(int *num)
+{
+ return imlib_list_fonts(num);
+}
+
+
+void
+gib_imlib_get_text_size(Imlib_Font fn, char *text, gib_style * s, int *w,
+ int *h, Imlib_Text_Direction dir)
+{
+
+ imlib_context_set_font(fn);
+ imlib_context_set_direction(dir);
+ imlib_get_text_size(text, w, h);
+ if (s)
+ {
+ gib_style_bit *b;
+ int max_x_off = 0, min_x_off = 0, max_y_off = 0, min_y_off = 0;
+ gib_list *l;
+
+ l = s->bits;
+ while (l)
+ {
+ b = (gib_style_bit *) l->data;
+ if (b)
+ {
+ if (b->x_offset > max_x_off)
+ max_x_off = b->x_offset;
+ else if (b->x_offset < min_x_off)
+ min_x_off = b->x_offset;
+ if (b->y_offset > max_y_off)
+ max_y_off = b->y_offset;
+ else if (b->y_offset < min_y_off)
+ min_y_off = b->y_offset;
+ }
+ l = l->next;
+ }
+ if (h)
+ {
+ *h += max_y_off;
+ *h -= min_y_off;
+ }
+ if (w)
+ {
+ *w += max_x_off;
+ *w -= min_x_off;
+ }
+ }
+}
+
+Imlib_Image gib_imlib_clone_image(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ return imlib_clone_image();
+}
+
+char *
+gib_imlib_image_format(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ return imlib_image_format();
+}
+
+void
+gib_imlib_blend_image_onto_image(Imlib_Image dest_image,
+ Imlib_Image source_image, char merge_alpha,
+ int sx, int sy, int sw, int sh, int dx,
+ int dy, int dw, int dh, char dither,
+ char blend, char alias)
+{
+ imlib_context_set_image(dest_image);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_blend(blend);
+ imlib_context_set_angle(0);
+ imlib_blend_image_onto_image(source_image, merge_alpha, sx, sy, sw, sh, dx,
+ dy, dw, dh);
+}
+
+void
+gib_imlib_blend_image_onto_image_with_rotation(Imlib_Image dest_image,
+ Imlib_Image source_image,
+ char merge_alpha, int sx,
+ int sy, int sw, int sh, int dx,
+ int dy, int dw, int dh,
+ double angle, char dither,
+ char blend, char alias)
+{
+ imlib_context_set_image(dest_image);
+ imlib_context_set_anti_alias(alias);
+ imlib_context_set_dither(dither);
+ imlib_context_set_blend(blend);
+ imlib_context_set_angle(angle);
+ imlib_blend_image_onto_image_at_angle(source_image, merge_alpha, sx, sy,
+ sw, sh, dx, dy, (int) angle,
+ (int) angle);
+ return;
+ dw = 0;
+ dh = 0;
+}
+
+Imlib_Image gib_imlib_create_cropped_scaled_image(Imlib_Image im, int sx,
+ int sy, int sw, int sh,
+ int dw, int dh, char alias)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_anti_alias(alias);
+ return imlib_create_cropped_scaled_image(sx, sy, sw, sh, dw, dh);
+}
+
+void
+gib_imlib_apply_color_modifier_to_rectangle(Imlib_Image im, int x, int y,
+ int w, int h, DATA8 * rtab,
+ DATA8 * gtab, DATA8 * btab,
+ DATA8 * atab)
+{
+ Imlib_Color_Modifier cm;
+
+ imlib_context_set_image(im);
+ cm = imlib_create_color_modifier();
+ imlib_context_set_color_modifier(cm);
+ imlib_set_color_modifier_tables(rtab, gtab, btab, atab);
+ imlib_apply_color_modifier_to_rectangle(x, y, w, h);
+ imlib_free_color_modifier();
+}
+
+void
+gib_imlib_image_set_has_alpha(Imlib_Image im, int alpha)
+{
+ imlib_context_set_image(im);
+ imlib_image_set_has_alpha(alpha);
+}
+
+void
+gib_imlib_save_image(Imlib_Image im, char *file)
+{
+ char *tmp;
+
+ imlib_context_set_image(im);
+ tmp = strrchr(file, '.');
+ if (tmp)
+ {
+ char *p, *pp;
+ p = strdup(tmp + 1);
+ pp = p;
+ while(*pp) {
+ *pp = tolower(*pp);
+ pp++;
+ }
+ imlib_image_set_format(p);
+ free(p);
+ }
+ imlib_save_image(file);
+}
+
+void
+gib_imlib_save_image_with_error_return(Imlib_Image im, char *file,
+ Imlib_Load_Error * error_return)
+{
+ char *tmp;
+
+ imlib_context_set_image(im);
+ tmp = strrchr(file, '.');
+ if (tmp)
+ imlib_image_set_format(tmp + 1);
+ imlib_save_image_with_error_return(file, error_return);
+}
+
+void
+gib_imlib_free_font(Imlib_Font fn)
+{
+ imlib_context_set_font(fn);
+ imlib_free_font();
+}
+
+void
+gib_imlib_image_draw_line(Imlib_Image im, int x1, int y1, int x2, int y2,
+ char make_updates, int r, int g, int b, int a)
+{
+ imlib_context_set_image(im);
+ imlib_context_set_color(r, g, b, a);
+ imlib_image_draw_line(x1, y1, x2, y2, make_updates);
+}
+
+Imlib_Image gib_imlib_create_rotated_image(Imlib_Image im, double angle)
+{
+ imlib_context_set_image(im);
+ return (imlib_create_rotated_image(angle));
+}
+
+void
+gib_imlib_image_tile(Imlib_Image im)
+{
+ imlib_context_set_image(im);
+ imlib_image_tile();
+}
+
+void
+gib_imlib_image_blur(Imlib_Image im, int radius)
+{
+ imlib_context_set_image(im);
+ imlib_image_blur(radius);
+}
+
+void
+gib_imlib_image_sharpen(Imlib_Image im, int radius)
+{
+ imlib_context_set_image(im);
+ imlib_image_sharpen(radius);
+}
+
+void
+gib_imlib_line_clip_and_draw(Imlib_Image dest, int x0, int y0, int x1, int y1,
+ int cx, int cy, int cw, int ch, int r, int g,
+ int b, int a)
+{
+ imlib_context_set_cliprect(cx, cy, cw, ch);
+ gib_imlib_image_draw_line(dest, x0, y0, x1, y1, 0, r, g, b, a);
+ imlib_context_set_cliprect(0, 0, 0, 0);
+}
+
+Imlib_Image
+gib_imlib_create_image_from_drawable(Drawable d, Pixmap mask, int x, int y,
+ int width, int height,
+ char need_to_grab_x)
+{
+ imlib_context_set_drawable(d);
+ return imlib_create_image_from_drawable(mask, x, y, width, height,
+ need_to_grab_x);
+}
+
+void gib_imlib_parse_color(char *col, int *r, int *g, int *b, int *a)
+ {
+ gib_list *ll;
+ unsigned long cc, rr, gg, bb, aa;
+ int len;
+
+ if (col[0] == '#')
+ {
+ /* #RRGGBBAA style */
+ /* skip the '#' */
+ col++;
+ len = strlen(col);
+ if (len == 8)
+ {
+ cc = (unsigned long) strtoul(col, NULL, 16);
+ rr = (cc & 0xff000000) >> 24;
+ gg = (cc & 0x00ff0000) >> 16;
+ bb = (cc & 0x0000ff00) >> 8;
+ aa = (cc & 0x000000ff);
+ }
+ else if (len == 6)
+ {
+ cc = (unsigned long) strtoul(col, NULL, 16);
+ rr = (cc & 0xff0000) >> 16;
+ gg = (cc & 0x00ff00) >> 8;
+ bb = (cc & 0x0000ff);
+ aa = 255;
+ }
+ else
+ {
+ gib_weprintf("unable to parse color %s\n", col);
+ return;
+ }
+ }
+ else
+ {
+ /* r,g,b,a style */
+ ll = gib_string_split(col, ",");
+ if (!ll)
+ {
+ gib_weprintf("unable to parse color %s\n", col);
+ return;
+ }
+ len = gib_list_length(ll);
+ if (len == 3)
+ {
+ rr = atoi(ll->data);
+ gg = atoi(ll->next->data);
+ bb = atoi(ll->next->next->data);
+ aa = 255;
+ }
+ else if (len == 4)
+ {
+ rr = atoi(ll->data);
+ gg = atoi(ll->next->data);
+ bb = atoi(ll->next->next->data);
+ aa = atoi(ll->next->next->next->data);
+ }
+ else
+ {
+ gib_weprintf("unable to parse color %s\n", col);
+ return;
+ }
+ }
+ *r = rr;
+ *g = gg;
+ *b = bb;
+ *a = aa;
+ }
+
+void
+gib_imlib_parse_fontpath(char *path)
+{
+ gib_list *l, *ll;
+
+ if (!path)
+ return;
+
+ l = gib_string_split(path, ":");
+ if (!l)
+ return;
+ ll = l;
+ while (ll)
+ {
+ imlib_add_path_to_font_path((char *) ll->data);
+ ll = ll->next;
+ }
+ gib_list_free_and_data(l);
+}
+
+Imlib_Font
+gib_imlib_load_font(char *name)
+{
+ Imlib_Font fn;
+
+ if ((fn = imlib_load_font(name)))
+ return fn;
+ gib_weprintf("couldn't load font %s, attempting to fall back to fixed.", name);
+ if ((fn = imlib_load_font("fixed")))
+ return fn;
+ gib_weprintf("failed to even load fixed! Attempting to find any font.");
+ return imlib_load_font("*");
+}
+
+void gib_imlib_image_orientate(Imlib_Image im, int orientation)
+{
+ imlib_context_set_image(im);
+ imlib_image_orientate(orientation);
+}