image: only compute when needed
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
1e6d4747be
commit
45c2ac38a4
2
draw.c
2
draw.c
|
@ -598,7 +598,7 @@ draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h,
|
||||||
void
|
void
|
||||||
draw_image(draw_context_t *ctx, int x, int y, double ratio, image_t *image)
|
draw_image(draw_context_t *ctx, int x, int y, double ratio, image_t *image)
|
||||||
{
|
{
|
||||||
draw_image_from_argb_data(ctx, x, y, image->width, image->height, ratio, image->data);
|
draw_image_from_argb_data(ctx, x, y, image_getwidth(image), image_getheight(image), ratio, image_getdata(image));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Rotate a pixmap.
|
/** Rotate a pixmap.
|
||||||
|
|
77
image.c
77
image.c
|
@ -75,26 +75,48 @@ image_imlib_load_strerror(Imlib_Load_Error e)
|
||||||
return "unknown error";
|
return "unknown error";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Recompute the ARGB32 data from an image.
|
/** Get image width.
|
||||||
|
* \param image The image.
|
||||||
|
* \return The image width in pixel.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
image_getwidth(image_t *image)
|
||||||
|
{
|
||||||
|
imlib_context_set_image(image->image);
|
||||||
|
return imlib_image_get_width();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get image height.
|
||||||
|
* \param image The image.
|
||||||
|
* \return The image height in pixel.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
image_getheight(image_t *image)
|
||||||
|
{
|
||||||
|
imlib_context_set_image(image->image);
|
||||||
|
return imlib_image_get_height();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the ARGB32 data from an image.
|
||||||
* \param image The image.
|
* \param image The image.
|
||||||
* \return Data.
|
* \return Data.
|
||||||
*/
|
*/
|
||||||
static void
|
uint8_t *
|
||||||
image_compute(image_t *image)
|
image_getdata(image_t *image)
|
||||||
{
|
{
|
||||||
int size, i;
|
int size, i;
|
||||||
uint32_t *data;
|
uint32_t *data;
|
||||||
double alpha;
|
double alpha;
|
||||||
uint8_t *dataimg;
|
uint8_t *dataimg;
|
||||||
|
|
||||||
|
if(image->isupdated)
|
||||||
|
return image->data;
|
||||||
|
|
||||||
imlib_context_set_image(image->image);
|
imlib_context_set_image(image->image);
|
||||||
|
|
||||||
data = imlib_image_get_data_for_reading_only();
|
data = imlib_image_get_data_for_reading_only();
|
||||||
|
|
||||||
image->width = imlib_image_get_width();
|
size = imlib_image_get_width() * imlib_image_get_height();
|
||||||
image->height = imlib_image_get_height();
|
|
||||||
|
|
||||||
size = image->width * image->height;
|
|
||||||
|
|
||||||
p_realloc(&image->data, size * 4);
|
p_realloc(&image->data, size * 4);
|
||||||
dataimg = image->data;
|
dataimg = image->data;
|
||||||
|
@ -117,6 +139,10 @@ image_compute(image_t *image)
|
||||||
dataimg[0] = (data[i] & 0xff) * alpha; /* B */
|
dataimg[0] = (data[i] & 0xff) * alpha; /* B */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image->isupdated = true;
|
||||||
|
|
||||||
|
return image->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new image from ARGB32 data.
|
/** Create a new image from ARGB32 data.
|
||||||
|
@ -136,7 +162,6 @@ image_new_from_argb32(int width, int height, uint32_t *data)
|
||||||
imlib_image_set_has_alpha(true);
|
imlib_image_set_has_alpha(true);
|
||||||
image_t *image = image_new(globalconf.L);
|
image_t *image = image_new(globalconf.L);
|
||||||
image->image = imimage;
|
image->image = imimage;
|
||||||
image_compute(image);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +191,6 @@ image_new_from_file(const char *filename)
|
||||||
image = image_new(globalconf.L);
|
image = image_new(globalconf.L);
|
||||||
image->image = imimage;
|
image->image = imimage;
|
||||||
|
|
||||||
image_compute(image);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +260,7 @@ luaA_image_orientate(lua_State *L)
|
||||||
imlib_context_set_image(image->image);
|
imlib_context_set_image(image->image);
|
||||||
imlib_image_orientate(orientation);
|
imlib_image_orientate(orientation);
|
||||||
|
|
||||||
image_compute(image);
|
image->isupdated = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -261,8 +284,6 @@ luaA_image_rotate(lua_State *L)
|
||||||
imlib_context_set_image(image->image);
|
imlib_context_set_image(image->image);
|
||||||
new->image = imlib_create_rotated_image(angle);
|
new->image = imlib_create_rotated_image(angle);
|
||||||
|
|
||||||
image_compute(new);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +311,6 @@ luaA_image_crop(lua_State *L)
|
||||||
imlib_context_set_image(image->image);
|
imlib_context_set_image(image->image);
|
||||||
new->image = imlib_create_cropped_image(x, y, w, h);
|
new->image = imlib_create_cropped_image(x, y, w, h);
|
||||||
|
|
||||||
image_compute(new);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,8 +346,6 @@ luaA_image_crop_and_scale(lua_State *L)
|
||||||
w, h,
|
w, h,
|
||||||
dest_w, dest_h);
|
dest_w, dest_h);
|
||||||
|
|
||||||
image_compute(new);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +377,7 @@ luaA_image_draw_pixel(lua_State *L)
|
||||||
|
|
||||||
imlib_context_set_color(color.red, color.green, color.blue, color.alpha);
|
imlib_context_set_color(color.red, color.green, color.blue, color.alpha);
|
||||||
imlib_image_draw_pixel(x, y, 1);
|
imlib_image_draw_pixel(x, y, 1);
|
||||||
image_compute(image);
|
image->isupdated = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +413,7 @@ luaA_image_draw_line(lua_State *L)
|
||||||
|
|
||||||
imlib_context_set_color(color.red, color.green, color.blue, color.alpha);
|
imlib_context_set_color(color.red, color.green, color.blue, color.alpha);
|
||||||
imlib_image_draw_line(x1, y1, x2, y2, 0);
|
imlib_image_draw_line(x1, y1, x2, y2, 0);
|
||||||
image_compute(image);
|
image->isupdated = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +456,7 @@ luaA_image_draw_rectangle(lua_State *L)
|
||||||
imlib_image_draw_rectangle(x, y, width, height);
|
imlib_image_draw_rectangle(x, y, width, height);
|
||||||
else
|
else
|
||||||
imlib_image_fill_rectangle(x, y, width, height);
|
imlib_image_fill_rectangle(x, y, width, height);
|
||||||
image_compute(image);
|
image->isupdated = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +547,7 @@ luaA_image_draw_rectangle_gradient(lua_State *L)
|
||||||
|
|
||||||
imlib_free_color_range();
|
imlib_free_color_range();
|
||||||
|
|
||||||
image_compute(image);
|
image->isupdated = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -574,7 +591,7 @@ luaA_image_draw_circle(lua_State *L)
|
||||||
imlib_image_draw_ellipse(x, y, ah, av);
|
imlib_image_draw_ellipse(x, y, ah, av);
|
||||||
else
|
else
|
||||||
imlib_image_fill_ellipse(x, y, ah, av);
|
imlib_image_fill_ellipse(x, y, ah, av);
|
||||||
image_compute(image);
|
image->isupdated = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,14 +646,14 @@ luaA_image_insert(lua_State *L)
|
||||||
|
|
||||||
int xsrc = luaL_optnumber(L, 5, 0);
|
int xsrc = luaL_optnumber(L, 5, 0);
|
||||||
int ysrc = luaL_optnumber(L, 6, 0);
|
int ysrc = luaL_optnumber(L, 6, 0);
|
||||||
int wsrc = luaL_optnumber(L, 7, image_source->width);
|
int wsrc = luaL_optnumber(L, 7, image_getwidth(image_source));
|
||||||
int hsrc = luaL_optnumber(L, 8, image_source->height);
|
int hsrc = luaL_optnumber(L, 8, image_getheight(image_source));
|
||||||
|
|
||||||
int hxoff = luaL_optnumber(L, 9, image_source->width);
|
int hxoff = luaL_optnumber(L, 9, image_getwidth(image_source));
|
||||||
int hyoff = luaL_optnumber(L, 10, 0);
|
int hyoff = luaL_optnumber(L, 10, 0);
|
||||||
|
|
||||||
int vxoff = luaL_optnumber(L, 11, 0);
|
int vxoff = luaL_optnumber(L, 11, 0);
|
||||||
int vyoff = luaL_optnumber(L, 12, image_source->height);
|
int vyoff = luaL_optnumber(L, 12, image_getheight(image_source));
|
||||||
|
|
||||||
imlib_context_set_image(image_target->image);
|
imlib_context_set_image(image_target->image);
|
||||||
|
|
||||||
|
@ -649,7 +666,7 @@ luaA_image_insert(lua_State *L)
|
||||||
* is the default */
|
* is the default */
|
||||||
hxoff, hyoff, vxoff, vyoff);
|
hxoff, hyoff, vxoff, vyoff);
|
||||||
|
|
||||||
image_compute(image_target);
|
image_target->isupdated = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -675,12 +692,10 @@ luaA_image_index(lua_State *L)
|
||||||
switch(a_tokenize(attr, len))
|
switch(a_tokenize(attr, len))
|
||||||
{
|
{
|
||||||
case A_TK_WIDTH:
|
case A_TK_WIDTH:
|
||||||
imlib_context_set_image(image->image);
|
lua_pushnumber(L, image_getwidth(image));
|
||||||
lua_pushnumber(L, imlib_image_get_width());
|
|
||||||
break;
|
break;
|
||||||
case A_TK_HEIGHT:
|
case A_TK_HEIGHT:
|
||||||
imlib_context_set_image(image->image);
|
lua_pushnumber(L, image_getheight(image));
|
||||||
lua_pushnumber(L, imlib_image_get_height());
|
|
||||||
break;
|
break;
|
||||||
case A_TK_ALPHA:
|
case A_TK_ALPHA:
|
||||||
imlib_context_set_image(image->image);
|
imlib_context_set_image(image->image);
|
||||||
|
|
10
image.h
10
image.h
|
@ -33,17 +33,19 @@ typedef struct
|
||||||
luaA_ref_array_t refs;
|
luaA_ref_array_t refs;
|
||||||
/** Imlib2 image */
|
/** Imlib2 image */
|
||||||
Imlib_Image image;
|
Imlib_Image image;
|
||||||
/** Image width */
|
|
||||||
int width;
|
|
||||||
/** Image height */
|
|
||||||
int height;
|
|
||||||
/** Image data */
|
/** Image data */
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
/** Flag telling if the image is up to date or needs computing before
|
||||||
|
* drawing */
|
||||||
|
bool isupdated;
|
||||||
} image_t;
|
} image_t;
|
||||||
|
|
||||||
LUA_OBJECT_FUNCS(image_t, image, "image")
|
LUA_OBJECT_FUNCS(image_t, image, "image")
|
||||||
|
|
||||||
int image_new_from_argb32(int, int, uint32_t *);
|
int image_new_from_argb32(int, int, uint32_t *);
|
||||||
|
uint8_t * image_getdata(image_t *);
|
||||||
|
int image_getwidth(image_t *);
|
||||||
|
int image_getheight(image_t *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||||
|
|
|
@ -40,10 +40,12 @@ imagebox_geometry(widget_t *widget, screen_t *screen, int height, int width)
|
||||||
|
|
||||||
if(d->image)
|
if(d->image)
|
||||||
{
|
{
|
||||||
|
int iwidth = image_getwidth(d->image);
|
||||||
|
int iheight = image_getheight(d->image);
|
||||||
if(d->resize)
|
if(d->resize)
|
||||||
{
|
{
|
||||||
double ratio = (double) height / d->image->height;
|
double ratio = (double) height / iheight;
|
||||||
geometry.width = ratio * d->image->width;
|
geometry.width = ratio * iwidth;
|
||||||
if(geometry.width > width)
|
if(geometry.width > width)
|
||||||
{
|
{
|
||||||
geometry.width = 0;
|
geometry.width = 0;
|
||||||
|
@ -52,9 +54,9 @@ imagebox_geometry(widget_t *widget, screen_t *screen, int height, int width)
|
||||||
else
|
else
|
||||||
geometry.height = height;
|
geometry.height = height;
|
||||||
}
|
}
|
||||||
else if(d->image->width <= width)
|
else if(iwidth <= width)
|
||||||
{
|
{
|
||||||
geometry.width = d->image->width;
|
geometry.width = iwidth;
|
||||||
geometry.height = height;
|
geometry.height = height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -91,14 +93,15 @@ imagebox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry, wibox_t *p
|
||||||
draw_rectangle(ctx, geometry, 1.0, true, &d->bg);
|
draw_rectangle(ctx, geometry, 1.0, true, &d->bg);
|
||||||
|
|
||||||
int y = geometry.y;
|
int y = geometry.y;
|
||||||
double ratio = d->resize ? (double) geometry.height / d->image->height : 1;
|
int iheight = image_getheight(d->image);
|
||||||
|
double ratio = d->resize ? (double) geometry.height / iheight : 1;
|
||||||
switch(d->valign)
|
switch(d->valign)
|
||||||
{
|
{
|
||||||
case AlignBottom:
|
case AlignBottom:
|
||||||
y += geometry.height - d->image->height;
|
y += geometry.height - iheight;
|
||||||
break;
|
break;
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
y += (geometry.height - d->image->height) / 2;
|
y += (geometry.height - iheight) / 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -66,8 +66,10 @@ textbox_geometry(widget_t *widget, screen_t *screen, int height, int width)
|
||||||
geometry.width = width;
|
geometry.width = width;
|
||||||
else if(d->bg_image)
|
else if(d->bg_image)
|
||||||
{
|
{
|
||||||
double ratio = d->bg_resize ? (double) geometry.height / d->bg_image->height : 1;
|
int bgi_height = image_getheight(d->bg_image);
|
||||||
geometry.width = MIN(width, MAX(d->extents.width + d->margin.left + d->margin.right, MAX(d->width, d->bg_image->width * ratio)));
|
int bgi_width = image_getwidth(d->bg_image);
|
||||||
|
double ratio = d->bg_resize ? (double) geometry.height / bgi_height : 1;
|
||||||
|
geometry.width = MIN(width, MAX(d->extents.width + d->margin.left + d->margin.right, MAX(d->width, bgi_width * ratio)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
geometry.width = MIN(d->extents.width + d->margin.left + d->margin.right, width);
|
geometry.width = MIN(d->extents.width + d->margin.left + d->margin.right, width);
|
||||||
|
@ -95,25 +97,27 @@ textbox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry, wibox_t *p)
|
||||||
|
|
||||||
if(d->bg_image)
|
if(d->bg_image)
|
||||||
{
|
{
|
||||||
double ratio = d->bg_resize ? (double) geometry.height / d->bg_image->height : 1;
|
int bgi_height = image_getheight(d->bg_image);
|
||||||
|
int bgi_width = image_getwidth(d->bg_image);
|
||||||
|
double ratio = d->bg_resize ? (double) geometry.height / bgi_height : 1;
|
||||||
/* check there is enough space to draw the image */
|
/* check there is enough space to draw the image */
|
||||||
if(ratio * d->bg_image->width <= geometry.width)
|
if(ratio * bgi_width <= geometry.width)
|
||||||
{
|
{
|
||||||
int x = geometry.x;
|
int x = geometry.x;
|
||||||
int y = geometry.y;
|
int y = geometry.y;
|
||||||
switch(d->bg_align)
|
switch(d->bg_align)
|
||||||
{
|
{
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
x += (geometry.width - d->bg_image->width * ratio) / 2;
|
x += (geometry.width - bgi_width * ratio) / 2;
|
||||||
break;
|
break;
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
x += geometry.width - d->bg_image->width * ratio;
|
x += geometry.width - bgi_width * ratio;
|
||||||
break;
|
break;
|
||||||
case AlignBottom:
|
case AlignBottom:
|
||||||
y += geometry.height - d->bg_image->height * ratio;
|
y += geometry.height - bgi_height * ratio;
|
||||||
break;
|
break;
|
||||||
case AlignMiddle:
|
case AlignMiddle:
|
||||||
y += (geometry.height - d->bg_image->height * ratio) / 2;
|
y += (geometry.height - bgi_height * ratio) / 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue