2013-12-22 2 views
0

У меня есть синусоидальная волна, которую я генерирую со случайной функцией. Полученные точки помещаются в массив, где индекс равен 0-799 (соответствует моему значению x), а значение указанного индекса соответствует позиции y.(C + GTK + Cairo) Не удается получить линейные градиенты для работы

Теперь я пытаюсь создать градиент, который начинается с зеленого со 100% альфой и спускается на 100 пикселей до 20% альфа. Было бы похоже, что в основном исчезает волна вниз. Я делаю это, рисуя 1px широкий x 100px высокий градиент, начиная с y позиции каждой точки на моей линии.

Вот код в моей функции рисования.

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; 

     } 
    } 
} 

В результате я на данный момент только 20% альфа-зеленый 100px толстую линию, но это не следовать моим координатам. Как заставить этот градиент работать? Я не понимаю, как работает градиентное пространство.

ответ

2

Я превратил это в некоторый автономный код, который можно скомпилировать и протестировать, а затем заметил, что ваш вызов cairo_rectangle() неверен. Аргументы этой функции являются:

  • х
  • у
  • ширина
  • высота

Вы передаете в:

  • J
  • у
  • используется
  • J
  • у + 100

Таким образом, большие значения приводят к более крупных и более крупных прямоугольников. Я предполагаю, что вы хотите, чтобы эти аргументы вместо:

  • J
  • у

Для справки, вот мой код:

#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; 
}