summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <ssp@redhat.com>2013-01-09 08:25:44 -0500
committerSøren Sandmann <ssp@redhat.com>2013-01-09 08:25:44 -0500
commit1bc7a8562261aad12957abe838e3c1ad4ae84b47 (patch)
treebf93065f3371449636549152ac091164d09b1ce4
parent16c7e28a9c8c59d06be6172ce5806005b41ba14f (diff)
diagrams
-rw-r--r--blend.txt12
-rw-r--r--pics.c88
2 files changed, 84 insertions, 16 deletions
diff --git a/blend.txt b/blend.txt
index b2b4763..72927cc 100644
--- a/blend.txt
+++ b/blend.txt
@@ -9,16 +9,14 @@ there, when it is 0, the image isn't there at all. In other words, the
alpha channel describes the the shape of the image, it does not
describe opacity. The reason we have alpha values between 0 and 1 is
so that the shape can be antialiased. The way to think of images with
-an alpha channel in the Porter/Duff model is as irregularly shaped
-pieces of cardboard, not as colored glass.
+an alpha channel is as irregularly shaped pieces of cardboard, not as
+colored glass.
Consider these two images:
SRC ("triangle") DEST ("ampersand")
-If we combine them and zoom in on one pixel, we get this:
-
-Each individual pixel can be divided into four regions:
+When we combine them, each pixel can be divided into four regions:
\ /
\ /
@@ -140,9 +138,7 @@ other formulas than just { C_s, C_d, 0 }. With one additional blend
mode, 'plus', the ADD operator falls out as well.
This model is a simple and coherent way to extend the Porter/Duff
-compositing algebra with blend modes. If we were to generalize the
-operators in pixman/cairo/X11, this is the model we should be looking
-at.
+compositing algebra with blend modes.
CSS compositing spec
diff --git a/pics.c b/pics.c
index d9b571e..1dc33a3 100644
--- a/pics.c
+++ b/pics.c
@@ -3,6 +3,9 @@
#define CHECK_SIZE 16
+#define SOURCE_COLOR 0.8, 0.5, 0.2
+#define DEST_COLOR 0.2, 0.2, 0.4
+
static cairo_t *
get_cairo (int width, int height)
{
@@ -55,7 +58,7 @@ draw_ampersand (cairo_t *cr)
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_set_source_rgb (cr, DEST_COLOR);
cairo_fill (cr);
}
@@ -66,7 +69,7 @@ draw_polygon (cairo_t *cr)
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_set_source_rgb (cr, SOURCE_COLOR);
cairo_fill (cr);
}
@@ -135,7 +138,6 @@ centered_text (cairo_t *cr, double x, double y, const char *text)
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);
@@ -184,6 +186,7 @@ draw_cell (cairo_t *cr,
draw_source (cr);
}
+ cairo_set_source_rgb (cr, 0, 0, 0);
centered_text (cr,
x + CELL_WIDTH / 2.0 - 20.0,
y + CELL_HEIGHT - 30, name);
@@ -216,23 +219,92 @@ static void
create_op (cairo_operator_t op, const char *name, const char *filename)
{
cairo_t *cr = get_cairo (CELL_WIDTH + 20, CELL_HEIGHT);
- char fn[64] = { 0 };
cairo_move_to (cr, 0, 0);
draw_cell (cr, 30, 10, op, name);
- snprintf (fn, 63, "%s.png", filename);
- finish (cr, fn);
+ finish (cr, filename);
+}
+
+static void
+clear_to_white (cairo_t *cr)
+{
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+}
+
+static void
+draw_pixel_box (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_rectangle (cr, 1, 1, 178, 178);
+ cairo_move_to (cr, 1, 1);
+ cairo_line_to (cr, 179, 179);
+ cairo_move_to (cr, 179, 1);
+ cairo_line_to (cr, 1, 179);
+ cairo_stroke (cr);
+}
+
+static void
+general_pixel_diagram (const char *filename)
+{
+ cairo_t *cr = get_cairo (180, 180);
+
+ clear_to_white (cr);
+ draw_pixel_box (cr);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ centered_text (cr, 90, 45, "Both");
+ centered_text (cr, 35, 90, "Source");
+ centered_text (cr, 145, 90, "Dest");
+ centered_text (cr, 90, 147, "Neither");
+
+ finish (cr, filename);
+}
+
+static void
+dest_atop_diagram (const char *filename)
+{
+ cairo_t *cr = get_cairo (180, 180);
+
+ cairo_move_to (cr, 1, 1);
+ cairo_line_to (cr, 90, 90);
+ cairo_line_to (cr, 179, 1);
+ cairo_set_source_rgb (cr, DEST_COLOR);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ centered_text (cr, 90, 45, "Both");
+
+ cairo_move_to (cr, 1, 1);
+ cairo_line_to (cr, 90, 90);
+ cairo_line_to (cr, 1, 179);
+ cairo_set_source_rgb (cr, SOURCE_COLOR);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ centered_text (cr, 35, 90, "Source");
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ centered_text (cr, 145, 90, "Dest");
+ centered_text (cr, 90, 147, "Neither");
+
+ draw_pixel_box (cr);
+
+ finish (cr, filename);
}
int
main (int argc, char *argv)
{
- create_ampersand ();
- create_polygon ();
+ create_op (CAIRO_OPERATOR_SOURCE, "Source", "source.png");
+ create_op (CAIRO_OPERATOR_DEST, "Destination", "dest.png");
create_op (CAIRO_OPERATOR_COLOR_DODGE, "Color Dodge", "colordodge.png");
create_op (CAIRO_OPERATOR_DEST_ATOP, "Dest Atop", "destatop.png");
create_op (CAIRO_OPERATOR_OVER, "Over", "over.png");
create_porter_duff_table ();
+ general_pixel_diagram ("diagram.png");
+ dest_atop_diagram ("destatop-diagram.png");
}