diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2021-11-26 20:54:08 +0100 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2021-11-26 20:54:41 +0100 |
commit | 18e96d8c9dd6b0346514121facf8137f13ccd6dc (patch) | |
tree | 96db29d63a69be5cab71c907822a6e4899d0c59b | |
parent | bd7f2f8c987772704a5889790b2dc06fa087ee62 (diff) | |
download | fiv-18e96d8c9dd6b0346514121facf8137f13ccd6dc.tar.gz fiv-18e96d8c9dd6b0346514121facf8137f13ccd6dc.tar.xz fiv-18e96d8c9dd6b0346514121facf8137f13ccd6dc.zip |
Allow frame iteration in both directions
-rw-r--r-- | fastiv-io.c | 8 | ||||
-rw-r--r-- | fastiv-io.h | 4 | ||||
-rw-r--r-- | fastiv-view.c | 8 |
3 files changed, 19 insertions, 1 deletions
diff --git a/fastiv-io.c b/fastiv-io.c index a2ac166..35e640d 100644 --- a/fastiv-io.c +++ b/fastiv-io.c @@ -317,6 +317,8 @@ load_wuffs_frame(struct load_wuffs_frame_context *ctx, GError **error) (void *) (intptr_t) (wuffs_base__frame_config__duration(&fc) / WUFFS_BASE__FLICKS_PER_MILLISECOND), NULL); + cairo_surface_set_user_data(surface, &fastiv_io_key_frame_previous, + ctx->result_tail, NULL); if (ctx->result_tail) cairo_surface_set_user_data(ctx->result_tail, &fastiv_io_key_frame_next, surface, (cairo_destroy_func_t) cairo_surface_destroy); @@ -466,6 +468,11 @@ open_wuffs( while (load_wuffs_frame(&ctx, error)) ; + // Wrap the chain around, since our caller receives only one pointer. + if (ctx.result) + cairo_surface_set_user_data(ctx.result, &fastiv_io_key_frame_previous, + ctx.result_tail, NULL); + fail: free(ctx.workbuf.ptr); g_clear_pointer(&ctx.meta_exif, g_bytes_unref); @@ -1024,6 +1031,7 @@ cairo_user_data_key_t fastiv_io_key_orientation; cairo_user_data_key_t fastiv_io_key_icc; cairo_user_data_key_t fastiv_io_key_frame_next; +cairo_user_data_key_t fastiv_io_key_frame_previous; cairo_user_data_key_t fastiv_io_key_frame_duration; cairo_user_data_key_t fastiv_io_key_loops; diff --git a/fastiv-io.h b/fastiv-io.h index 7bce925..20fa4f6 100644 --- a/fastiv-io.h +++ b/fastiv-io.h @@ -37,6 +37,10 @@ extern cairo_user_data_key_t fastiv_io_key_icc; /// The next frame in a sequence, as a surface, in a chain, pre-composited. /// There is no wrap-around. extern cairo_user_data_key_t fastiv_io_key_frame_next; +/// The previous frame in a sequence, as a surface, in a chain, pre-composited. +/// This is a weak pointer that wraps around, and needn't be present +/// for static images. +extern cairo_user_data_key_t fastiv_io_key_frame_previous; /// Frame duration in milliseconds as an intptr_t. extern cairo_user_data_key_t fastiv_io_key_frame_duration; /// How many times to repeat the animation, or zero for +inf, as a uintptr_t. diff --git a/fastiv-view.c b/fastiv-view.c index 1cbb837..1573ff9 100644 --- a/fastiv-view.c +++ b/fastiv-view.c @@ -452,9 +452,15 @@ fastiv_view_key_press_event(GtkWidget *widget, GdkEventKey *event) gtk_widget_queue_resize(widget); return TRUE; + case GDK_KEY_bracketleft: + if (!(self->frame = cairo_surface_get_user_data( + self->frame, &fastiv_io_key_frame_previous))) + self->frame = self->surface; + gtk_widget_queue_draw(widget); + return TRUE; case GDK_KEY_bracketright: if (!(self->frame = cairo_surface_get_user_data( - self->frame, &fastiv_io_key_frame_next))) + self->frame, &fastiv_io_key_frame_next))) self->frame = self->surface; gtk_widget_queue_draw(widget); return TRUE; |