#!/usr/bin/env python

'''
pycairo testcase for incorrect pdf stroke gradient rendering
Written by Karl Ostmo
June 3, 2008
'''

import pygtk
pygtk.require('2.0')
import gtk, cairo


from math import pi, sqrt

# Create a GTK+ widget on which we will draw using Cairo
class Screen(gtk.DrawingArea):

	def __init__(self):
		gtk.DrawingArea.__init__(self)

	# =============================

	# Draw in response to an expose-event
	__gsignals__ = { "expose-event": "override" }

	# =============================

	# Handle the expose-event by drawing
	def do_expose_event(self, event):

		# Create the cairo context
		cr = self.window.cairo_create()

		# Restrict Cairo to the exposed area; avoid extra work
		cr.rectangle(event.area.x, event.area.y,
		        event.area.width, event.area.height)
		cr.clip()

		self.draw(cr, *self.window.get_size())

	# =============================

	def draw(self, cr, width, height):

		circle_radius = min(width, height)/3.0
		cr.translate(width/2.0, height/2.0)
		cr.arc( 0, 0, circle_radius, 0, 2*pi)

		linear_gradient = cairo.LinearGradient(0, circle_radius, 0, -circle_radius)
		linear_gradient.add_color_stop_rgb(0, *tuple([1.0]*3) )
		linear_gradient.add_color_stop_rgb(1, *tuple([0.0]*3) )
		cr.set_source(linear_gradient)

		cr.set_line_width( 20 )
		cr.stroke()

	# -------------

	def draw_and_save_graphic(self, widget):

		x, y, img_width, img_height = self.get_allocation()

		filename = "gradient_testcase.pdf"
		surf = cairo.PDFSurface(filename, img_width, img_height)
		cr = cairo.Context(surf)
		self.draw(cr, img_width, img_height)
		cr.show_page()

		print "Wrote", filename, "at", img_width, "x", img_height

# =============================

def run(Widget):
	window = gtk.Window()
	window.connect("delete-event", gtk.main_quit)
	widget = Widget()
	widget.set_size_request( 100, 100 )
	widget.show()

	vbox = gtk.VBox(False)
	window.add(vbox)

	vbox.pack_start(widget, True, True)

	button = gtk.Button("Save to PDF")
	vbox.pack_start(button, False, False)
	button.connect('clicked', widget.draw_and_save_graphic)

	vbox.show_all()

	window.present()
	gtk.main()

if __name__ == "__main__":
	run(Screen)
