Пример #1
0
/**
 *	return number of frames per second and duration in msec
 */
gint 
pgpug_pixbuf_animation_get_detail (GdkPixbufAnimation *anim, gint *frames_count, gint *duration)
{
     //FIXME: there should be a better way to get frames count from animation     	       
     *frames_count = 0;
     *duration = 0;

     if (gdk_pixbuf_animation_is_static_image (anim)){
	  (*frames_count)++; 
	  return;
     }
     
     GTimeVal start_time = {0, 0};
     GdkPixbufAnimationIter *iter = gdk_pixbuf_animation_get_iter (anim, &start_time);
     GdkPixbuf *cur_frame, *first_frame = gdk_pixbuf_animation_iter_get_pixbuf (iter);
     int delay_time = gdk_pixbuf_animation_iter_get_delay_time (iter);

     while (delay_time > 0){

	  g_time_val_add (&start_time, delay_time*1000);

	  gboolean need_upd = gdk_pixbuf_animation_iter_advance (iter, &start_time);
	  if (need_upd){
	       (*frames_count)++; 
	       *duration += delay_time;
	  }

	  cur_frame = gdk_pixbuf_animation_iter_get_pixbuf (iter);
	  if (!need_upd || cur_frame == first_frame) {
	       delay_time = -1;
	  }
     }
     
     g_object_unref (iter);     
}
Пример #2
0
/* Auxiliary function - look for frame that's currently loading. */
static void
update_currently_loaded_frame (FrameData* frame)
{
    int tmp_count;

    if (gdk_pixbuf_animation_iter_on_currently_loading_frame(frame->iter))
        return; /* frame is currently being loaded */
    /* clear old content of pixbuf */
    if (frame->pixbuf)
        g_object_unref (frame->pixbuf);
    frame->pixbuf = NULL;

    tmp_count = 0;
    do {
        int delay_time;

        if (++tmp_count > MAX_NUMBER_FRAMES) {
            /* protection against frames repeating */
            return;
        }

        delay_time = gdk_pixbuf_animation_iter_get_delay_time (frame->iter);
        if (delay_time < 0) {
            /* this is last frame in the animation */
            return;
        }
        g_time_val_add (&frame->time, delay_time * 1000);
        gdk_pixbuf_animation_iter_advance (frame->iter, &frame->time);
    } while (!gdk_pixbuf_animation_iter_on_currently_loading_frame (frame->iter));
    /* store current content of the frame */
    frame->pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (frame->iter));
}
Пример #3
0
static void
img_cell_renderer_anim_render( GtkCellRenderer      *cell,
							   GdkDrawable          *window,
							   GtkWidget            *widget,
							   GdkRectangle         *background_a,
							   GdkRectangle         *cell_a,
							   GdkRectangle         *expose_a,
							   GtkCellRendererState  state )
{
	ImgCellRendererAnimPrivate *priv;
	GdkPixbufAnimationIter     *iter;
	GdkPixbuf                  *pixbuf;
	cairo_t                    *cr;
	GdkRectangle                rect,
								draw_rect;

	priv = IMG_CELL_RENDERER_ANIM_GET_PRIVATE ( cell );

	/* Get image size */
	img_cell_renderer_anim_get_size( cell, widget, cell_a, &rect.x,
									 &rect.y, &rect.width, &rect.height );
	rect.x += cell_a->x + cell->xpad;
	rect.y += cell_a->y + cell->ypad;
	rect.width  -= 2 * cell->xpad;
	rect.height -= 2 * cell->ypad;

	/* Check for overlaping */
	if( ! gdk_rectangle_intersect( cell_a, &rect, &draw_rect ) ||
		! gdk_rectangle_intersect( expose_a, &draw_rect, &draw_rect ) )
		return;

	/* Draw indicators */
	cr = gdk_cairo_create( window );

	/* Draw the current frame of the GdkPixbufAnimation */
	iter = g_object_get_data( G_OBJECT( priv->anim ), "iter" );
	if( ! iter )
	{
		gint delay;

		/* Initialiize iter */
		iter = gdk_pixbuf_animation_get_iter( priv->anim, NULL );
		g_object_set_data_full( G_OBJECT( priv->anim ), "iter", iter,
								(GDestroyNotify)g_object_unref );

		/* Install timeout */
		delay = gdk_pixbuf_animation_iter_get_delay_time( iter );
		gdk_threads_add_timeout( delay, (GSourceFunc)cb_timeout, iter );
	}
	g_object_set_data( G_OBJECT( iter ), "widget", widget );
	pixbuf = gdk_pixbuf_animation_iter_get_pixbuf( iter );
	gdk_cairo_set_source_pixbuf( cr, pixbuf, rect.x, rect.y );
	gdk_cairo_rectangle( cr, &draw_rect );
	cairo_fill( cr );

	cairo_destroy( cr );
}
Пример #4
0
/* prepare frame information and register other callbacks */
static void
callback_area_prepared_anim (GdkPixbufLoader* loader)
{
    GdkPixbufAnimation *anim;
    FrameData* frame_copy = g_new (FrameData, 1);

    g_signal_connect (loader, "area-updated",
                      (GCallback) callback_area_updated_anim, (gpointer) frame_copy);
    g_signal_connect (loader, "closed",
                      (GCallback) callback_closed_anim, (gpointer) frame_copy);

    frame_copy->time.tv_sec = frame_copy->time.tv_usec = 0; /* some time */

    anim = gdk_pixbuf_loader_get_animation (loader);
    frame_copy->iter = gdk_pixbuf_animation_get_iter (anim, &frame_copy->time);
    frame_copy->pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (frame_copy->iter));
    update_currently_loaded_frame (frame_copy);
}
Пример #5
0
static void
callback_area_updated_anim (GdkPixbufLoader *loader,
                            int              x,
                            int              y,
                            int              width,
                            int              height,
                            FrameData       *frame_old)
{
    GdkPixbuf *pixbuf_new;

    /* "area-updated" signal was emitted after animation had fully loaded. */
    g_assert_nonnull (frame_old->pixbuf);

    pixbuf_new = gdk_pixbuf_animation_iter_get_pixbuf (frame_old->iter);
    pixbuf_not_changed_outside_area (pixbuf_new, frame_old->pixbuf, x, y, width, height);
    gdk_pixbuf_copy_area (pixbuf_new, x, y, width, height, frame_old->pixbuf, x, y);
    update_currently_loaded_frame (frame_old);
}
Пример #6
0
void wxAnimationCtrl::OnTimer(wxTimerEvent &ev)
{
    wxASSERT(m_iter != NULL);

    // gdk_pixbuf_animation_iter_advance() will automatically restart
    // the animation, if necessary and we have no way to know !!
    if (gdk_pixbuf_animation_iter_advance(m_iter, NULL))
    {
        // start a new one-shot timer
        int n = gdk_pixbuf_animation_iter_get_delay_time(m_iter);
        if (n >= 0)
            m_timer.Start(n, true);

        gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget),
                                  gdk_pixbuf_animation_iter_get_pixbuf(m_iter));
    }
    else
    {
        // no need to update the m_widget yet
        m_timer.Start(10, true);
    }
}
Пример #7
0
static GdkPixbufAnimation*
compose_animation_from_array (animation_param_entry **anim_array, gint array_len, gint pix_size)
{
     GdkPixbufSimpleAnim *result = NULL;
     gint frames = 1, duration = 0,  duration_p, frames_p;
     /* calculate frames count as multiplication of all frames and duration as max */
     gint i;

     GTimeVal start_time = {0, 0};
     for (i = 0; i<array_len; i++){
	  /* initialize iterators for each animation*/
	  animation_param_entry *p_entry = anim_array[i];
	  
	  p_entry->iter = gdk_pixbuf_animation_get_iter (p_entry->anim, &start_time);
	  
	  frames_p = duration_p = 0;
	  pgpug_pixbuf_animation_get_detail (p_entry->anim, &frames_p, &duration_p);

	  duration = duration < duration_p ? duration_p : duration;
	  frames *= frames_p;
     }	  



     float fps = duration > 0 ? frames * 1000 / duration : 1;
     gint frame_change_time = duration / frames; 
     DEBG_MSG ("Fps: %f. frame change time :%dmsec", fps,frame_change_time);

     result = gdk_pixbuf_simple_anim_new (pix_size, pix_size, fps);
 
     gint elapsed_time = 0, frames_counter = 1;
     while (elapsed_time <= duration && frames_counter++ <= frames){

	  animation_param_entry *p_entry = anim_array[0];
	  GdkPixbuf *base_pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter));
	  g_time_val_add (&start_time, frame_change_time * 1000);
	  gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time);

	  for (i = 1; i < array_len; i++) {
	       
	       p_entry = anim_array[i];
	       GdkPixbuf *src_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter);
	       gint x_offset, y_offset, src_size;
	       src_size = gdk_pixbuf_get_width (src_pixbuf);

	       
	       pgpug_pixbuf_calculate_composition_offset (pix_size, src_size, p_entry->pos, &x_offset, &y_offset);

	       
	       gdk_pixbuf_composite (src_pixbuf, 
				     base_pixbuf,
				     x_offset, y_offset, 
				     src_size, src_size, 
				     x_offset, y_offset,
				     1.0f, 1.0f,
				     GDK_INTERP_BILINEAR, 255);
	       gboolean res;
	       res = gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time);
	       
	  }

	  gdk_pixbuf_simple_anim_add_frame (result, base_pixbuf);
	  elapsed_time += frame_change_time;
     }

     gdk_pixbuf_simple_anim_set_loop (result, TRUE);

     for (i=0;i<array_len;i++){
	  g_object_unref (anim_array[i]->iter);
     }

     return GDK_PIXBUF_ANIMATION (result);
}
Пример #8
0
void gaym_gtkconv_update_thumbnail(GaimConversation * conv, struct fetch_thumbnail_data
                                   *thumbnail_data)
{
    GaimGtkConversation *gtkconv;

    char filename[256];
    FILE *file;
    GError *err = NULL;

    size_t len;

    GdkPixbuf *buf;
    GdkPixbuf *scale;
    GdkPixmap *pm;
    GdkBitmap *bm;
    int scale_width, scale_height;


    GaimAccount *account;
    GaimPluginProtocolInfo *prpl_info = NULL;
    g_return_if_fail(conv != NULL);
    g_return_if_fail(GAIM_IS_GTK_CONVERSATION(conv));
    g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_CHAT);

    gtkconv = GAIM_GTK_CONVERSATION(conv);

    GaymChatIcon *icon_data = g_hash_table_lookup(icons, conv);

    if (!thumbnail_data)
        return;
    if (!icon_data->show_icon)
        return;

    const char *data = thumbnail_data->pic_data;
    len = thumbnail_data->pic_data_len;

    account = gaim_conversation_get_account(conv);
    if (account && account->gc)
        prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl);


    if (icon_data->anim != NULL)
        g_object_unref(G_OBJECT(icon_data->anim));

    icon_data->anim = NULL;

    if (icon_data->icon_timer != 0)
        g_source_remove(icon_data->icon_timer);

    icon_data->icon_timer = 0;

    if (icon_data->iter != NULL)
        g_object_unref(G_OBJECT(icon_data->iter));

    icon_data->iter = NULL;

    if (!gaim_prefs_get_bool
        ("/gaim/gtk/conversations/im/show_buddy_icons"))
        return;

    if (gaim_conversation_get_gc(conv) == NULL)
        return;


    /* this is such an evil hack, i don't know why i'm even considering
       it. we'll do it differently when gdk-pixbuf-loader isn't leaky
       anymore. */
    /* gdk-pixbuf-loader was leaky? is it still? */

    g_snprintf(filename, sizeof(filename),
               "%s" G_DIR_SEPARATOR_S "gaimicon-%s.%d",
               g_get_tmp_dir(), thumbnail_data->who, getpid());

    if (!(file = g_fopen(filename, "wb")))
        return;

    fwrite(data, 1, len, file);
    fclose(file);
    icon_data->anim = gdk_pixbuf_animation_new_from_file(filename, &err);

    /* make sure we remove the file as soon as possible */
    g_unlink(filename);

    if (err) {
        gaim_debug(GAIM_DEBUG_ERROR, "gtkconv",
                   "Buddy icon error: %s\n", err->message);
        g_error_free(err);
    }



    if (!icon_data->anim)
        return;

    if (gdk_pixbuf_animation_is_static_image(icon_data->anim)) {
        icon_data->iter = NULL;
        buf = gdk_pixbuf_animation_get_static_image(icon_data->anim);
    } else {
        icon_data->iter = gdk_pixbuf_animation_get_iter(icon_data->anim, NULL); /* LEAK 
                                                                                 */
        buf = gdk_pixbuf_animation_iter_get_pixbuf(icon_data->iter);
    }

    get_icon_scale_size(icon_data->anim,
                        prpl_info ? &prpl_info->icon_spec : NULL,
                        &scale_width, &scale_height);
    scale =
        gdk_pixbuf_scale_simple(buf,
                                MAX(gdk_pixbuf_get_width(buf) *
                                    scale_width /
                                    gdk_pixbuf_animation_get_width
                                    (icon_data->anim), 1),
                                MAX(gdk_pixbuf_get_height(buf) *
                                    scale_height /
                                    gdk_pixbuf_animation_get_height
                                    (icon_data->anim), 1),
                                GDK_INTERP_NEAREST);

    gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100);
    g_object_unref(G_OBJECT(scale));


    icon_data->event = gtk_event_box_new();
    gtk_container_add(GTK_CONTAINER(icon_data->frame), icon_data->event);
    gtk_widget_set_size_request(GTK_WIDGET(icon_data->frame), scale_width,
                                scale_height);

    // g_signal_connect(G_OBJECT(icon_data->event), "button-press-event",
    // G_CALLBACK(icon_menu), conv);
    gtk_widget_show(icon_data->event);
    icon_data->icon = gtk_image_new_from_pixmap(pm, bm);
    gtk_container_add(GTK_CONTAINER(icon_data->event), icon_data->icon);
    gtk_widget_show(icon_data->icon);

    g_object_unref(G_OBJECT(pm));

    if (bm)
        g_object_unref(G_OBJECT(bm));


}
static VALUE
rg_pixbuf(VALUE self)
{
    return GOBJ2RVAL(gdk_pixbuf_animation_iter_get_pixbuf(RVAL2ITR(self)));
}