diff options
Diffstat (limited to 'pics.c')
-rw-r--r-- | pics.c | 208 |
1 files changed, 208 insertions, 0 deletions
@@ -0,0 +1,208 @@ +#include <cairo.h> + +#define CHECK_SIZE 16 + +static cairo_t * +get_cairo (int width, int height) +{ + cairo_surface_t *target = + cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + cairo_t *cr; + int i, j; + + cr = cairo_create (target); + + for (i = 0; i < width; i += CHECK_SIZE) + for (j = 0; j < height; j += CHECK_SIZE) + { + int light = !!(((i / CHECK_SIZE) ^ (j / CHECK_SIZE)) & 1); + + if (light) + cairo_set_source_rgb (cr, 0.95, 0.95, 0.95); + else + cairo_set_source_rgb (cr, 0.9, 0.9, 0.9); + + cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE); + cairo_fill (cr); + } + return cr; +} + +static void +finish (cairo_t *cr, const char *filename) +{ + cairo_surface_t *target = cairo_get_target (cr); + + cairo_surface_write_to_png (target, filename); + cairo_surface_destroy (target); + cairo_destroy (cr); +} + +static void +draw_ampersand (cairo_t *cr) +{ + cairo_rel_move_to (cr, 5, 70.0); + cairo_select_font_face (cr, "Sans", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size (cr, 80); + cairo_text_path (cr, "&"); + cairo_set_source_rgb (cr, 0.2, 0.2, 0.4); + cairo_fill (cr); +} + +static void +draw_polygon (cairo_t *cr) +{ + cairo_rel_move_to (cr, 10, 10); + cairo_rel_line_to (cr, 65, 35); + cairo_rel_line_to (cr, -38, 35); + + cairo_set_source_rgb (cr, 0.8, 0.3, 0.2); + cairo_fill (cr); +} + +static void +create_ampersand (void) +{ + cairo_t *cr = get_cairo (80, 80); + + draw_ampersand (cr); + + finish (cr, "ampersand.png"); +} + +static void +create_polygon (void) +{ + cairo_t *cr = get_cairo (80, 80); + + draw_polygon (cr); + + finish (cr, "polygon.png"); +} + +static struct { + char name[16]; + cairo_operator_t op; +} ops[] = + { + "Source", CAIRO_OPERATOR_SOURCE, + "Over", CAIRO_OPERATOR_OVER, + "Atop", CAIRO_OPERATOR_ATOP, + "In", CAIRO_OPERATOR_IN, + "Out", CAIRO_OPERATOR_OUT, + + "Dest", CAIRO_OPERATOR_DEST, + "Dest Over", CAIRO_OPERATOR_DEST_OVER, + "Dest Atop", CAIRO_OPERATOR_DEST_ATOP, + "Dest In", CAIRO_OPERATOR_DEST_IN, + "Dest Out", CAIRO_OPERATOR_DEST_OUT, + + "Clear", CAIRO_OPERATOR_CLEAR, + "Xor", CAIRO_OPERATOR_XOR, + }; + +static void +draw_source (cairo_t *cr) +{ + draw_polygon (cr); +} + +static void +draw_dest (cairo_t *cr) +{ + draw_ampersand (cr); +} + +static void +centered_text (cairo_t *cr, double x, double y, const char *text) +{ + double x1, y1, x2, y2; + + cairo_save (cr); + cairo_select_font_face (cr, "Sans", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_NORMAL); + cairo_new_path (cr); + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_font_size (cr, 14.0); + cairo_text_path (cr, text); + cairo_path_extents (cr, &x1, &y1, &x2, &y2); + cairo_new_path (cr); + printf ("in x %f %f %s\n", x, x2 - x1, text); + cairo_move_to (cr, x - (x2 - x1) / 2.0, y); + cairo_show_text (cr, text); + cairo_restore (cr); +} + +static void +create_porter_duff_table (void) +{ +#define CELL_WIDTH 120 +#define CELL_HEIGHT 130 +#define XPAD (CELL_WIDTH / 4) +#define YPAD (CELL_WIDTH / 4) + + cairo_t *cr = get_cairo (CELL_WIDTH * 5 + XPAD, + (CELL_HEIGHT) * 3 + 2 * YPAD); + int i; + + for (i = 0; i < 12; ++i) + { + double x = CELL_WIDTH * (i % 5) + XPAD; + double y = CELL_HEIGHT * (i / 5) + YPAD; + + cairo_save (cr); + + printf ("move to %f %f for %s\n", x, y, ops[i].name); + cairo_push_group (cr); + + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_rectangle (cr, x, y, CELL_WIDTH, CELL_HEIGHT); + cairo_clip (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + + /* Cairo's source and clear are clip-to-self, but we + * want to draw the actual Porter/Duff operator, + * so those need to be special cased. + */ + if (ops[i].op == CAIRO_OPERATOR_SOURCE) + { + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_move_to (cr, x, y); + draw_source (cr); + } + else if (ops[i].op != CAIRO_OPERATOR_CLEAR) + { + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_move_to (cr, x, y); + draw_dest (cr); + cairo_move_to (cr, x, y); + cairo_set_operator (cr, ops[i].op); + draw_source (cr); + } + + centered_text (cr, + x + CELL_WIDTH / 2.0 - 20.0, + y + CELL_HEIGHT - 30, ops[i].name); + + cairo_pop_group_to_source (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_paint (cr); + cairo_restore (cr); + + } + finish (cr, "table.png"); +} + +int +main (int argc, char *argv) +{ + create_ampersand (); + create_polygon (); + create_porter_duff_table (); +} |