Author: akv
Date: 2010-10-27 23:46:27 +0200 (Wed, 27 Oct 2010)
New Revision: 3593

Modified:
   trunk/src/rs-store.c
Log:
Adding a bit of eyecandy...

Modified: trunk/src/rs-store.c
===================================================================
--- trunk/src/rs-store.c        2010-10-27 21:34:49 UTC (rev 3592)
+++ trunk/src/rs-store.c        2010-10-27 21:46:27 UTC (rev 3593)
@@ -1758,9 +1758,9 @@
 void
 cairo_draw_thumbnail(cairo_t *cr, GdkPixbuf *pixbuf, gint x, gint y, gint 
width, gint height, gdouble alpha)
 {
-       gdouble greyvalue = 1.0;
+       gdouble greyvalue = 0.9;
 
-       cairo_set_source_rgba(cr, greyvalue, greyvalue, greyvalue, 0.5);
+       cairo_set_source_rgba(cr, greyvalue, greyvalue, greyvalue, 1.0);
        cairo_rectangle(cr, x, y, width, height);
        cairo_fill(cr);
 
@@ -2422,60 +2422,183 @@
                                                -1);
 }
 
+/* This function is grabbed from http://stevehanov.ca/blog/index.php?id=53 */
+void cairo_image_surface_blur( cairo_surface_t* surface, double radius )
+{
+       // Steve Hanov, 2009
+       // Released into the public domain.
+
+       // get width, height
+       int width = cairo_image_surface_get_width( surface );
+       int height = cairo_image_surface_get_height( surface );
+       unsigned char* dst = (unsigned char*)malloc(width*height*4);
+       unsigned* precalc = (unsigned*)malloc(width*height*sizeof(unsigned));
+       unsigned char* src = cairo_image_surface_get_data( surface );
+       double mul=1.f/((radius*2)*(radius*2));
+       int channel;
+
+       // The number of times to perform the averaging. According to wikipedia,
+       // three iterations is good enough to pass for a gaussian.
+       const int MAX_ITERATIONS = 3;
+       int iteration;
+
+       memcpy( dst, src, width*height*4 );
+
+       for ( iteration = 0; iteration < MAX_ITERATIONS; iteration++ ) {
+               for( channel = 0; channel < 4; channel++ ) {
+                       int x,y;
+
+                       // precomputation step.
+                       unsigned char* pix = src;
+                       unsigned* pre = precalc;
+
+                       pix += channel;
+                       for (y=0;y<height;y++) {
+                               for (x=0;x<width;x++) {
+                                       int tot=pix[0];
+                                       if (x>0) tot+=pre[-1];
+                                       if (y>0) tot+=pre[-width];
+                                       if (x>0 && y>0) tot-=pre[-width-1];
+                                       *pre++=tot;
+                                       pix += 4;
+                               }
+                       }
+
+                       // blur step.
+                       pix = dst + (int)radius * width * 4 + (int)radius * 4 + 
channel;
+                       for (y=radius;y<height-radius;y++) {
+                               for (x=radius;x<width-radius;x++) {
+                                       int l = x < radius ? 0 : x - radius;
+                                       int t = y < radius ? 0 : y - radius;
+                                       int r = x + radius >= width ? width - 1 
: x + radius;
+                                       int b = y + radius >= height ? height - 
1 : y + radius;
+                                       int tot = precalc[r+b*width] + 
precalc[l+t*width] -
+                                       precalc[l+b*width] - precalc[r+t*width];
+                                       *pix=(unsigned char)(tot*mul);
+                                       pix += 4;
+                               }
+                               pix += (int)radius * 2 * 4;
+                       }
+               }
+               memcpy( src, dst, width*height*4 );
+       }
+
+       free( dst );
+       free( precalc );
+}
+
+cairo_surface_t *
+cairo_surface_make_shadow(cairo_surface_t *surface)
+{
+       GdkPixbuf *pixbuf = cairo_convert_to_pixbuf(surface);
+       guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
+       int x, y;
+       for (y = 0; gdk_pixbuf_get_height(pixbuf) > y; y++) {
+               for (x = 0; gdk_pixbuf_get_rowstride(pixbuf) > x; x+=4) {
+                       pixels[y*gdk_pixbuf_get_rowstride(pixbuf)+x+0] = 50;
+                       pixels[y*gdk_pixbuf_get_rowstride(pixbuf)+x+1] = 50;
+                       pixels[y*gdk_pixbuf_get_rowstride(pixbuf)+x+2] = 50;
+                       if (pixels[y*gdk_pixbuf_get_rowstride(pixbuf)+x+3] > 0)
+                               pixels[y*gdk_pixbuf_get_rowstride(pixbuf)+x+3] 
= 255;
+                       else
+                               pixels[y*gdk_pixbuf_get_rowstride(pixbuf)+x+3] 
= 0;
+               }
+       }
+
+       cairo_surface_t *surface_new = 
cairo_image_surface_create(cairo_image_surface_get_format(surface), 
cairo_image_surface_get_width(surface), 
cairo_image_surface_get_height(surface));
+       cairo_t *cr = cairo_create(surface_new);
+
+       gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
+       cairo_paint(cr);
+
+       cairo_destroy(cr);
+
+       return surface_new;
+}
+
 GdkPixbuf *
 get_thumbnail_eyecandy(GdkPixbuf *thumbnail)
 {
        cairo_surface_t *surface;
        cairo_t *cr;
 
+       gdouble a2, b2, bb_x1, bb_x2, bb_y1, bb_y2, bb_height, bb_width;
+       gint height_centering;
+
        gint frame_size = 4; /* MAGIC CONSTANT - see cairo_draw_thumbnail() */
        gint width = gdk_pixbuf_get_width(thumbnail)+frame_size;
        gint height = gdk_pixbuf_get_height(thumbnail)+frame_size;
 
-       gdouble a2, b2, bb_x1, bb_x2, bb_y1, bb_y2, bb_height, bb_width, 
xoffset, yoffset, border = 1;
+       gint calc_width = width+8*3;
+       gint calc_height = 128+8*3;
 
-       gdouble random = g_random_double_range(-0.05, 0.05);
+       gdouble random = 0.0; /* only for use when rotating */
 
-       if (random > 0.0) {
-               calc_rotated_coordinats((0-(width/2)), 0, random, &a2, &b2);
+#ifdef EXPERIMENTAL
+       /* Overwrite random if we want rotation */
+       random = g_random_double_range(-0.05, 0.05);
+#endif
+
+       if (random > 0.0) {     
+               calc_rotated_coordinats((0-(calc_width/2)), 0, random, &a2, 
&b2);
                bb_x1 = a2;
 
-               calc_rotated_coordinats((width/2), 128, random, &a2, &b2);
+               calc_rotated_coordinats((calc_width/2), calc_height, random, 
&a2, &b2);
                bb_x2 = a2;
 
-               calc_rotated_coordinats((0-(width/2)), 128, random, &a2, &b2);
+               calc_rotated_coordinats((0-(calc_width/2)), calc_height, 
random, &a2, &b2);
                bb_y1 = b2;
 
-               calc_rotated_coordinats((width/2), 0, random, &a2, &b2);
+               calc_rotated_coordinats((calc_width/2), 0, random, &a2, &b2);
                bb_y2 = b2;
        } else {
-               calc_rotated_coordinats((0-(width/2)), 128, random, &a2, &b2);
+               calc_rotated_coordinats((0-(calc_width/2)), calc_height, 
random, &a2, &b2);
                bb_x1 = a2;
 
-               calc_rotated_coordinats((width/2), 0, random, &a2, &b2);
+               calc_rotated_coordinats((calc_width/2), 0, random, &a2, &b2);
                bb_x2 = a2;
 
-               calc_rotated_coordinats((width/2), 128, random, &a2, &b2);
+               calc_rotated_coordinats((calc_width/2), calc_height, random, 
&a2, &b2);
                bb_y1 = b2;
 
-               calc_rotated_coordinats(0-(width/2), 0, random, &a2, &b2);
+               calc_rotated_coordinats(0-(calc_width/2), 0, random, &a2, &b2);
                bb_y2 = b2;
        }
 
        /* Calculate the magic numbers */
-       bb_height = ((bb_y1-bb_y2)+border*2);
-       bb_width = ((bb_x1*-1+bb_x2+10)+border*2);
-       xoffset = (bb_x2+bb_x1)/2*-1;
-       yoffset = (128-(bb_y1-(128)))*-1;
+       bb_height = (bb_y1-bb_y2);
+       bb_width = (bb_x1*-1+bb_x2);
 
        surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bb_width, 
bb_height);
        cr = cairo_create(surface);
 
        cairo_translate(cr, bb_width/2, bb_height/2);
+
+#ifdef EXPERIMENTAL
        cairo_rotate(cr, random);
-       cairo_draw_thumbnail(cr, thumbnail, width/2*-1, height/2*-1, width, 
height, 0.0);
+#endif
 
+       /* Only adjust height when it's a landscape mode photo */
+       if (width > height)
+               height_centering = ((bb_height-height)/2)-8;
+       else
+               height_centering = 0;
+
+       cairo_draw_thumbnail(cr, thumbnail, bb_width/2*-1+12, 
bb_height/2*-1+12+height_centering, width, height, 0.0);
+       surface = cairo_surface_make_shadow(surface);
        cairo_destroy(cr);
+       cr = cairo_create(surface);
+
+       cairo_image_surface_blur(surface, 4.0);
+       cairo_translate(cr, bb_width/2, bb_height/2);
+
+#ifdef EXPERIMENTAL
+       cairo_rotate(cr, random);
+#endif
+
+       cairo_draw_thumbnail(cr, thumbnail, bb_width/2*-1+4, 
bb_height/2*-1+4+height_centering, width, height, 0.0);
+
+       cairo_destroy(cr);
        GdkPixbuf *pixbuf = cairo_convert_to_pixbuf(surface);
 
        return pixbuf;
@@ -2495,7 +2618,7 @@
                /* We will use this, if no thumbnail can be loaded */
                pixbuf = gtk_widget_render_icon(GTK_WIDGET(job->store),
                        GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_DIALOG, NULL);
-#ifdef EXPERIMENTAL
+#if GTK_CHECK_VERSION(2,8,0)
        else
          pixbuf = get_thumbnail_eyecandy(pixbuf);
 #endif


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to