aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-11-26 20:54:08 +0100
committerPřemysl Eric Janouch <p@janouch.name>2021-11-26 20:54:41 +0100
commit18e96d8c9dd6b0346514121facf8137f13ccd6dc (patch)
tree96db29d63a69be5cab71c907822a6e4899d0c59b
parentbd7f2f8c987772704a5889790b2dc06fa087ee62 (diff)
downloadfiv-18e96d8c9dd6b0346514121facf8137f13ccd6dc.tar.gz
fiv-18e96d8c9dd6b0346514121facf8137f13ccd6dc.tar.xz
fiv-18e96d8c9dd6b0346514121facf8137f13ccd6dc.zip
Allow frame iteration in both directions
-rw-r--r--fastiv-io.c8
-rw-r--r--fastiv-io.h4
-rw-r--r--fastiv-view.c8
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;