Gradient function




Hello all,

I got this gradient creation function from the XFCE 4.2 source code. I can read the code and understand it, I 
know what the different data types do, I just could understand the GdkPixdata type, and how is information 
stored in it. I cannot also understand the logic behind it (especially that 8 bit offset). Could anyone 
explain me how it works?
Also, what happens when I assign a negative number or a number greater than 65535 to one of the color 
properties of a GdkColor variable?

Thanks a lot, and here is the code:

#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk-pixbuf/gdk-pixdata.h>

static GdkPixbuf *
create_gradient(GdkColor *color1, GdkColor *color2, gint width, gint height, gint horz)
{
        GdkPixbuf *pix;
        gint i, j;
        GdkPixdata pixdata;
        guint8 rgb[3];
        GError *err = NULL;

        g_return_val_if_fail(color1!=NULL && color2!=NULL, NULL);
        g_return_val_if_fail(width > 0 && height > 0, NULL);
        g_return_val_if_fail(horz == 1 || horz == 0, NULL);
        
        pixdata.magic = GDK_PIXBUF_MAGIC_NUMBER;
        pixdata.length = GDK_PIXDATA_HEADER_LENGTH + (width * height * 3);
        pixdata.pixdata_type = GDK_PIXDATA_COLOR_TYPE_RGB
                        | GDK_PIXDATA_SAMPLE_WIDTH_8 | GDK_PIXDATA_ENCODING_RAW;
        pixdata.rowstride = width * 3;
        pixdata.width = width;
        pixdata.height = height;
        pixdata.pixel_data = g_malloc(width * height * 3);

        if(horz) {
                for(i = 0; i < width; i++) {
                        rgb[0] = (color1->red + (i * (color2->red - color1->red) / width)) >> 8;
                        rgb[1] = (color1->green + (i * (color2->green - color1->green) / width)) >> 8;
                        rgb[2] = (color1->blue + (i * (color2->blue - color1->blue) / width)) >> 8;
                        memcpy(pixdata.pixel_data+(i*3), rgb, 3);
                }
                
                for(i = 1; i < height; i++) {
                        memcpy(pixdata.pixel_data+(i*pixdata.rowstride),
                                        pixdata.pixel_data, pixdata.rowstride);
                }
        } else {
                for(i = 0; i < height; i++) {
                        rgb[0] = (color1->red + (i * (color2->red - color1->red) / height)) >> 8;
                        rgb[1] = (color1->green + (i * (color2->green - color1->green) / height)) >> 8;
                        rgb[2] = (color1->blue + (i * (color2->blue - color1->blue) / height)) >> 8;
                        for(j = 0; j < width; j++)
                                memcpy(pixdata.pixel_data+(i*pixdata.rowstride)+(j*3), rgb, 3);
                }
        }
        
        pix = gdk_pixbuf_from_pixdata(&pixdata, TRUE, &err);

        if(!pix) exit(1);

        return pix;
}

-----------------
César L. B. Silveira
Linux user #365512
PC: Slackware 10.0 + Kernel 2.6.10 + Dropline GNOME 2.8.3
Notebook: Slackware 10.0 + Kernel 2.6.11.3 + XFCE



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]