Index: uspace/app/gfxdemo/gfxdemo.c
===================================================================
--- uspace/app/gfxdemo/gfxdemo.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/app/gfxdemo/gfxdemo.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -590,7 +590,18 @@
 		goto error;
 
+	gfx_color_delete(color);
+
 	gfx_text_fmt_init(&fmt);
 
 	for (i = 0; i < 8; i++) {
+		rc = gfx_color_new_rgb_i16((i & 4) ? 0xffff : 0,
+		    (i & 2) ? 0xffff : 0, (i & 1) ? 0xffff : 0, &color);
+		if (rc != EOK)
+			goto error;
+
+		rc = gfx_set_color(gc, color);
+		if (rc != EOK)
+			goto error;
+
 		pos.x = w / 20;
 		pos.y = (7 + i) * h / 15;
@@ -598,4 +609,6 @@
 		if (rc != EOK)
 			goto error;
+
+		gfx_color_delete(color);
 	}
 
@@ -605,6 +618,4 @@
 			break;
 	}
-
-	gfx_color_delete(color);
 
 	gfx_font_close(font);
Index: uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -383,5 +383,5 @@
 
 	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
+	if ((params->flags & ~(bmpf_color_key | bmpf_colorize)) != 0)
 		return ENOTSUP;
 
@@ -392,4 +392,5 @@
 	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
 	dcbm->rect = params->rect;
+	dcbm->flags = params->flags;
 
 	if (alloc == NULL) {
@@ -487,13 +488,44 @@
 	gfx_rect_clip(&srect, &skfbrect, &crect);
 
-	// XXX bmpf_color_key
-	for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
-		for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
-			gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
-			gfx_coord2_add(&pos, &offs, &dp);
-
-			color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
-			dispc->active_fb.pixel2visual(dispc->fb_data +
-			    FB_POS(dispc, dp.x, dp.y), color);
+	if ((dcbm->flags & bmpf_color_key) == 0) {
+		/* Simple copy */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				dispc->active_fb.pixel2visual(dispc->fb_data +
+				    FB_POS(dispc, dp.x, dp.y), color);
+			}
+		}
+	} else if ((dcbm->flags & bmpf_colorize) == 0) {
+		/* Color key */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				if (color != dcbm->key_color) {
+					dispc->active_fb.pixel2visual(dispc->fb_data +
+					    FB_POS(dispc, dp.x, dp.y), color);
+				}
+			}
+		}
+	} else {
+		/* Color key & colorize */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				if (color != dcbm->key_color) {
+					dispc->active_fb.pixel2visual(dispc->fb_data +
+					    FB_POS(dispc, dp.x, dp.y),
+					    dcbm->dispc->color);
+				}
+			}
 		}
 	}
Index: uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h
===================================================================
--- uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -68,8 +68,16 @@
 
 typedef struct {
+	/* Containing display controller */
 	amdm37x_dispc_t *dispc;
+	/** Allocation info */
 	gfx_bitmap_alloc_t alloc;
+	/** @c true if we allocated the bitmap, @c false if allocated by caller */
+	bool myalloc;
+	/** Rectangle covered by bitmap */
 	gfx_rect_t rect;
-	bool myalloc;
+	/** Bitmap flags */
+	gfx_bitmap_flags_t flags;
+	/** Key color */
+	pixel_t key_color;
 } amdm37x_bitmap_t;
 
Index: uspace/drv/fb/kfb/port.c
===================================================================
--- uspace/drv/fb/kfb/port.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/drv/fb/kfb/port.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -200,5 +200,5 @@
 
 	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
+	if ((params->flags & ~(bmpf_color_key | bmpf_colorize)) != 0)
 		return ENOTSUP;
 
@@ -307,4 +307,5 @@
 
 	if ((kfbbm->flags & bmpf_color_key) != 0) {
+		/* Simple copy */
 		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
 			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
@@ -319,5 +320,18 @@
 			}
 		}
