#
# Script to convert .PNG files representing individual characters into
# C code for drawing something displayable on the Nokia/Epson LCD
#
# John Peterson, Feb 2011
#
# This script requires the Python Image Library (PIL).
#
from PIL import Image
import sys, os

os.chdir("D:\\Inventions\\MBed\\UI\\")

def CreateCfromImage( filename ):
	srcImage = Image.open( filename, 'r' )
	if (srcImage.size[0] != 132 or srcImage.size[1] != 132):
		print "Image must be 132 x 132"
		sys.exit(0)

	destCode = file( os.path.splitext( filename )[0] + ".h", 'w' )
	baseName = os.path.splitext(os.path.basename(filename))[0]
	destCode.write( "const unsigned char %s_data[] = {\n" % baseName );

	for row in reversed(range(srcImage.size[1])):	# Flip in Y to match LCD coords
		rowBytes = []
		for col in range(132/2):
			# Convert two pixels to three bytes: R0R0G0G0 B0B0R1R1 G1G1B1B1
			(r0, g0, b0) = srcImage.getpixel( (col*2, row) )
			(r1, g1, b1) = srcImage.getpixel( (col*2+1, row) )

			ch0 = (r0 & 0xF0) | (g0 >> 4)
			ch1 = (b0 & 0xF0) | (r1 >> 4)
			ch2 = (g1 & 0xF0) | (b1 >> 4)

			rowBytes.extend( [ch0, ch1, ch2] )

		destCode.write( "\t%s%s\n" % (",".join(["0x%02X" % c for c in rowBytes]), "," if row > 0 else "") )

	destCode.write("};\n\nconst image_data_t %s_img = { %s_data, %d, %d };\n" % (baseName, baseName, srcImage.size[1], srcImage.size[0] ))
	destCode.close()

def CreateCfromSprite( filename, destCode = None, baseline = None, font_prefix = "" ):
	srcImage = Image.open( filename, 'r' )
	if (len(srcImage.getbands()) > 1) or (srcImage.getbands()[0] != 'L'):
		print "Image must be grayscale"
		sys.exit(0)

	if (srcImage.size[0] > 130 or srcImage.size[1] > 130):
		print "Image too big"
		sys.exit(0)

	closeDest = True
	if (not destCode):
		destCode = file( os.path.splitext( filename )[0] + ".c", 'w' )
	else:
		closeDest = False
	baseName = font_prefix + os.path.splitext(os.path.basename(filename))[0]
	comment = ""
	if (baseline != None):
		# Evil expression to fish the character out of the filename
		comment = "\t/* '%s' */" % chr(eval("0x" + re.search(".+x(..)[.]png", filename).group(1)))
	destCode.write( "const unsigned char %s_data[] = {%s\n" % (baseName, comment) );

	for row in reversed(range(srcImage.size[1])):	# Flip in Y to match LCD coords
		rowBytes = []

		# Pack every two adjacent grayscale values into each byte (four bits each)
		for col in range(srcImage.size[0] / 2):
			g0 = srcImage.getpixel( (col*2, row) )
			g1 = srcImage.getpixel( (col*2+1, row) )

			rowBytes.extend( [(g0 & 0xF0) | (g1 >> 4)] )
		if (srcImage.size[0] & 1):
			rowBytes.extend( [srcImage.getpixel( (srcImage.size[0]-1, row)) & 0xF0] )

		destCode.write( "\t%s%s\n" % (",".join(["0x%02X" % c for c in rowBytes]), "," if row > 0 else "") )
	if (baseline == None):
		destCode.write("};\n\nconst sprite_data_t %s_sprt = { %s_data, %d, %d };\n\n" % (baseName, baseName, srcImage.size[1], srcImage.size[0] ))
	else:
		destCode.write("};\n\nconst glyph_data_t %s_glyph = { %s_data, %d, %d, %d };\n\n" % (baseName, baseName, srcImage.size[1], srcImage.size[0], baseline ))
	if (closeDest):
		destCode.close()

class chrdat:
	def __init__(self, id, filename, top, bottom ):
		self.id = id
		self.top = top
		self.bot = bottom
		self.filename = filename

def processGlyphs():
	kbaseline = 20
	kfontName = "f18"
	chardata = eval(file( "D:\\Inventions\\MBed\\UI\\charinfo.txt", 'r').read())
	textcode = file("D:\\Inventions\\MBed\\UI\\%sTextData.h" % kfontName,'w')
	for cd in chardata:
		CreateCfromSprite( cd.filename, textcode, cd.bot - kbaseline, kfontName )

	glyphRefs = ["&"+kfontName + "x%2x_glyph" % cd.id for cd in chardata]
	textcode.write("const glyph_data_t * const %s_glyph_array[] = { \n\t" % kfontName + ",\n\t".join( glyphRefs ) + "};\n" )

	textcode.close()

def makeNumSprites():
	nsfile = file( "D:\\Inventions\\ColorMeter\\app\\images\\NumSprites.c", 'w' )
	for f in ["N0",'N1','N2','N3','N4','N5','N6','N7','N8','N9','dot','plus','minus']:
		CreateCfromSprite( f + '.png', nsfile )

	nsfile.close()
# makeNumSprites()

def moreSprites():
	CreateCfromSprite( "plus.png" )
	CreateCfromSprite("minus.png")
	CreateCfromSprite("dot.png")
	CreateCfromSprite("Red.png")
	CreateCfromSprite("Grn.png")
	CreateCfromSprite("Blu.png")
	CreateCfromSprite("RGBColor.png")
