summaryrefslogtreecommitdiff
path: root/pics.c
diff options
context:
space:
mode:
Diffstat (limited to 'pics.c')
-rw-r--r--pics.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/pics.c b/pics.c
new file mode 100644
index 0000000..4c6ad23
--- /dev/null
+++ b/pics.c
@@ -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 ();
+}