00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "gradient.h"
00024 #include <gtk/gtk.h>
00025
00026 typedef void (* RenderGradientFunc) (GdkDrawable *drawable,
00027 GdkGC *gc,
00028 int width,
00029 int height);
00030
00031 static void
00032 draw_checkerboard (GdkDrawable *drawable,
00033 int width,
00034 int height)
00035 {
00036 gint i, j, xcount, ycount;
00037 GdkGC *gc1, *gc2;
00038 GdkColor color;
00039
00040 #define CHECK_SIZE 10
00041 #define SPACING 2
00042
00043
00044
00045
00046
00047 gc1 = gdk_gc_new (drawable);
00048 color.red = 30000;
00049 color.green = 30000;
00050 color.blue = 30000;
00051 gdk_gc_set_rgb_fg_color (gc1, &color);
00052
00053 gc2 = gdk_gc_new (drawable);
00054 color.red = 50000;
00055 color.green = 50000;
00056 color.blue = 50000;
00057 gdk_gc_set_rgb_fg_color (gc2, &color);
00058
00059 xcount = 0;
00060 i = SPACING;
00061 while (i < width)
00062 {
00063 j = SPACING;
00064 ycount = xcount % 2;
00065 while (j < height)
00066 {
00067 GdkGC *gc;
00068
00069 if (ycount % 2)
00070 gc = gc1;
00071 else
00072 gc = gc2;
00073
00074
00075
00076
00077
00078 gdk_draw_rectangle (drawable,
00079 gc,
00080 TRUE,
00081 i, j,
00082 CHECK_SIZE,
00083 CHECK_SIZE);
00084
00085 j += CHECK_SIZE + SPACING;
00086 ++ycount;
00087 }
00088
00089 i += CHECK_SIZE + SPACING;
00090 ++xcount;
00091 }
00092
00093 g_object_unref (G_OBJECT (gc1));
00094 g_object_unref (G_OBJECT (gc2));
00095 }
00096
00097 static void
00098 render_simple (GdkDrawable *drawable,
00099 GdkGC *gc,
00100 int width, int height,
00101 MetaGradientType type,
00102 gboolean with_alpha)
00103 {
00104 GdkPixbuf *pixbuf;
00105 GdkColor from, to;
00106
00107 gdk_color_parse ("blue", &from);
00108 gdk_color_parse ("green", &to);
00109
00110 pixbuf = meta_gradient_create_simple (width, height,
00111 &from, &to,
00112 type);
00113
00114 if (with_alpha)
00115 {
00116 const unsigned char alphas[] = { 0xff, 0xaa, 0x2f, 0x0, 0xcc, 0xff, 0xff };
00117
00118 if (!gdk_pixbuf_get_has_alpha (pixbuf))
00119 {
00120 GdkPixbuf *new_pixbuf;
00121
00122 new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
00123 g_object_unref (G_OBJECT (pixbuf));
00124 pixbuf = new_pixbuf;
00125 }
00126
00127 meta_gradient_add_alpha (pixbuf,
00128 alphas, G_N_ELEMENTS (alphas),
00129 META_GRADIENT_HORIZONTAL);
00130
00131 draw_checkerboard (drawable, width, height);
00132 }
00133
00134 gdk_draw_pixbuf (drawable,
00135 gc,
00136 pixbuf,
00137 0, 0,
00138 0, 0, width, height,
00139 GDK_RGB_DITHER_MAX,
00140 0, 0);
00141
00142 g_object_unref (G_OBJECT (pixbuf));
00143 }
00144
00145 static void
00146 render_vertical_func (GdkDrawable *drawable,
00147 GdkGC *gc,
00148 int width, int height)
00149 {
00150 render_simple (drawable, gc, width, height, META_GRADIENT_VERTICAL, FALSE);
00151 }
00152
00153 static void
00154 render_horizontal_func (GdkDrawable *drawable,
00155 GdkGC *gc,
00156 int width, int height)
00157 {
00158 render_simple (drawable, gc, width, height, META_GRADIENT_HORIZONTAL, FALSE);
00159 }
00160
00161 static void
00162 render_diagonal_func (GdkDrawable *drawable,
00163 GdkGC *gc,
00164 int width, int height)
00165 {
00166 render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL, FALSE);
00167 }
00168
00169 static void
00170 render_diagonal_alpha_func (GdkDrawable *drawable,
00171 GdkGC *gc,
00172 int width, int height)
00173 {
00174 render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL, TRUE);
00175 }
00176
00177 static void
00178 render_multi (GdkDrawable *drawable,
00179 GdkGC *gc,
00180 int width, int height,
00181 MetaGradientType type)
00182 {
00183 GdkPixbuf *pixbuf;
00184 #define N_COLORS 5
00185 GdkColor colors[N_COLORS];
00186
00187 gdk_color_parse ("red", &colors[0]);
00188 gdk_color_parse ("blue", &colors[1]);
00189 gdk_color_parse ("orange", &colors[2]);
00190 gdk_color_parse ("pink", &colors[3]);
00191 gdk_color_parse ("green", &colors[4]);
00192
00193 pixbuf = meta_gradient_create_multi (width, height,
00194 colors, N_COLORS,
00195 type);
00196
00197 gdk_pixbuf_render_to_drawable (pixbuf,
00198 drawable,
00199 gc,
00200 0, 0,
00201 0, 0, width, height,
00202 GDK_RGB_DITHER_NORMAL,
00203 0, 0);
00204
00205 g_object_unref (G_OBJECT (pixbuf));
00206 #undef N_COLORS
00207 }
00208
00209 static void
00210 render_vertical_multi_func (GdkDrawable *drawable,
00211 GdkGC *gc,
00212 int width, int height)
00213 {
00214 render_multi (drawable, gc, width, height, META_GRADIENT_VERTICAL);
00215 }
00216
00217 static void
00218 render_horizontal_multi_func (GdkDrawable *drawable,
00219 GdkGC *gc,
00220 int width, int height)
00221 {
00222 render_multi (drawable, gc, width, height, META_GRADIENT_HORIZONTAL);
00223 }
00224
00225 static void
00226 render_diagonal_multi_func (GdkDrawable *drawable,
00227 GdkGC *gc,
00228 int width, int height)
00229 {
00230 render_multi (drawable, gc, width, height, META_GRADIENT_DIAGONAL);
00231 }
00232
00233 static void
00234 render_interwoven_func (GdkDrawable *drawable,
00235 GdkGC *gc,
00236 int width, int height)
00237 {
00238 GdkPixbuf *pixbuf;
00239 #define N_COLORS 4
00240 GdkColor colors[N_COLORS];
00241
00242 gdk_color_parse ("red", &colors[0]);
00243 gdk_color_parse ("blue", &colors[1]);
00244 gdk_color_parse ("pink", &colors[2]);
00245 gdk_color_parse ("green", &colors[3]);
00246
00247 pixbuf = meta_gradient_create_interwoven (width, height,
00248 colors, height / 10,
00249 colors + 2, height / 14);
00250
00251 gdk_pixbuf_render_to_drawable (pixbuf,
00252 drawable,
00253 gc,
00254 0, 0,
00255 0, 0, width, height,
00256 GDK_RGB_DITHER_NORMAL,
00257 0, 0);
00258
00259 g_object_unref (G_OBJECT (pixbuf));
00260 }
00261
00262 static gboolean
00263 expose_callback (GtkWidget *widget,
00264 GdkEventExpose *event,
00265 gpointer data)
00266 {
00267 RenderGradientFunc func = data;
00268
00269 (* func) (widget->window,
00270 widget->style->fg_gc[widget->state],
00271 widget->allocation.width,
00272 widget->allocation.height);
00273
00274 return TRUE;
00275 }
00276
00277 static GtkWidget*
00278 create_gradient_window (const char *title,
00279 RenderGradientFunc func)
00280 {
00281 GtkWidget *window;
00282 GtkWidget *drawing_area;
00283
00284 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00285
00286 gtk_window_set_title (GTK_WINDOW (window), title);
00287
00288 drawing_area = gtk_drawing_area_new ();
00289
00290 gtk_widget_set_size_request (drawing_area, 1, 1);
00291
00292 gtk_window_set_default_size (GTK_WINDOW (window), 175, 175);
00293
00294 g_signal_connect (G_OBJECT (drawing_area),
00295 "expose_event",
00296 G_CALLBACK (expose_callback),
00297 func);
00298
00299 gtk_container_add (GTK_CONTAINER (window), drawing_area);
00300
00301 gtk_widget_show_all (window);
00302
00303 return window;
00304 }
00305
00306 static void
00307 meta_gradient_test (void)
00308 {
00309 GtkWidget *window;
00310
00311 window = create_gradient_window ("Simple vertical",
00312 render_vertical_func);
00313
00314 window = create_gradient_window ("Simple horizontal",
00315 render_horizontal_func);
00316
00317 window = create_gradient_window ("Simple diagonal",
00318 render_diagonal_func);
00319
00320 window = create_gradient_window ("Multi vertical",
00321 render_vertical_multi_func);
00322
00323 window = create_gradient_window ("Multi horizontal",
00324 render_horizontal_multi_func);
00325
00326 window = create_gradient_window ("Multi diagonal",
00327 render_diagonal_multi_func);
00328
00329 window = create_gradient_window ("Interwoven",
00330 render_interwoven_func);
00331
00332 window = create_gradient_window ("Simple diagonal with horizontal multi alpha",
00333 render_diagonal_alpha_func);
00334
00335 }
00336
00337 int
00338 main (int argc, char **argv)
00339 {
00340 gtk_init (&argc, &argv);
00341
00342 meta_gradient_test ();
00343
00344 gtk_main ();
00345
00346 return 0;
00347 }
00348