static pixman_image_t * create_linear_gradient_image (PictGradient *gradient) { PictLinearGradient *linear = (PictLinearGradient *)gradient; pixman_point_fixed_t p1; pixman_point_fixed_t p2; p1.x = linear->p1.x; p1.y = linear->p1.y; p2.x = linear->p2.x; p2.y = linear->p2.y; return pixman_image_create_linear_gradient ( &p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops); }
int main (int argc, char **argv) { #define d2f pixman_double_to_fixed GtkWidget *window, *swindow; GtkWidget *table; uint32_t *dest = malloc (WIDTH * HEIGHT * 4); uint32_t *src = malloc (WIDTH * HEIGHT * 4); pixman_image_t *src_img; pixman_image_t *dest_img; pixman_point_fixed_t p1 = { -10 << 0, 0 }; pixman_point_fixed_t p2 = { WIDTH << 16, (HEIGHT - 10) << 16 }; uint16_t full = 0xcfff; uint16_t low = 0x5000; uint16_t alpha = 0xffff; pixman_gradient_stop_t stops[6] = { { d2f (0.0), { full, low, low, alpha } }, { d2f (0.25), { full, full, low, alpha } }, { d2f (0.4), { low, full, low, alpha } }, { d2f (0.6), { low, full, full, alpha } }, { d2f (0.8), { low, low, full, alpha } }, { d2f (1.0), { full, low, full, alpha } }, }; int i; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL); table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE); src_img = pixman_image_create_linear_gradient (&p1, &p2, stops, G_N_ELEMENTS (stops)); pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD); dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); pixman_image_set_accessors (dest_img, reader, writer); for (i = 0; i < G_N_ELEMENTS (operators); ++i) { GtkWidget *image; GdkPixbuf *pixbuf; GtkWidget *vbox; GtkWidget *label; int j, k; vbox = gtk_vbox_new (FALSE, 0); label = gtk_label_new (operators[i].name); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6); gtk_widget_show (label); for (j = 0; j < HEIGHT; ++j) { for (k = 0; k < WIDTH; ++k) dest[j * WIDTH + k] = 0x7f6f6f00; } pixman_image_composite (operators[i].op, src_img, NULL, dest_img, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img), TRUE, WIDTH, HEIGHT, WIDTH * 4); image = gtk_image_new_from_pixbuf (pixbuf); gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0); gtk_widget_show (image); gtk_table_attach_defaults (GTK_TABLE (table), vbox, i % 6, (i % 6) + 1, i / 6, (i / 6) + 1); gtk_widget_show (vbox); g_object_unref (pixbuf); } pixman_image_unref (src_img); free (src); pixman_image_unref (dest_img); free (dest); swindow = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table); gtk_widget_show (table); gtk_container_add (GTK_CONTAINER (window), swindow); gtk_widget_show (swindow); gtk_widget_show (window); gtk_main (); return 0; }
static cairo_status_t _cairo_gl_gradient_render (const cairo_gl_context_t *ctx, unsigned int n_stops, const cairo_gradient_stop_t *stops, void *bytes, int width) { pixman_image_t *gradient, *image; pixman_gradient_stop_t pixman_stops_stack[32]; pixman_gradient_stop_t *pixman_stops; pixman_point_fixed_t p1, p2; unsigned int i; pixman_format_code_t gradient_pixman_format; /* * Ensure that the order of the gradient's components in memory is BGRA. * This is done so that the gradient's pixel data is always suitable for * texture upload using format=GL_BGRA and type=GL_UNSIGNED_BYTE. */ if (_cairo_is_little_endian ()) gradient_pixman_format = PIXMAN_a8r8g8b8; else gradient_pixman_format = PIXMAN_b8g8r8a8; pixman_stops = pixman_stops_stack; if (unlikely (n_stops > ARRAY_LENGTH (pixman_stops_stack))) { pixman_stops = _cairo_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t)); if (unlikely (pixman_stops == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } for (i = 0; i < n_stops; i++) { pixman_stops[i].x = _cairo_fixed_16_16_from_double (stops[i].offset); pixman_stops[i].color.red = stops[i].color.red_short; pixman_stops[i].color.green = stops[i].color.green_short; pixman_stops[i].color.blue = stops[i].color.blue_short; pixman_stops[i].color.alpha = stops[i].color.alpha_short; } p1.x = _cairo_fixed_16_16_from_double (0.5); p1.y = 0; p2.x = _cairo_fixed_16_16_from_double (width - 0.5); p2.y = 0; gradient = pixman_image_create_linear_gradient (&p1, &p2, pixman_stops, n_stops); if (pixman_stops != pixman_stops_stack) free (pixman_stops); if (unlikely (gradient == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); pixman_image_set_filter (gradient, PIXMAN_FILTER_BILINEAR, NULL, 0); pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD); image = pixman_image_create_bits (gradient_pixman_format, width, 1, bytes, sizeof(uint32_t)*width); if (unlikely (image == NULL)) { pixman_image_unref (gradient); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } pixman_image_composite32 (PIXMAN_OP_SRC, gradient, NULL, image, 0, 0, 0, 0, 0, 0, width, 1); pixman_image_unref (gradient); pixman_image_unref (image); /* We need to fudge pixel 0 to hold the left-most color stop and not * the neareset stop to the zeroth pixel centre in order to correctly * populate the border color. For completeness, do both edges. */ ((uint32_t*)bytes)[0] = color_stop_to_pixel(&stops[0]); ((uint32_t*)bytes)[width-1] = color_stop_to_pixel(&stops[n_stops-1]); return CAIRO_STATUS_SUCCESS; }
int main (int argc, char **argv) { #define WIDTH 400 #define HEIGHT 200 uint32_t *dest = malloc (WIDTH * HEIGHT * 4); pixman_image_t *src_img; pixman_image_t *dest_img; int i, j, k, p; typedef struct { pixman_point_fixed_t p0; pixman_point_fixed_t p1; } point_pair_t; pixman_gradient_stop_t onestop[1] = { { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, }; pixman_gradient_stop_t subsetstops[2] = { { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, }; pixman_gradient_stop_t stops01[2] = { { pixman_int_to_fixed (0), { 0xffff, 0xeeee, 0xeeee, 0xeeee } }, { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0x1111 } } }; point_pair_t point_pairs [] = { { { pixman_double_to_fixed (0), 0 }, { pixman_double_to_fixed (WIDTH / 8.), pixman_int_to_fixed (0) } }, { { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) }, { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) } } }; pixman_transform_t transformations[] = { { { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } } }, { { { pixman_double_to_fixed (1), pixman_double_to_fixed (0), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } } }, { { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (2), pixman_double_to_fixed (1.000), pixman_double_to_fixed (1.0) } } }, { { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (0) } } }, { { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } } }, { { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (3), }, { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } } }, }; pixman_fixed_t r_inner; pixman_fixed_t r_outer; enable_divbyzero_exceptions(); for (i = 0; i < WIDTH * HEIGHT; ++i) dest[i] = 0x4f00004f; /* pale blue */ dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); r_inner = 0; r_outer = pixman_double_to_fixed (50.0); for (i = 0; i < 3; ++i) { pixman_gradient_stop_t *stops; int num_stops; if (i == 0) { stops = onestop; num_stops = ARRAY_LENGTH (onestop); } else if (i == 1) { stops = subsetstops; num_stops = ARRAY_LENGTH (subsetstops); } else { stops = stops01; num_stops = ARRAY_LENGTH (stops01); } for (j = 0; j < 3; ++j) { for (p = 0; p < ARRAY_LENGTH (point_pairs); ++p) { point_pair_t *pair = &(point_pairs[p]); if (j == 0) src_img = pixman_image_create_conical_gradient (&(pair->p0), r_inner, stops, num_stops); else if (j == 1) src_img = pixman_image_create_radial_gradient (&(pair->p0), &(pair->p1), r_inner, r_outer, stops, num_stops); else src_img = pixman_image_create_linear_gradient (&(pair->p0), &(pair->p1), stops, num_stops); for (k = 0; k < ARRAY_LENGTH (transformations); ++k) { pixman_image_set_transform (src_img, &transformations[k]); pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE); pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img, 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT); } pixman_image_unref (src_img); } } } pixman_image_unref (dest_img); free (dest); return 0; }
int main (int argc, char **argv) { #define WIDTH 400 #define HEIGHT 200 uint32_t *alpha = malloc (WIDTH * HEIGHT * 4); uint32_t *dest = malloc (WIDTH * HEIGHT * 4); uint32_t *src = malloc (WIDTH * HEIGHT * 4); pixman_image_t *grad_img; pixman_image_t *alpha_img; pixman_image_t *dest_img; pixman_image_t *src_img; int i; pixman_gradient_stop_t stops[2] = { { pixman_int_to_fixed (0), { 0x0000, 0x0000, 0x0000, 0x0000 } }, { pixman_int_to_fixed (1), { 0xffff, 0x0000, 0x1111, 0xffff } } }; pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 }; pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH), pixman_int_to_fixed (0) }; #if 0 pixman_transform_t trans = { { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } } }; #else pixman_transform_t trans = { { { pixman_fixed_1, 0, 0 }, { 0, pixman_fixed_1, 0 }, { 0, 0, pixman_fixed_1 } } }; #endif pixman_point_fixed_t c_inner; pixman_point_fixed_t c_outer; pixman_fixed_t r_inner; pixman_fixed_t r_outer; for (i = 0; i < WIDTH * HEIGHT; ++i) alpha[i] = 0x4f00004f; /* pale blue */ alpha_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, alpha, WIDTH * 4); for (i = 0; i < WIDTH * HEIGHT; ++i) dest[i] = 0xffffff00; /* yellow */ dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); for (i = 0; i < WIDTH * HEIGHT; ++i) src[i] = 0xffff0000; src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src, WIDTH * 4); c_inner.x = pixman_double_to_fixed (50.0); c_inner.y = pixman_double_to_fixed (50.0); c_outer.x = pixman_double_to_fixed (50.0); c_outer.y = pixman_double_to_fixed (50.0); r_inner = 0; r_outer = pixman_double_to_fixed (50.0); #if 0 grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner, stops, 2); #endif #if 0 grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner, stops, 2); grad_img = pixman_image_create_linear_gradient (&c_inner, &c_outer, r_inner, r_outer, stops, 2); #endif grad_img = pixman_image_create_linear_gradient (&p1, &p2, stops, 2); pixman_image_set_transform (grad_img, &trans); pixman_image_set_repeat (grad_img, PIXMAN_REPEAT_PAD); pixman_image_composite (PIXMAN_OP_OVER, grad_img, NULL, alpha_img, 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT); pixman_image_set_alpha_map (src_img, alpha_img, 10, 10); pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img, 0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT); printf ("0, 0: %x\n", dest[0]); printf ("10, 10: %x\n", dest[10 * 10 + 10]); printf ("w, h: %x\n", dest[(HEIGHT - 1) * 100 + (WIDTH - 1)]); show_image (dest_img); pixman_image_unref (src_img); pixman_image_unref (grad_img); pixman_image_unref (alpha_img); free (dest); return 0; }
int main (int argc, char **argv) { pixman_image_t *gradient_img; pixman_image_t *src_img, *dst_img; pixman_gradient_stop_t stops[2] = { { pixman_int_to_fixed (0), { 0xffff, 0x0000, 0x0000, 0xffff } }, { pixman_int_to_fixed (1), { 0xffff, 0xffff, 0x0000, 0xffff } } }; pixman_point_fixed_t p1 = { 0, 0 }; pixman_point_fixed_t p2 = { pixman_int_to_fixed (WIDTH), pixman_int_to_fixed (HEIGHT) }; pixman_point_fixed_t c_inner; pixman_point_fixed_t c_outer; pixman_fixed_t r_inner; pixman_fixed_t r_outer; pixman_region32_t clip_region; pixman_transform_t trans = { { { pixman_double_to_fixed (1.3), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.5), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.5), }, { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) } } }; src_img = create_solid_bits (0xff0000ff); c_inner.x = pixman_double_to_fixed (100.0); c_inner.y = pixman_double_to_fixed (100.0); c_outer.x = pixman_double_to_fixed (100.0); c_outer.y = pixman_double_to_fixed (100.0); r_inner = 0; r_outer = pixman_double_to_fixed (100.0); gradient_img = pixman_image_create_radial_gradient (&c_inner, &c_outer, r_inner, r_outer, stops, 2); #if 0 gradient_img = pixman_image_create_linear_gradient (&p1, &p2, stops, 2); #endif pixman_image_composite (PIXMAN_OP_OVER, gradient_img, NULL, src_img, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); pixman_region32_init_rect (&clip_region, 50, 0, 100, 200); pixman_image_set_clip_region32 (src_img, &clip_region); pixman_image_set_source_clipping (src_img, TRUE); pixman_image_set_has_client_clip (src_img, TRUE); pixman_image_set_transform (src_img, &trans); pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); dst_img = create_solid_bits (0xffff0000); pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dst_img, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); #if 0 printf ("0, 0: %x\n", src[0]); printf ("10, 10: %x\n", src[10 * 10 + 10]); printf ("w, h: %x\n", src[(HEIGHT - 1) * 100 + (WIDTH - 1)]); #endif show_image (dst_img); pixman_image_unref (gradient_img); pixman_image_unref (src_img); return 0; }