+	} else if ((kfbbm->flags & bmpf_colorize) != 0) {
+		/* Color key */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				kfb->pixel2visual(kfb->addr +
+				    FB_POS(kfb, dp.x, dp.y), color);
+			}
+		}
 	} else {
+		/* Color key & colorize */
 		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
 			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
Index: uspace/lib/congfx/src/console.c
===================================================================
--- uspace/lib/congfx/src/console.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/lib/congfx/src/console.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -207,5 +207,5 @@
 
 	/* Check that we support all requested flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
+	if ((params->flags & ~(bmpf_color_key | bmpf_colorize)) != 0)
 		return ENOTSUP;
 
@@ -296,4 +296,5 @@
 
 	if ((cbm->flags & bmpf_color_key) == 0) {
+		/* Simple copy */
 		for (y = crect.p0.y; y < crect.p1.y; y++) {
 			console_set_pos(cbm->cgc->con, crect.p0.x, y);
@@ -312,5 +313,6 @@
 			}
 		}
-	} else {
+	} else if ((cbm->flags & bmpf_colorize) == 0) {
+		/* Color key */
 		for (y = crect.p0.y; y < crect.p1.y; y++) {
 			for (x = crect.p0.x; x < crect.p1.x; x++) {
@@ -332,4 +334,27 @@
 			}
 		}
+	} else {
+		/* Color key & colorize */
+		console_set_rgb_color(cbm->cgc->con, cbm->cgc->clr,
+		    cbm->cgc->clr);
+
+		for (y = crect.p0.y; y < crect.p1.y; y++) {
+			for (x = crect.p0.x; x < crect.p1.x; x++) {
+
+				clr = pixelmap_get_pixel(&pixelmap,
+				    x - offs.x - cbm->rect.p0.x,
+				    y - offs.y - cbm->rect.p0.y);
+
+				if (clr != cbm->key_color) {
+					console_set_pos(cbm->cgc->con, x, y);
+					rv = fputc('X', cbm->cgc->fout);
+					if (rv < 0)
+						return EIO;
+
+					console_flush(cbm->cgc->con);
+				}
+
+			}
+		}
 	}
 
Index: uspace/lib/gfx/include/types/gfx/bitmap.h
===================================================================
--- uspace/lib/gfx/include/types/gfx/bitmap.h	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/lib/gfx/include/types/gfx/bitmap.h	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -47,8 +47,10 @@
 /** Bitmap flags */
 typedef enum {
+	/** Directly map GC output into this bitmap */
+	bmpf_direct_output = 0x1,
 	/** Enable color key */
-	bmpf_color_key = 0x1,
-	/** Directly map GC output into this bitmap */
-	bmpf_direct_output = 0x2
+	bmpf_color_key = 0x2,
+	/** Paint non-background pixels with current drawing color */
+	bmpf_colorize = 0x4
 } gfx_bitmap_flags_t;
 
Index: uspace/lib/gfxfont/src/font.c
===================================================================
--- uspace/lib/gfxfont/src/font.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/lib/gfxfont/src/font.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -122,5 +122,5 @@
 	gfx_bitmap_params_init(&params);
 	params.rect = font->rect;
-	params.flags = bmpf_color_key;
+	params.flags = bmpf_color_key | bmpf_colorize;
 	params.key_color = PIXEL(0, 0, 0, 0);
 
@@ -366,5 +366,5 @@
 	if (nrect->p1.y - nrect->p0.y > params.rect.p1.y)
 		params.rect.p1.y = nrect->p1.y - nrect->p0.y;
-	params.flags = bmpf_color_key;
+	params.flags = bmpf_color_key | bmpf_colorize;
 	params.key_color = PIXEL(0, 0, 0, 0);
 
@@ -705,5 +705,5 @@
 	params.rect.p1.x = width;
 	params.rect.p1.y = height;
