Add dispose-to-previous frame handling
Dispose to previous appears to be used often by apng's.
This commit is contained in:
parent
b26150d9f4
commit
1f883a721a
|
@ -204,15 +204,54 @@ anim_update(Imlib_Image im, const rect_t * up_in, rect_t * up_out, int flags)
|
||||||
{
|
{
|
||||||
static const rect_t r_zero = { };
|
static const rect_t r_zero = { };
|
||||||
static rect_t r_prev = r_zero;
|
static rect_t r_prev = r_zero;
|
||||||
|
static Imlib_Image im_prev = NULL;
|
||||||
|
Imlib_Image im_save = NULL;
|
||||||
|
|
||||||
|
if (!im)
|
||||||
|
{
|
||||||
|
/* Cleanup */
|
||||||
|
if (im_prev)
|
||||||
|
{
|
||||||
|
imlib_context_set_image(im_prev);
|
||||||
|
imlib_free_image_and_decache();
|
||||||
|
im_prev = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
imlib_context_set_image(fg_im);
|
imlib_context_set_image(fg_im);
|
||||||
|
|
||||||
|
if (flags & IMLIB_FRAME_DISPOSE_PREV)
|
||||||
|
{
|
||||||
|
Dprintf("Save %d,%d %dx%d\n", up_in->x, up_in->y, up_in->w, up_in->h);
|
||||||
|
im_save =
|
||||||
|
imlib_create_cropped_image(up_in->x, up_in->y, up_in->w, up_in->h);
|
||||||
|
}
|
||||||
|
|
||||||
if (r_prev.w > 0)
|
if (r_prev.w > 0)
|
||||||
{
|
{
|
||||||
/* "dispose" of (clear) previous area before rendering new */
|
/* "dispose" of (clear) previous area before rendering new */
|
||||||
Dprintf("Clear %d,%d %dx%d\n", r_prev.x, r_prev.y, r_prev.w, r_prev.h);
|
if (im_prev)
|
||||||
imlib_context_set_color(0, 0, 0, 0);
|
{
|
||||||
imlib_image_fill_rectangle(r_prev.x, r_prev.y, r_prev.w, r_prev.h);
|
Dprintf("Prev %d,%d %dx%d\n",
|
||||||
|
r_prev.x, r_prev.y, r_prev.w, r_prev.h);
|
||||||
|
imlib_context_set_blend(0);
|
||||||
|
imlib_blend_image_onto_image(im_prev, 1,
|
||||||
|
0, 0, r_prev.w, r_prev.h,
|
||||||
|
r_prev.x, r_prev.y,
|
||||||
|
r_prev.w, r_prev.h);
|
||||||
|
imlib_context_set_image(im_prev);
|
||||||
|
imlib_free_image_and_decache();
|
||||||
|
imlib_context_set_image(fg_im);
|
||||||
|
im_prev = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dprintf("Clear %d,%d %dx%d\n",
|
||||||
|
r_prev.x, r_prev.y, r_prev.w, r_prev.h);
|
||||||
|
imlib_context_set_color(0, 0, 0, 0);
|
||||||
|
imlib_image_fill_rectangle(r_prev.x, r_prev.y, r_prev.w, r_prev.h);
|
||||||
|
}
|
||||||
|
|
||||||
/* Damaged area is (cleared + new frame) */
|
/* Damaged area is (cleared + new frame) */
|
||||||
up_out->x = MIN(r_prev.x, up_in->x);
|
up_out->x = MIN(r_prev.x, up_in->x);
|
||||||
|
@ -224,9 +263,10 @@ anim_update(Imlib_Image im, const rect_t * up_in, rect_t * up_out, int flags)
|
||||||
{
|
{
|
||||||
*up_out = *up_in;
|
*up_out = *up_in;
|
||||||
}
|
}
|
||||||
|
im_prev = im_save;
|
||||||
|
|
||||||
if (flags & IMLIB_FRAME_DISPOSE_CLEAR)
|
if (flags & (IMLIB_FRAME_DISPOSE_CLEAR | IMLIB_FRAME_DISPOSE_PREV))
|
||||||
r_prev = *up_in; /* Clear next time around */
|
r_prev = *up_in; /* Clear/revert next time around */
|
||||||
else
|
else
|
||||||
r_prev = r_zero; /* No clearing before next frame */
|
r_prev = r_zero; /* No clearing before next frame */
|
||||||
|
|
||||||
|
@ -345,7 +385,7 @@ progress(Imlib_Image im, char percent, int update_x, int update_y,
|
||||||
|
|
||||||
if (animated)
|
if (animated)
|
||||||
{
|
{
|
||||||
rect_t r_dam;
|
rect_t r_dam = { };
|
||||||
|
|
||||||
/* Update animated "target" canvas image (fg_im) */
|
/* Update animated "target" canvas image (fg_im) */
|
||||||
anim_update(im, &r_up, &r_dam, finfo.frame_flags);
|
anim_update(im, &r_up, &r_dam, finfo.frame_flags);
|
||||||
|
@ -434,6 +474,8 @@ load_image(int no, const char *name)
|
||||||
|
|
||||||
Vprintf("Show %d: '%s'\n", no, name);
|
Vprintf("Show %d: '%s'\n", no, name);
|
||||||
|
|
||||||
|
anim_update(NULL, NULL, NULL, 0); /* Clean up previous animation */
|
||||||
|
|
||||||
image_width = 0; /* Force redraw in progress() */
|
image_width = 0; /* Force redraw in progress() */
|
||||||
|
|
||||||
draw = strtoul(name, &ptr, 0);
|
draw = strtoul(name, &ptr, 0);
|
||||||
|
|
|
@ -615,9 +615,10 @@ typedef struct {
|
||||||
} Imlib_Frame_Info;
|
} Imlib_Frame_Info;
|
||||||
|
|
||||||
/* frame info flags */
|
/* frame info flags */
|
||||||
#define IMLIB_IMAGE_ANIMATED (1 << 0) /* Frames are an animated sequence */
|
#define IMLIB_IMAGE_ANIMATED (1 << 0) /* Frames are an animated sequence */
|
||||||
#define IMLIB_FRAME_DISPOSE_CLEAR (1 << 1) /* Clear before rendering next frame */
|
#define IMLIB_FRAME_BLEND (1 << 1) /* Blend current onto previous frame */
|
||||||
#define IMLIB_FRAME_BLEND (1 << 2) /* Blend current onto previous frame */
|
#define IMLIB_FRAME_DISPOSE_CLEAR (1 << 2) /* Clear before rendering next frame */
|
||||||
|
#define IMLIB_FRAME_DISPOSE_PREV (1 << 3) /* Revert before rendering next frame */
|
||||||
|
|
||||||
EAPI Imlib_Image imlib_load_image_frame(const char *file, int frame);
|
EAPI Imlib_Image imlib_load_image_frame(const char *file, int frame);
|
||||||
EAPI void imlib_image_get_frame_info(Imlib_Frame_Info * info);
|
EAPI void imlib_image_get_frame_info(Imlib_Frame_Info * info);
|
||||||
|
|
|
@ -30,9 +30,10 @@ enum _iflags {
|
||||||
typedef enum _iflags ImlibImageFlags;
|
typedef enum _iflags ImlibImageFlags;
|
||||||
|
|
||||||
/* Must match the ones in Imlib2.h.in */
|
/* Must match the ones in Imlib2.h.in */
|
||||||
#define FF_IMAGE_ANIMATED (1 << 0) /* Frames are an animated sequence */
|
#define FF_IMAGE_ANIMATED (1 << 0) /* Frames are an animated sequence */
|
||||||
#define FF_FRAME_DISPOSE_CLEAR (1 << 1) /* Clear before rendering next frame */
|
#define FF_FRAME_BLEND (1 << 1) /* Blend current onto previous frame */
|
||||||
#define FF_FRAME_BLEND (1 << 2) /* Blend current onto previous frame */
|
#define FF_FRAME_DISPOSE_CLEAR (1 << 2) /* Clear before rendering next frame */
|
||||||
|
#define FF_FRAME_DISPOSE_PREV (1 << 3) /* Revert before rendering next frame */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int left, right, top, bottom;
|
int left, right, top, bottom;
|
||||||
|
|
Loading…
Reference in New Issue