static void
update_pixbufs (UmCropArea *area)
{
        gint width;
        gint height;
        GtkAllocation allocation;
        gdouble scale;
        GdkRGBA color;
        guint32 pixel;
        gint dest_x, dest_y, dest_width, dest_height;
        GtkWidget *widget;
        GtkStyleContext *context;

        widget = GTK_WIDGET (area);
        gtk_widget_get_allocation (widget, &allocation);
        context = gtk_widget_get_style_context (widget);

        if (area->priv->pixbuf == NULL ||
            gdk_pixbuf_get_width (area->priv->pixbuf) != allocation.width ||
            gdk_pixbuf_get_height (area->priv->pixbuf) != allocation.height) {
                if (area->priv->pixbuf != NULL)
                        g_object_unref (area->priv->pixbuf);
                area->priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
                                                     gdk_pixbuf_get_has_alpha (area->priv->browse_pixbuf),
                                                     8,
                                                     allocation.width, allocation.height);

                gtk_style_context_get_background_color (context, gtk_style_context_get_state (context), &color);
                pixel = (((gint)(color.red * 1.0)) << 16) |
                        (((gint)(color.green * 1.0)) << 8) |
                         ((gint)(color.blue * 1.0));
                gdk_pixbuf_fill (area->priv->pixbuf, pixel);

                width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
                height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);

                scale = allocation.height / (gdouble)height;
                if (scale * width > allocation.width)
                    scale = allocation.width / (gdouble)width;

                dest_width = width * scale;
                dest_height = height * scale;
                dest_x = (allocation.width - dest_width) / 2;
                dest_y = (allocation.height - dest_height) / 2,

                gdk_pixbuf_scale (area->priv->browse_pixbuf,
                                  area->priv->pixbuf,
                                  dest_x, dest_y,
                                  dest_width, dest_height,
                                  dest_x, dest_y,
                                  scale, scale,
                                  GDK_INTERP_BILINEAR);

                if (area->priv->color_shifted)
                        g_object_unref (area->priv->color_shifted);
                area->priv->color_shifted = gdk_pixbuf_copy (area->priv->pixbuf);
                shift_colors (area->priv->color_shifted, -32, -32, -32, 0);

                if (area->priv->scale == 0.0) {
                        area->priv->crop.width = 2 * area->priv->base_width / scale;
                        area->priv->crop.height = 2 * area->priv->base_height / scale;
                        area->priv->crop.x = (gdk_pixbuf_get_width (area->priv->browse_pixbuf) - area->priv->crop.width) / 2;
                        area->priv->crop.y = (gdk_pixbuf_get_height (area->priv->browse_pixbuf) - area->priv->crop.height) / 2;
                }

                area->priv->scale = scale;
                area->priv->image.x = dest_x;
                area->priv->image.y = dest_y;
                area->priv->image.width = dest_width;
                area->priv->image.height = dest_height;
        }
}
Ejemplo n.º 2
0
/*
 * update_pixbufs:
 * @area: a #UmCropArea
 *
 * Update the #GdkPixbuf objects inside @area, by darkening the regions outside
 * the current crop area.
 */
static void
update_pixbufs (UmCropArea *area)
{
        UmCropAreaPrivate *priv = um_crop_area_get_instance_private (area);
        gint width;
        gint height;
        GtkAllocation allocation;
        gdouble scale;
        gint dest_width, dest_height;
        GtkWidget *widget;

        widget = GTK_WIDGET (area);
        gtk_widget_get_allocation (widget, &allocation);

        width = gdk_pixbuf_get_width (priv->browse_pixbuf);
        height = gdk_pixbuf_get_height (priv->browse_pixbuf);

        scale = allocation.height / (gdouble)height;
        if (scale * width > allocation.width)
                scale = allocation.width / (gdouble)width;

        dest_width = width * scale;
        dest_height = height * scale;

        if (priv->pixbuf == NULL ||
            gdk_pixbuf_get_width (priv->pixbuf) != allocation.width ||
            gdk_pixbuf_get_height (priv->pixbuf) != allocation.height) {
                if (priv->pixbuf != NULL)
                        g_object_unref (priv->pixbuf);
                priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
                                                     gdk_pixbuf_get_has_alpha (priv->browse_pixbuf),
                                                     8,
                                                     dest_width, dest_height);
                gdk_pixbuf_fill (priv->pixbuf, 0x0);

                gdk_pixbuf_scale (priv->browse_pixbuf,
                                  priv->pixbuf,
                                  0, 0,
                                  dest_width, dest_height,
                                  0, 0,
                                  scale, scale,
                                  GDK_INTERP_BILINEAR);

                if (priv->color_shifted)
                        g_object_unref (priv->color_shifted);
                priv->color_shifted = gdk_pixbuf_copy (priv->pixbuf);
                shift_colors (priv->color_shifted, -32, -32, -32, 0);

                if (priv->scale == 0.0) {
                        gdouble scale_to_80, scale_to_image, crop_scale;

                        /* Scale the crop rectangle to 80% of the area, or less to fit the image */
                        scale_to_80 = MIN ((gdouble)gdk_pixbuf_get_width (priv->pixbuf) * 0.8 / priv->base_width,
                                           (gdouble)gdk_pixbuf_get_height (priv->pixbuf) * 0.8 / priv->base_height);
                        scale_to_image = MIN ((gdouble)dest_width / priv->base_width,
                                              (gdouble)dest_height / priv->base_height);
                        crop_scale = MIN (scale_to_80, scale_to_image);

                        priv->crop.width = crop_scale * priv->base_width / scale;
                        priv->crop.height = crop_scale * priv->base_height / scale;
                        priv->crop.x = (gdk_pixbuf_get_width (priv->browse_pixbuf) - priv->crop.width) / 2;
                        priv->crop.y = (gdk_pixbuf_get_height (priv->browse_pixbuf) - priv->crop.height) / 2;
                }

                priv->scale = scale;
                priv->image.x = (allocation.width - dest_width) / 2;
                priv->image.y = (allocation.height - dest_height) / 2;
                priv->image.width = dest_width;
                priv->image.height = dest_height;
        }
}