#!/usr/bin/python from __future__ import division import gtk import cairo import math IDENTITY = 0 ROTATE_90 = 1 SCALE = 2 ROTATE = 3 TRANSFORMS = [ IDENTITY, ROTATE_90, SCALE, ROTATE ] SOURCE_ALPHAS = [ False, True ] FILTERS = [ cairo.FILTER_NEAREST, cairo.FILTER_BILINEAR ] SOURCE_SIZE = 16 DEST_SIZE = 100 PAD = 10 TOTAL_SIZE = 4 * (DEST_SIZE + PAD) + PAD transform = None source_alpha = None source_filter = None def draw_sample(cr, x, y, transform, filter, source_alpha): cr.save() cr.translate(x, y) cr.rectangle(0, 0, DEST_SIZE, DEST_SIZE) cr.clip() if source_alpha: source = cairo.ImageSurface(cairo.FORMAT_ARGB32, SOURCE_SIZE, SOURCE_SIZE) else: source = cairo.ImageSurface(cairo.FORMAT_RGB24, SOURCE_SIZE, SOURCE_SIZE) source_cr = cairo.Context(source) source_cr.set_source_rgba(0, 0, 1) source_cr.paint() hole_x = hole_y = SOURCE_SIZE // 4 hole_width = hole_height = SOURCE_SIZE // 2 # Add some rectangles on the source image at the corners source_cr.rectangle(0, 0, hole_x, hole_y) source_cr.rectangle(hole_x + hole_width, 0, SOURCE_SIZE - (hole_x + hole_width), hole_y) source_cr.rectangle(0, hole_y + hole_height, hole_x, SOURCE_SIZE - (hole_y + hole_height)) source_cr.rectangle(hole_x + hole_width, hole_y + hole_height, SOURCE_SIZE - (hole_x + hole_width), SOURCE_SIZE - (hole_y + hole_height)) source_cr.set_source_rgba(0, 1, 0) source_cr.fill() if source_alpha: # Cut a whole out of the middle source_cr.set_operator(cairo.OPERATOR_DEST_OUT) source_cr.rectangle(hole_x, hole_y, hole_width, hole_height) source_cr.set_source_rgba(1, 1, 1) source_cr.fill() cr.translate(DEST_SIZE // 2, DEST_SIZE // 2) if transform == IDENTITY: pass elif transform == ROTATE_90: cr.rotate(math.pi / 2) elif transform == SCALE: cr.scale(11/3, 11/3) elif transform == ROTATE: cr.rotate(math.pi / 3) cr.scale(11/3, 11/3) cr.translate(- SOURCE_SIZE // 2, - SOURCE_SIZE // 2) # # Draw a shape in red under the bounds of the surface # cr.move_to(0, 0) # cr.line_to(SOURCE_SIZE, 0) # cr.line_to(SOURCE_SIZE, SOURCE_SIZE) # cr.line_to(0, SOURCE_SIZE) # cr.close_path() # if source_alpha: # # Cut the hole out of the shape # cr.move_to(hole_x, hole_y) # cr.line_to(hole_x, hole_y + hole_height) # cr.line_to(hole_x + hole_height, hole_y + hole_height) # cr.line_to(hole_x + hole_height, hole_y) # cr.close_path() # cr.set_source_rgba(1, 0, 0) # cr.fill() # Draw the transformed surface cr.set_source_surface(source) cr.get_source().set_filter(filter) # cr.set_operator(cairo.OPERATOR_SOURCE) cr.paint() cr.restore() def draw(cr): cr.set_source_rgba(1, 1, 1) cr.paint() y = PAD for source_alpha in SOURCE_ALPHAS: for filter in FILTERS: x = PAD for transform in TRANSFORMS: draw_sample(cr, x, y, transform, filter, source_alpha) x += DEST_SIZE + PAD y += DEST_SIZE + PAD def on_expose(widget, event): cr = widget.window.cairo_create() draw(cr) def dump_image(): width, height = w.size_request() surface = cairo.ImageSurface(cairo.FORMAT_RGB24, width, height) cr = cairo.Context(surface) draw(cr) surface.write_to_png("/tmp/test-repeat-none-image.png") def dump_pixmap(): cmap = gtk.gdk.screen_get_default().get_rgb_colormap() out = gtk.gdk.Pixmap(None, TOTAL_SIZE, TOTAL_SIZE, cmap.get_visual().depth) out.set_colormap(cmap) cr = out.cairo_create() draw(cr) cr.get_target().write_to_png("/tmp/test-repeat-none-pixmap.png") def reset(): w.set_size_request(TOTAL_SIZE, TOTAL_SIZE) w.queue_draw() def on_key_press(widget, event): if event.keyval in (gtk.keysyms.d, gtk.keysyms.D): dump_image() return True if event.keyval in (gtk.keysyms.p, gtk.keysyms.P): dump_pixmap() return True elif event.keyval in (gtk.keysyms.r, gtk.keysyms.R): reset() return True elif event.keyval in (gtk.keysyms.q, gtk.keysyms.Q): gtk.main_quit() return True elif event.keyval in (gtk.keysyms.Escape,): transform = None source_alpha = None filter = None reset() return True return False w = gtk.Window() w.set_app_paintable(True) w.set_resizable(False) reset() w.connect('expose-event', on_expose) w.connect('key-press-event', on_key_press) w.show() gtk.main()