diff options
-rw-r--r-- | blend.txt | 12 | ||||
-rw-r--r-- | pics.c | 88 |
2 files changed, 84 insertions, 16 deletions
@@ -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 @@ -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"); } |