summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2022-01-13 17:18:15 +0100
committerKim Woelders <kim@woelders.dk>2022-01-16 20:53:58 +0100
commit1f883a721a4378e7fdf3d929539cc572e5868e05 (patch)
tree4ab42ce0dcbea5732acc58530fd85cad4561d48e
parentb26150d9f43706e48a7ee420a66baf748864b2ac (diff)
downloadimlib2-1f883a721a4378e7fdf3d929539cc572e5868e05.tar.gz
Add dispose-to-previous frame handling
Dispose to previous appears to be used often by apng's.
-rw-r--r--src/bin/imlib2_view.c54
-rw-r--r--src/lib/Imlib2.h.in7
-rw-r--r--src/lib/image.h7
3 files changed, 56 insertions, 12 deletions
diff --git a/src/bin/imlib2_view.c b/src/bin/imlib2_view.c
index abfdb90..84fb6f9 100644
--- a/src/bin/imlib2_view.c
+++ b/src/bin/imlib2_view.c
@@ -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 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);
+ 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)
{
/* "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);
- imlib_context_set_color(0, 0, 0, 0);
- imlib_image_fill_rectangle(r_prev.x, r_prev.y, r_prev.w, r_prev.h);
+ if (im_prev)
+ {
+ 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) */
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;
}
+ im_prev = im_save;
- if (flags & IMLIB_FRAME_DISPOSE_CLEAR)
- r_prev = *up_in; /* Clear next time around */
+ if (flags & (IMLIB_FRAME_DISPOSE_CLEAR | IMLIB_FRAME_DISPOSE_PREV))
+ r_prev = *up_in; /* Clear/revert next time around */
else
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)
{
- rect_t r_dam;
+ rect_t r_dam = { };
/* Update animated "target" canvas image (fg_im) */
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);
+ anim_update(NULL, NULL, NULL, 0); /* Clean up previous animation */
+
image_width = 0; /* Force redraw in progress() */
draw = strtoul(name, &ptr, 0);
diff --git a/src/lib/Imlib2.h.in b/src/lib/Imlib2.h.in
index 0e465c5..7783a61 100644
--- a/src/lib/Imlib2.h.in
+++ b/src/lib/Imlib2.h.in
@@ -615,9 +615,10 @@ typedef struct {
} Imlib_Frame_Info;
/* frame info flags */
-#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 << 2) /* Blend current onto previous frame */
+#define IMLIB_IMAGE_ANIMATED (1 << 0) /* Frames are an animated sequence */
+#define IMLIB_FRAME_BLEND (1 << 1) /* 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 void imlib_image_get_frame_info(Imlib_Frame_Info * info);
diff --git a/src/lib/image.h b/src/lib/image.h
index daaac57..393c37b 100644
--- a/src/lib/image.h
+++ b/src/lib/image.h
@@ -30,9 +30,10 @@ enum _iflags {
typedef enum _iflags ImlibImageFlags;
/* Must match the ones in Imlib2.h.in */
-#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 << 2) /* Blend current onto previous frame */
+#define FF_IMAGE_ANIMATED (1 << 0) /* Frames are an animated sequence */
+#define FF_FRAME_BLEND (1 << 1) /* 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 {
int left, right, top, bottom;