-	params.flags = bmpf_color_key;
+	params.flags = bmpf_color_key | bmpf_colorize;
 	params.key_color = PIXEL(0, 0, 0, 0);
 
Index: uspace/lib/gfxfont/src/text.c
===================================================================
--- uspace/lib/gfxfont/src/text.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/lib/gfxfont/src/text.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -135,5 +135,5 @@
 		case gfx_valign_bottom:
 			cpos.y -= fmetrics.descent;
-		    	break;
+			break;
 		default:
 			break;
Index: uspace/lib/memgfx/src/memgc.c
===================================================================
--- uspace/lib/memgfx/src/memgc.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/lib/memgfx/src/memgc.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -225,5 +225,6 @@
 
 	/* Check that we support all requested flags */
-	if ((params->flags & ~(bmpf_color_key | bmpf_direct_output)) != 0)
+	if ((params->flags & ~(bmpf_color_key | bmpf_colorize |
+	    bmpf_direct_output)) != 0)
 		return ENOTSUP;
 
@@ -367,4 +368,5 @@
 		/* Nothing to do */
 	} else if ((mbm->flags & bmpf_color_key) == 0) {
+		/* Simple copy */
 		for (y = drect.p0.y; y < drect.p1.y; y++) {
 			for (x = drect.p0.x; x < drect.p1.x; x++) {
@@ -375,5 +377,6 @@
 			}
 		}
-	} else {
+	} else if ((mbm->flags & bmpf_colorize) == 0) {
+		/* Color key */
 		for (y = drect.p0.y; y < drect.p1.y; y++) {
 			for (x = drect.p0.x; x < drect.p1.x; x++) {
@@ -385,4 +388,16 @@
 			}
 		}
+	} else {
+		/* Color key & colorization */
+		for (y = drect.p0.y; y < drect.p1.y; y++) {
+			for (x = drect.p0.x; x < drect.p1.x; x++) {
+				pixel = pixelmap_get_pixel(&smap,
+				    x - mbm->rect.p0.x - offs.x,
+				    y - mbm->rect.p0.y - offs.y);
+				if (pixel != mbm->key_color)
+					pixelmap_put_pixel(&dmap, x, y,
+					    mbm->mgc->color);
+			}
+		}
 	}
 
Index: uspace/srv/hid/rfb/main.c
===================================================================
--- uspace/srv/hid/rfb/main.c	(revision 8bf9058f09dced75aac624984f173f5571c2084c)
+++ uspace/srv/hid/rfb/main.c	(revision 0d62c10a4e92097fe235df71e74a4c547e7e9d71)
@@ -196,5 +196,5 @@
 
 	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
+	if ((params->flags & ~(bmpf_color_key | bmpf_colorize)) != 0)
 		return ENOTSUP;
 
@@ -287,4 +287,5 @@
 
 	if ((rfbbm->flags & bmpf_color_key) == 0) {
+		/* Simple copy */
 		for (y = srect.p0.y; y < srect.p1.y; y++) {
 			for (x = srect.p0.x; x < srect.p1.x; x++) {
@@ -294,5 +295,6 @@
 			}
 		}
-	} else {
+	} else if ((rfbbm->flags & bmpf_colorize) == 0) {
+		/* Color key */
 		for (y = srect.p0.y; y < srect.p1.y; y++) {
 			for (x = srect.p0.x; x < srect.p1.x; x++) {
@@ -304,4 +306,16 @@
 			}
 		}
+	} else {
+		/* Color key & colorization */
+		for (y = srect.p0.y; y < srect.p1.y; y++) {
+			for (x = srect.p0.x; x < srect.p1.x; x++) {
+				color = pixelmap_get_pixel(&pbm, x, y);
+				if (color != rfbbm->key_color) {
+					pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
+					    x + offs.x, y + offs.y,
+					    rfbbm->rfb->color);
+				}
+			}
+		}
 	}
 
