Hi

I wrote this ages ago but failed to do anything further with it.  I've
just cleaned it up and checked it still builds.

It stops GIF animations when they are no longer being used, rather
than waiting for them to be destroyed.  This prevents NetSurf from
wasting time cycling through frames when there is nothing to see.

Chris
diff --git a/content/content.c b/content/content.c
index d5eff46..3438239 100644
--- a/content/content.c
+++ b/content/content.c
@@ -670,6 +670,9 @@ bool content_add_user(struct content *c,
        user->next = c->user_list->next;
        c->user_list->next = user;
 
+       if (c->handler->add_user != NULL)
+               c->handler->add_user(c);
+
        return true;
 }
 
@@ -699,6 +702,10 @@ void content_remove_user(struct content *c,
                assert(0);
                return;
        }
+
+       if (c->handler->remove_user != NULL)
+               c->handler->remove_user(c);
+
        next = user->next;
        user->next = next->next;
        free(next);
diff --git a/content/content_protected.h b/content/content_protected.h
index 7311da6..e5ff1ca 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -82,6 +82,8 @@ struct content_handler {
        bool (*matches_quirks)(const struct content *c, bool quirks);
        const char *(*get_encoding)(const struct content *c, enum 
content_encoding_type op);
        content_type (*type)(void);
+       void (*add_user)(struct content *c);
+       void (*remove_user)(struct content *c);
 
         /** handler dependant content sensitive internal data interface. */
        void * (*get_internal)(const struct content *c, void *context);
diff --git a/image/gif.c b/image/gif.c
index 3f5f630..fb0985a 100644
--- a/image/gif.c
+++ b/image/gif.c
@@ -392,6 +392,31 @@ static nserror nsgif_clone(const struct content *old, 
struct content **newc)
        return NSERROR_OK;
 }
 
+static void nsgif_add_user(struct content *c)
+{
+       nsgif_content *gif = (nsgif_content *) c;
+
+       /* Ensure this content has already been converted.
+        * If it hasn't, the animation will start at the conversion phase 
instead. */
+       if (gif->gif == NULL) return;
+
+       if (content_count_users(c) == 1) {
+               /* First user, and content already converted, so start the 
animation. */
+               if (gif->gif->frame_count_partial > 1) {
+                       guit->browser->schedule(gif->gif->frames[0].frame_delay 
* 10,
+                               nsgif_animate, c);
+               }
+       }
+}
+
+static void nsgif_remove_user(struct content *c)
+{
+       if (content_count_users(c) == 1) {
+               /* Last user is about to be removed from this content, so stop 
the animation. */
+               guit->browser->schedule(-1, nsgif_animate, c);
+       }
+}
+
 static void *nsgif_get_internal(const struct content *c, void *context)
 {
        nsgif_content *gif = (nsgif_content *) c;
@@ -415,6 +440,8 @@ static const content_handler nsgif_content_handler = {
        .destroy = nsgif_destroy,
        .redraw = nsgif_redraw,
        .clone = nsgif_clone,
+       .add_user = nsgif_add_user,
+       .remove_user = nsgif_remove_user,
        .get_internal = nsgif_get_internal,
        .type = nsgif_content_type,
        .no_share = false,

Reply via email to