merging fixes & changes from delft-sprint-2012

git-svn-id: svn://svn.code.sf.net/p/fonttools/code/trunk@611 4cde692c-a291-49d1-8350-778aa11640f8
diff --git a/Lib/fontTools/ttLib/sfnt.py b/Lib/fontTools/ttLib/sfnt.py
index 6019d5f..7ba40f4 100644
--- a/Lib/fontTools/ttLib/sfnt.py
+++ b/Lib/fontTools/ttLib/sfnt.py
@@ -14,7 +14,6 @@
 
 import sys
 import struct, sstruct
-import numpy
 import os
 
 
@@ -152,24 +151,28 @@
 				seenHead = 1
 			directory = directory + entry.toString()
 		if seenHead:
-			self.calcMasterChecksum(directory)
+			self.writeMasterChecksum(directory)
 		self.file.seek(0)
 		self.file.write(directory)
-	
-	def calcMasterChecksum(self, directory):
+
+	def _calcMasterChecksum(self, directory):
 		# calculate checkSumAdjustment
 		tags = self.tables.keys()
-		checksums = numpy.zeros(len(tags)+1, numpy.uint32)
+		checksums = []
 		for i in range(len(tags)):
-			checksums[i] = self.tables[tags[i]].checkSum
-		
+			checksums.append(self.tables[tags[i]].checkSum)
+
 		directory_end = sfntDirectorySize + len(self.tables) * sfntDirectoryEntrySize
 		assert directory_end == len(directory)
-		
-		checksums[-1] = calcChecksum(directory)
-		checksum = numpy.add.reduce(checksums,dtype=numpy.uint32)
+
+		checksums.append(calcChecksum(directory))
+		checksum = sum(checksums) & 0xffffffff
 		# BiboAfba!
-		checksumadjustment = int(numpy.subtract.reduce(numpy.array([0xB1B0AFBA, checksum], numpy.uint32)))
+		checksumadjustment = (0xB1B0AFBA - checksum) & 0xffffffff
+		return checksumadjustment
+
+	def writeMasterChecksum(self, directory):
+		checksumadjustment = self._calcMasterChecksum(directory)
 		# write the checksum to the file
 		self.file.seek(self.tables['head'].offset + 8)
 		self.file.write(struct.pack(">L", checksumadjustment))
@@ -230,7 +233,7 @@
 			return "<SFNTDirectoryEntry at %x>" % id(self)
 
 
-def calcChecksum(data, start=0):
+def calcChecksum(data):
 	"""Calculate the checksum for an arbitrary block of data.
 	Optionally takes a 'start' argument, which allows you to
 	calculate a checksum in chunks by feeding it a previous
@@ -238,14 +241,23 @@
 	
 	If the data length is not a multiple of four, it assumes
 	it is to be padded with null byte. 
+
+		>>> print calcChecksum("abcd")
+		1633837924
+		>>> print calcChecksum("abcdxyz")
+		3655064932
 	"""
-	from fontTools import ttLib
 	remainder = len(data) % 4
 	if remainder:
-		data = data + '\0' * (4-remainder)
-	data = struct.unpack(">%dL"%(len(data)/4), data)
-	a = numpy.array((start,)+data, numpy.uint32)
-	return int(numpy.sum(a,dtype=numpy.uint32))
+		data += "\0" * (4 - remainder)
+	value = 0
+	blockSize = 4096
+	assert blockSize % 4 == 0
+	for i in xrange(0, len(data), blockSize):
+		block = data[i:i+blockSize]
+		longs = struct.unpack(">%dL" % (len(block) // 4), block)
+		value = (value + sum(longs)) & 0xffffffff
+	return value
 
 
 def maxPowerOfTwo(x):
@@ -271,3 +283,7 @@
 	rangeShift = n * 16 - searchRange
 	return searchRange, entrySelector, rangeShift
 
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()