#!/usr/bin/env python

import gtk
import sys
import cairo
background = None # gtk.gdk.pixbuf_new_from_file("/home/dannym/444.PNG")
#scale = 4.5
#background = background.scale_simple(background.get_width() * scale, background.get_height() * scale, gtk.gdk.INTERP_NEAREST) # BILINEAR)

#operations = operations[:15+3] +  [("endchar", [])]
#operations = operations[:15+6+1] +  [("endchar", [])]
#operations = operations[:22] +  [("endchar", [])]
# ('rrcurveto', [27, 13, 2, 14, -25, 13])
# ??? ('vvcurveto', [-10, 5, -4, 9, 13])
#operations = operations[:16] +  [("endchar", [])]
#print operations[-2]
# http://centos.cs.wisc.edu/pub/mirrors/ghost/kanji/Font/tools/wftomf.c
#('hhcurveto', [-23, -4, -14, -11, -23])
#('hvcurveto', [-16, -8, 8, 15])

context = None

coordinate_system = cairo.Matrix(1, 0, 0, -1, 0, 400)

def repaint(widget, event, operations):
	global position
	global context

	window = widget.window
	if background:
		GC = window.new_gc()
		window.draw_pixbuf(GC, background, 0, 0, -86, -260)
	#GC = window.new_gc()
	context = window.cairo_create()
	context.set_source_rgb(1.0, 0.0, 0.0) # 1.0, 1.0, 1.0)
	context.transform(coordinate_system)
	context.scale(0.5, 0.5)
	context.move_to(0, 0)

	def curveto(dx1, dy1, dx2, dy2, dx3, dy3):
		global context
		# http://yytex.googlecode.com/svn/trunk/src/c32/dejis.c
		# rrcurveto: dx1 dy1 dx2 dy2 dx3 dy3
		# hvcurveto: dx1 dx2 dy2 dy3
		# vhcurveto: dy1 dx2 dy2 dx3
		context.rel_curve_to(dx1, dy1, dx2 + dx1, dy2 + dy1, dx3 + dx2 + dx1, dy3 + dy2 + dy1)

	def rrcurveto(curves):
		for i in range(len(curves) // 6):
			curve = curves[i * 6: (i + 1) * 6]
			curveto(*curve)

	def hlineto(positions):
		assert(len(positions) > 0)
		while len(positions) > 0:
			rlineto([positions[0], 0])
			if len(positions) >= 2:
				rlineto([0, positions[1]])
			positions = positions[2:]

	def hhcurveto(curves): # starts and ends horizontally
		if len(curves) % 2 != 0:
			dy1 = curves[0] # first curve
			curves = curves[1 : ]
		else:
			dy1 = 0
		for i in range(len(curves) // 4):
			curve = curves[i * 4 : (i + 1) * 4]
			curveto(curve[0], dy1, curve[1], curve[2], curve[3], 0)

	def vmoveto(arguments):
		if len(arguments) != 2: # width
			assert(len(arguments) == 1)
		rmoveto([0, arguments[0]])

	def hmoveto(arguments):
		if len(arguments) != 2: # width
			assert(len(arguments) == 1)
		rmoveto([arguments[0], 0])

	def rmoveto(position):
		close_path()
		context.rel_move_to(position[0], position[1])

	def rlineto(lines):
		for i in range(len(lines) // 2):
			line = lines[i * 2 : (i + 1) * 2]
			context.rel_line_to(*line)

	def mark_X():
		context.rel_line_to(20, 20)
		context.rel_line_to(-40, -40)
		context.rel_line_to(20, 20)

	def rlinecurve(curves):
		lines = curves[:-6]
		#print("LINES", lines)
		#context.stroke_preserve()
		#context.set_source_rgb(1.0, 1.0, 1.0) # 1.0, 1.0, 1.0)
		rlineto(lines)
		#mark_X()
		#context.stroke_preserve()
		#context.set_source_rgb(1.0, 0.0, 0.0) # 1.0, 1.0, 1.0)
		#print("CURVE TO", curves[-6:])
		rrcurveto(curves[-6:])

	def hvcurveto(curves):
		# FIXME if there are more, toggle between vhcurveto and hvcurveto.
		assert(len(curves) == 4 or len(curves) == 5) # or 5.
		"""
		x += pop, 
		add point, 
		x,y += pop, 
		add point, 
		y += pop, 
		if exactly 1 available x += pop; 
		add point."""
		# first bezier tangent = horizontal.
		# ends vertical.
		if len(curves) % 2:
			dxl = curves[-1]
		else:
			dxl = 0
		curve = curves[:4]
		# hvcurveto: dx1 dx2 dy2 dy3
		curveto(curve[0], 0, curve[1], curve[2], dxl, curve[3])

	def vhcurveto(curves):
		# FIXME if there are more, toggle between vhcurveto and hvcurveto.
		""" TODO 
		y+=pop, 
		add point, 
		x, y+= pop, 
		add point, 
		x += pop, 
		if exactly 1 avail y+= pop;
		add point."""
		assert(len(curves) == 4 or len(curves) == 5) # or 5.
		# first bezier tangent = horizontal.
		# ends vertical.
		if len(curves) % 2:
			dyl = curves[-1] # FIXME
		else:
			dyl = 0
		curve = curves[: 4]
		curveto(0, curve[0], curve[1], curve[2], curve[3], dyl)

	def vlineto(arguments):
		assert(len(arguments) > 0)
		while len(arguments) > 0:
			rlineto([0, arguments[0]])
			if len(arguments) >= 2:
				rlineto([arguments[1], 0])
			arguments = arguments[2:]

	def rcurveline(arguments): # suspect this!
		curves = arguments[ : -2]
		rrcurveto(curves)
		rlineto(arguments[-2:])

	def close_path():
		#context.stroke()
		#context.stroke()
		context.close_path()
		#context.stroke()
		#context.fill()

	def vvcurveto(curves):
		""" TODO start; 
			if odd count x+=pop; 
			y+=pop,
			add point, 
			x,y+=pop, 
			add point, 
			y+=pop, 
			add point."""
		assert(len(curves) >= 4)
		if len(curves) % 4:
			dx1 = curves[0]
			curves = curves[1:]
		else:
			dx1 = 0
		for i in range(0, len(curves), 4):
			curve = curves[i : i + 4]
			curveto(dx1, curve[0], curve[1], curve[2], 0, curve[3])
			dx1 = 0

	for operator, arguments in operations:
		#print(operator)
		if operator == "rmoveto":
			rmoveto(arguments)
		elif operator == "vlineto":
			vlineto(arguments)
		elif operator == "vmoveto":
			vmoveto(arguments)
		elif operator == "hmoveto":
			hmoveto(arguments)
		elif operator == "rrcurveto":
			rrcurveto(arguments)
		elif operator == "hhcurveto":
			hhcurveto(arguments)
		elif operator == "hlineto":
			hlineto(arguments)
		elif operator == "rlinecurve":
			rlinecurve(arguments)
		elif operator == "rcurveline":
			rcurveline(arguments)
		elif operator == "rlineto":
			rlineto(arguments)
		elif operator == "hvcurveto":
			if len(arguments) > 5:
				arguments = arguments[:4]
				remainder = arguments[4:]
			else:
				remainder = None
			hvcurveto(arguments)
			if remainder:
				vhcurveto(remainder)
		elif operator == "vhcurveto":
			if len(arguments) > 5:
				arguments = arguments[:4]
				remainder = arguments[4:]
			else:
				remainder = None
			vhcurveto(arguments)
			if remainder:
				hvcurveto(remainder)
		elif operator == "vvcurveto":
			vvcurveto(arguments)
		elif operator == "hstem":
			pass
		elif operator == "vstem":
			pass
		elif operator == "endchar":
			close_path()
			context.stroke()
			break
		else:
			sys.stderr.write("warning: ignoring unknown operation (%r %r)\n" % (operator, arguments))


def show_window(operations):
	drawing_area_1 = gtk.DrawingArea()
	drawing_area_1.set_size_request(320, 430)
	drawing_area_1.connect("expose-event", repaint, operations)
	window_1 = gtk.Window()
	window_1.add(drawing_area_1)
	window_1.show_all()
	return window_1

if __name__ == "__main__":
	operations=[('hstem', [694, 0, 40, 666, -20]), ('vstem', [103, 44]), ('rmoveto', [147, 346]), ('vlineto', [320]), ('rcurveline', [41, 15, 4, 11, -31, 7, -58, 7]), ('vlineto', [-381]), ('rrcurveto', [-32, -13, -31, -14, -32, -14]), ('hhcurveto', [-8, -11, 1, -5, 17]), ('rrcurveto', [28, 9, 30, 9, 30, 9]), ('vlineto', [-258]), ('vhcurveto', [-27, 14, -13, 27]), ('hlineto', [397]), ('hvcurveto', [20, 18, 3, 7, 13]), ('rrcurveto', [27, 13, 2, 14, -25, 13]), ('vvcurveto', [-10, 5, -4, 9, 13]), ('rlinecurve', [7, 123, -3, 6, -3, 0, -4, -6]), ('rlineto', [-31, -126]), ('hhcurveto', [-23, -4, -14, -11, -23]), ('hlineto', [-336]), ('hvcurveto', [-16, -8, 8, 15]), ('vlineto', [252]), ('rcurveline', [130, 55, 123, 70, 118, 86, 56, -7, 10, 9, -36, 25, -51, 38]), ('rrcurveto', [-98, -98, -116, -82, -136, -65]), ('endchar', [])]
	#operations = operations[:16] + [('endchar', [])]
	#print(operations[15])
	window_1 = show_window(operations)
	window_1.connect("delete-event", gtk.main_quit)
	gtk.main()
