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
|
||||
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.
|
||||
|
|
77
image.c
77
image.c
|
@ -75,26 +75,48 @@ image_imlib_load_strerror(Imlib_Load_Error e)
|
|||
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.
|
||||
* \return Data.
|
||||
*/
|
||||
static void
|
||||
image_compute(image_t *image)
|
||||
uint8_t *
|
||||
image_getdata(image_t *image)
|
||||
{
|
||||
int size, i;
|
||||
uint32_t *data;
|
||||
double alpha;
|
||||
uint8_t *dataimg;
|
||||
|
||||
if(image->isupdated)
|
||||
return image->data;
|
||||
|
||||
imlib_context_set_image(image->image);
|
||||
|
||||
data = imlib_image_get_data_for_reading_only();
|
||||
|
||||
image->width = imlib_image_get_width();
|
||||
image->height = imlib_image_get_height();
|
||||
|
||||
size = image->width * image->height;
|
||||
size = imlib_image_get_width() * imlib_image_get_height();
|
||||
|
||||
p_realloc(&image->data, size * 4);
|
||||
dataimg = image->data;
|
||||
|
@ -117,6 +139,10 @@ image_compute(image_t *image)
|
|||
dataimg[0] = (data[i] & 0xff) * alpha; /* B */
|
||||
#endif
|
||||
}
|
||||
|
||||
image->isupdated = true;
|
||||
|
||||
return image->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);
|
||||
image_t *image = image_new(globalconf.L);
|
||||
image->image = imimage;
|
||||
image_compute(image);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -166,8 +191,6 @@ image_new_from_file(const char *filename)
|
|||
image = image_new(globalconf.L);
|
||||
image->image = imimage;
|
||||
|
||||
image_compute(image);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -237,7 +260,7 @@ luaA_image_orientate(lua_State *L)
|
|||
imlib_context_set_image(image->image);
|
||||
imlib_image_orientate(orientation);
|
||||
|
||||
image_compute(image);
|
||||
image->isupdated = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -261,8 +284,6 @@ luaA_image_rotate(lua_State *L)
|
|||
imlib_context_set_image(image->image);
|
||||
new->image = imlib_create_rotated_image(angle);
|
||||
|
||||
image_compute(new);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -290,8 +311,6 @@ luaA_image_crop(lua_State *L)
|
|||
imlib_context_set_image(image->image);
|
||||
new->image = imlib_create_cropped_image(x, y, w, h);
|
||||
|
||||
image_compute(new);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -327,8 +346,6 @@ luaA_image_crop_and_scale(lua_State *L)
|
|||
w, h,
|
||||
dest_w, dest_h);
|
||||
|
||||
image_compute(new);
|
||||
|
||||
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_image_draw_pixel(x, y, 1);
|
||||
image_compute(image);
|
||||
image->isupdated = false;
|
||||
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_image_draw_line(x1, y1, x2, y2, 0);
|
||||
image_compute(image);
|
||||
image->isupdated = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -439,7 +456,7 @@ luaA_image_draw_rectangle(lua_State *L)
|
|||
imlib_image_draw_rectangle(x, y, width, height);
|
||||
else
|
||||
imlib_image_fill_rectangle(x, y, width, height);
|
||||
image_compute(image);
|
||||
image->isupdated = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -530,7 +547,7 @@ luaA_image_draw_rectangle_gradient(lua_State *L)
|
|||
|
||||
imlib_free_color_range();
|
||||
|
||||
image_compute(image);
|
||||
image->isupdated = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -574,7 +591,7 @@ luaA_image_draw_circle(lua_State *L)
|
|||
imlib_image_draw_ellipse(x, y, ah, av);
|
||||
else
|
||||
imlib_image_fill_ellipse(x, y, ah, av);
|
||||
image_compute(image);
|
||||
image->isupdated = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -629,14 +646,14 @@ luaA_image_insert(lua_State *L)
|
|||
|
||||
int xsrc = luaL_optnumber(L, 5, 0);
|
||||
int ysrc = luaL_optnumber(L, 6, 0);
|
||||
int wsrc = luaL_optnumber(L, 7, image_source->width);
|
||||
int hsrc = luaL_optnumber(L, 8, image_source->height);
|
||||
int wsrc = luaL_optnumber(L, 7, image_getwidth(image_source));
|
||||
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 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);
|
||||
|
||||
|
@ -649,7 +666,7 @@ luaA_image_insert(lua_State *L)
|
|||
* is the default */
|
||||
hxoff, hyoff, vxoff, vyoff);
|
||||
|
||||
image_compute(image_target);
|
||||
image_target->isupdated = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -675,12 +692,10 @@ luaA_image_index(lua_State *L)
|
|||
switch(a_tokenize(attr, len))
|
||||
{
|
||||
case A_TK_WIDTH:
|
||||
imlib_context_set_image(image->image);
|
||||
lua_pushnumber(L, imlib_image_get_width());
|
||||
lua_pushnumber(L, image_getwidth(image));
|
||||
break;
|
||||
case A_TK_HEIGHT:
|
||||
imlib_context_set_image(image->image);
|
||||
lua_pushnumber(L, imlib_image_get_height());
|
||||
lua_pushnumber(L, image_getheight(image));
|
||||
break;
|
||||
case A_TK_ALPHA:
|
||||
imlib_context_set_image(image->image);
|
||||
|
|
10
image.h
10
image.h
|
@ -33,17 +33,19 @@ typedef struct
|
|||
luaA_ref_array_t refs;
|
||||
/** Imlib2 image */
|
||||
Imlib_Image image;
|
||||
/** Image width */
|
||||
int width;
|
||||
/** Image height */
|
||||
int height;
|
||||
/** Image data */
|
||||
uint8_t *data;
|
||||
/** Flag telling if the image is up to date or needs computing before
|
||||
* drawing */
|
||||
bool isupdated;
|
||||
} image_t;
|
||||
|
||||
LUA_OBJECT_FUNCS(image_t, image, "image")
|
||||
|
||||
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
|
||||
// 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)
|
||||
{
|
||||
int iwidth = image_getwidth(d->image);
|
||||
int iheight = image_getheight(d->image);
|
||||
if(d->resize)
|
||||
{
|
||||
double ratio = (double) height / d->image->height;
|
||||
geometry.width = ratio * d->image->width;
|
||||
double ratio = (double) height / iheight;
|
||||
geometry.width = ratio * iwidth;
|
||||
if(geometry.width > width)
|
||||
{
|
||||
geometry.width = 0;
|
||||
|
@ -52,9 +54,9 @@ imagebox_geometry(widget_t *widget, screen_t *screen, int height, int width)
|
|||
else
|
||||
geometry.height = height;
|
||||
}
|
||||
else if(d->image->width <= width)
|
||||
else if(iwidth <= width)
|
||||
{
|
||||
geometry.width = d->image->width;
|
||||
geometry.width = iwidth;
|
||||
geometry.height = height;
|
||||
}
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
case AlignBottom:
|
||||
y += geometry.height - d->image->height;
|
||||
y += geometry.height - iheight;
|
||||
break;
|
||||
case AlignCenter:
|
||||
y += (geometry.height - d->image->height) / 2;
|
||||
y += (geometry.height - iheight) / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -66,8 +66,10 @@ textbox_geometry(widget_t *widget, screen_t *screen, int height, int width)
|
|||
geometry.width = width;
|
||||
else if(d->bg_image)
|
||||
{
|
||||
double ratio = d->bg_resize ? (double) geometry.height / d->bg_image->height : 1;
|
||||
geometry.width = MIN(width, MAX(d->extents.width + d->margin.left + d->margin.right, MAX(d->width, d->bg_image->width * ratio)));
|
||||
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;
|
||||
geometry.width = MIN(width, MAX(d->extents.width + d->margin.left + d->margin.right, MAX(d->width, bgi_width * ratio)));
|
||||
}
|
||||
else
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
if(ratio * d->bg_image->width <= geometry.width)
|
||||
if(ratio * bgi_width <= geometry.width)
|
||||
{
|
||||
int x = geometry.x;
|
||||
int y = geometry.y;
|
||||
switch(d->bg_align)
|
||||
{
|
||||
case AlignCenter:
|
||||
x += (geometry.width - d->bg_image->width * ratio) / 2;
|
||||
x += (geometry.width - bgi_width * ratio) / 2;
|
||||
break;
|
||||
case AlignRight:
|
||||
x += geometry.width - d->bg_image->width * ratio;
|
||||
x += geometry.width - bgi_width * ratio;
|
||||
break;
|
||||
case AlignBottom:
|
||||
y += geometry.height - d->bg_image->height * ratio;
|
||||
y += geometry.height - bgi_height * ratio;
|
||||
break;
|
||||
case AlignMiddle:
|
||||
y += (geometry.height - d->bg_image->height * ratio) / 2;
|
||||
y += (geometry.height - bgi_height * ratio) / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue