Question

I have a sine wave that I generate with a random function. The resulting points are put into an array where the index is 0 to 799 (corresponding to my x value) and the value of said index is corresponding to the position of y.

Now, I'm trying to create a gradient that starts from green with 100% alpha and goes down 100px to green 20% alpha. Would look like the wave fades out downwards basically. I'm doing that by drawing a 1px wide x 100px high gradient starting at the y position of each point on my line.

Here is the code in my drawing function.

void *do_draw(void *ptr)
{
    /*** Prepare SIGALRM ***/
    siginfo_t info;
    sigset_t sigset;

    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);

    while(1)
    {
        while(sigwaitinfo(&sigset, &info) > 0)
        {
            currently_drawing = 1;

            int width, height;
            gdk_threads_enter();
            gdk_drawable_get_size(pixmap, &width, &height);
            gdk_threads_leave();

            /*** Create surface to draw on ***/
            cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
            cairo_t *cr = cairo_create(cst);

            /*** Draw stuff ***/
            static int i = 0;
            ++i; i = i % 800;
            cairo_set_source_rgba (cr, .0, .0, .0, 1);
            cairo_paint(cr);

            int j = 0;
            for (j = 0; j < 799; ++j)
            {
                double y = (double)(height + sine[j]) / 2;

                cairo_pattern_t *pat1;  
                pat1 = cairo_pattern_create_linear(j, y, j, y + 100);

                cairo_pattern_add_color_stop_rgba(pat1, 0.1, 0, 1, 0, 1);
                cairo_pattern_add_color_stop_rgba(pat1, 0.9, 0, 1, 0, 0.2);

                cairo_rectangle(cr, j, y, j, y + 100);
                cairo_set_source(cr, pat1);
                cairo_fill(cr);

                cairo_pattern_destroy(pat1);    
            }



            cairo_destroy(cr);

            gdk_threads_enter();

            cairo_t *cr_pixmap = gdk_cairo_create(pixmap);
            cairo_set_source_surface(cr_pixmap, cst, 0, 0);
            cairo_paint(cr_pixmap);
            cairo_destroy(cr_pixmap);

            gdk_threads_leave();
            cairo_surface_destroy(cst);

            currently_drawing = 0;

        }
    }
}

The result I get at the moment is just a 20% alpha green 100px thick line but it does follow my coordinates. How do I get this gradient to work? I'm not understanding how the gradient space works I think.

Was it helpful?

Solution

I turned this into some freestanding code that can actually be compiled and tested and then noticed that your call to cairo_rectangle() is wrong. The arguments to this functions are:

  • x
  • y
  • width
  • height

You are passing in:

  • j
  • y
  • j
  • y + 100

So larger values result in larger and larger rectangles being used. I assume you want these arguments instead:

  • j
  • y
  • 1
  • 100

For reference, here is my code:

#include <cairo.h>
#include <math.h>

int main(void)
{
    int width = 800, height = 800;
    int sine[800];

    int k;
    for (k = 0; k < 800; k++) {
        sine[k] = height * sin(k*M_PI/180);
    }

    /*** Create surface to draw on ***/
    cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
    cairo_t *cr = cairo_create(cst);

    /*** Draw stuff ***/
    static int i = 0;
    ++i; i = i % 800;
    cairo_set_source_rgba (cr, .0, .0, .0, 1);
    cairo_paint(cr);

    int j = 0;
    for (j = 0; j < 799; ++j)
    {
        double y = (double)(height + sine[j]) / 2;

        cairo_pattern_t *pat1;
        pat1 = cairo_pattern_create_linear(j, y, j, y + 100);

        cairo_pattern_add_color_stop_rgba(pat1, 0.1, 0, 1, 0, 1);
        cairo_pattern_add_color_stop_rgba(pat1, 0.9, 0, 1, 0, 0.2);

        cairo_rectangle(cr, j, y, 1, 100);
        cairo_set_source(cr, pat1);
        cairo_fill(cr);

        cairo_pattern_destroy(pat1);
    }

    cairo_destroy(cr);
    cairo_surface_write_to_png(cst, "t.png");
    cairo_surface_destroy(cst);

    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top