[cairo] Circular Ring Gradient

cecashon at aol.com cecashon at aol.com
Sun May 14 21:57:21 UTC 2017


 
Hi Olaf,

Thank you for the code example. I gave it a try. I have an offset wrong somewhere but I have it drawing well enough. Your method makes it easy to set colors, positions and draw partial rings. Compact code also. It is very slow though. Trying to get something that will redraw fast. Using Bezier curves or trapezoids for drawing a ring is significantly faster but even there I might have to save a surface after a window resize and then use that surface when drawing and animating. 

Eric

/*
    gcc -Wall ring1.c -o ring1 `pkg-config --cflags --libs gtk+-3.0`
    Tested on Ubuntu16.04 and GTK3.18
*/

#include<gtk/gtk.h>

static gboolean da_drawing(GtkWidget *da, cairo_t *cr, gpointer data);

int main(int argc, char **argv)
 {
   gtk_init(&argc, &argv);

   GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(window), "Ring Test");
   gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
   g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

   GtkWidget *da=gtk_drawing_area_new();
   gtk_widget_set_hexpand(da, TRUE);
   gtk_widget_set_vexpand(da, TRUE);
   g_signal_connect(da, "draw", G_CALLBACK(da_drawing), NULL);

   GtkWidget *grid=gtk_grid_new();
   gtk_grid_attach(GTK_GRID(grid), da, 0, 0, 1, 1);
   
   gtk_container_add(GTK_CONTAINER(window), grid);

   gtk_widget_show_all(window);

   gtk_main();

   return 0;  
 }
static gboolean da_drawing(GtkWidget *da, cairo_t *cr, gpointer data)
 { 
   GTimer *timer=g_timer_new();

   gdouble width=(gdouble)gtk_widget_get_allocated_width(da);
   gdouble height=(gdouble)gtk_widget_get_allocated_height(da);

   cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
   cairo_paint(cr);

   gdouble Size=300.0;
   gdouble Radius1=60.0;
   gdouble Radius2=120.0;
   gdouble StartDeg=0.0;
   gdouble DistDeg=360.0;   

   gint i=0;
   gint Steps = (gint)(Size * DistDeg / 360.0 * G_PI * 2.0);
   g_print("Steps %i\n", Steps);
   cairo_pattern_t *Pat=cairo_pattern_create_linear(1.0, 0.0, 2.0 * (gdouble)Steps - 1.0, 0.0);
   cairo_pattern_add_color_stop_rgb(Pat, 0.0, 1.0, 0.0, 0.0);
   cairo_pattern_add_color_stop_rgb(Pat, 1.0/8.0, 1.0, 1.0, 0.0);
   cairo_pattern_add_color_stop_rgb(Pat, 2.0/8.0, 0.0, 1.0, 0.0);
   cairo_pattern_add_color_stop_rgb(Pat, 3.0/8.0, 0.0, 1.0, 1.0);
   cairo_pattern_add_color_stop_rgb(Pat, 4.0/8.0, 0.0, 0.0, 1.0);
   cairo_pattern_add_color_stop_rgb(Pat, 5.0/8.0, 1.0, 1.0, 0.0);
   cairo_pattern_add_color_stop_rgb(Pat, 6.0/8.0, 0.0, 1.0, 0.0);
   cairo_pattern_add_color_stop_rgb(Pat, 7.0/8.0, 0.0, 1.0, 1.0);
   cairo_pattern_add_color_stop_rgb(Pat, 1.0, 1.0, 0.0, 0.0);
   cairo_set_source(cr, Pat);

   cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
   cairo_set_line_width(cr, 1.35);
   cairo_translate(cr, width/2.0, height/2.0);
   cairo_rotate(cr, (StartDeg + DistDeg / (gdouble)Steps * 0.5 - 90)*G_PI/180.0);

   cairo_matrix_t matrix;
   cairo_matrix_init_translate(&matrix, 1.0, 0.0);
   cairo_pattern_set_matrix(Pat, &matrix); 

   cairo_set_source(cr, Pat);
  
   for(i=0;i<Steps;i++)
     {
       cairo_move_to(cr, 0.0, Radius1+cairo_get_line_width(cr));
       cairo_line_to(cr, 0.0, Radius2-cairo_get_line_width(cr));
       cairo_stroke(cr);
       cairo_rotate(cr, (DistDeg / (gdouble)Steps)*G_PI/180.0);
       cairo_matrix_translate(&matrix, 2.0, 0.0);
       cairo_pattern_set_matrix(Pat, &matrix); 
     }

   cairo_pattern_destroy(Pat);

   g_print("Draw Time %f\n", g_timer_elapsed(timer, NULL));
   g_timer_destroy(timer);

   return FALSE;
}

 


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.cairographics.org/archives/cairo/attachments/20170514/c42753ca/attachment.html>


More information about the cairo mailing list