diff --git a/Doc/documentation.html b/Doc/documentation.html
index ccb9a7d..748f5f7 100644
--- a/Doc/documentation.html
+++ b/Doc/documentation.html
@@ -42,7 +42,7 @@
 The following tables are currently supported:
 <BLOCKQUOTE><TT>
 <!-- begin table list -->
-BASE, CFF, DSIG, GDEF, GMAP, GPKG, GPOS, GSUB, JSTF, LTSH, META, OS/2, SING, TSI0, TSI1, TSI2, TSI3, TSI5, TSIB, TSID, TSIJ, TSIP, TSIS, TSIV, VORG, cmap, cvt, fpgm, gasp, glyf, hdmx, head, hhea, hmtx, kern, loca, maxp, name, post, prep, vhea and vmtx
+BASE, CFF, DSIG, EBDT, EBLC, GDEF, GMAP, GPKG, GPOS, GSUB, JSTF, LTSH, META, OS/2, SING, TSI0, TSI1, TSI2, TSI3, TSI5, TSIB, TSID, TSIJ, TSIP, TSIS, TSIV, VORG, cmap, cvt, fpgm, gasp, glyf, hdmx, head, hhea, hmtx, kern, loca, maxp, name, post, prep, vhea and vmtx
 <!-- end table list -->
 </TT></BLOCKQUOTE>
 Other tables are dumped as hexadecimal data.
diff --git a/Lib/fontTools/ttLib/__init__.py b/Lib/fontTools/ttLib/__init__.py
index 1b8117f..128bcea 100644
--- a/Lib/fontTools/ttLib/__init__.py
+++ b/Lib/fontTools/ttLib/__init__.py
@@ -211,7 +211,8 @@
 			file.close()
 	
 	def saveXML(self, fileOrPath, progress=None, 
-			tables=None, skipTables=None, splitTables=0, disassembleInstructions=1):
+			tables=None, skipTables=None, splitTables=0, disassembleInstructions=1,
+			bitmapGlyphDataFormat='raw'):
 		"""Export the font as TTX (an XML-based text file), or as a series of text
 		files when splitTables is true. In the latter case, the 'fileOrPath'
 		argument should be a path to a directory.
@@ -223,6 +224,7 @@
 		import xmlWriter
 		
 		self.disassembleInstructions = disassembleInstructions
+		self.bitmapGlyphDataFormat = bitmapGlyphDataFormat
 		if not tables:
 			tables = self.keys()
 			if "GlyphOrder" not in tables:
diff --git a/Lib/fontTools/ttLib/tables/BitmapGlyphMetrics.py b/Lib/fontTools/ttLib/tables/BitmapGlyphMetrics.py
new file mode 100644
index 0000000..9cf4667
--- /dev/null
+++ b/Lib/fontTools/ttLib/tables/BitmapGlyphMetrics.py
@@ -0,0 +1,57 @@
+# Since bitmap glyph metrics are shared between EBLC and EBDT
+# this class gets its own python file.
+import sstruct
+from types import TupleType
+from fontTools.misc.textTools import safeEval
+
+
+bigGlyphMetricsFormat = """
+  > # big endian
+  height:       B
+  width:        B
+  horiBearingX: b
+  horiBearingY: b
+  horiAdvance:  B
+  vertBearingX: b
+  vertBearingY: b
+  vertAdvance:  B
+"""
+
+smallGlyphMetricsFormat = """
+  > # big endian
+  height:   B
+  width:    B
+  BearingX: b
+  BearingY: b
+  Advance:  B
+"""
+
+class BitmapGlyphMetrics:
+
+	def toXML(self, writer, ttFont):
+		writer.begintag(self.__class__.__name__)
+		writer.newline()
+		for metricName in sstruct.getformat(self.__class__.binaryFormat)[1]:
+			writer.simpletag(metricName, value=getattr(self, metricName))
+			writer.newline()
+		writer.endtag(self.__class__.__name__)
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		metricNames = set(sstruct.getformat(self.__class__.binaryFormat)[1])
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attrs, content = element
+			# Make sure this is a metric that is needed by GlyphMetrics.
+			if name in metricNames:
+				vars(self)[name] = safeEval(attrs['value'])
+			else:
+				print "Warning: unknown name '%s' being ignored in %s." % name, self.__class__.__name__
+
+
+class BigGlyphMetrics(BitmapGlyphMetrics):
+	binaryFormat = bigGlyphMetricsFormat
+	
+class SmallGlyphMetrics(BitmapGlyphMetrics):
+	binaryFormat = smallGlyphMetricsFormat
diff --git a/Lib/fontTools/ttLib/tables/E_B_D_T_.py b/Lib/fontTools/ttLib/tables/E_B_D_T_.py
new file mode 100644
index 0000000..5e62693
--- /dev/null
+++ b/Lib/fontTools/ttLib/tables/E_B_D_T_.py
@@ -0,0 +1,749 @@
+
+import DefaultTable
+import os
+import string
+import struct
+import sstruct
+import itertools
+from types import TupleType
+from fontTools.misc.textTools import safeEval, readHex, hexStr, deHexStr
+from BitmapGlyphMetrics import BigGlyphMetrics, bigGlyphMetricsFormat, SmallGlyphMetrics, smallGlyphMetricsFormat
+
+ebdtTableVersionFormat = """
+	> # big endian
+	version: 16.16F
+"""
+
+ebdtComponentFormat = """
+	> # big endian
+	glyphCode: H
+	xOffset:   b
+	yOffset:   b
+"""
+
+class table_E_B_D_T_(DefaultTable.DefaultTable):
+
+	# Keep a reference to the name of the data locator table.
+	locatorName = 'EBLC'
+
+	# This method can be overridden in subclasses to support new formats
+	# without changing the other implementation. Also can be used as a
+	# convenience method for coverting a font file to an alternative format.
+	def getImageFormatClass(self, imageFormat):
+		return ebdt_bitmap_classes[imageFormat]
+
+	def decompile(self, data, ttFont):
+		# Get the version but don't advance the slice.
+		# Most of the lookup for this table is done relative
+		# to the begining so slice by the offsets provided
+		# in the EBLC table.
+		sstruct.unpack2(ebdtTableVersionFormat, data, self)
+
+		# Keep a dict of glyphs that have been seen so they aren't remade.
+		# This dict maps intervals of data to the BitmapGlyph.
+		glyphDict = {}
+
+		# Pull out the EBLC table and loop through glyphs.
+		# A strike is a concept that spans both tables.
+		# The actual bitmap data is stored in the EBDT.
+		locator = ttFont[self.__class__.locatorName]
+		self.strikeData = []
+		for curStrike in locator.strikes:
+			bitmapGlyphDict = {}
+			self.strikeData.append(bitmapGlyphDict)
+			for indexSubTable in curStrike.indexSubTables:
+				dataIter = itertools.izip(indexSubTable.names, indexSubTable.locations)
+				for curName, curLoc in dataIter:
+					# Don't create duplicate data entries for the same glyphs.
+					# Instead just use the structures that already exist if they exist.
+					if curLoc in glyphDict:
+						curGlyph = glyphDict[curLoc]
+					else:
+						curGlyphData = data[slice(*curLoc)]
+						imageFormatClass = self.getImageFormatClass(indexSubTable.imageFormat)
+						curGlyph = imageFormatClass(curGlyphData, ttFont)
+						glyphDict[curLoc] = curGlyph
+					bitmapGlyphDict[curName] = curGlyph
+
+	def compile(self, ttFont):
+
+		dataList = []
+		dataList.append(sstruct.pack(ebdtTableVersionFormat, self))
+		dataSize = len(dataList[0])
+
+		# Keep a dict of glyphs that have been seen so they aren't remade.
+		# This dict maps the id of the BitmapGlyph to the interval
+		# in the data.
+		glyphDict = {}
+
+		# Go through the bitmap glyph data. Just in case the data for a glyph
+		# changed the size metrics should be recalculated. There are a variety
+		# of formats and they get stored in the EBLC table. That is why
+		# recalculation is defered to the EblcIndexSubTable class and just
+		# pass what is known about bitmap glyphs from this particular table.
+		locator = ttFont[self.__class__.locatorName]
+		for curStrike, curGlyphDict in itertools.izip(locator.strikes, self.strikeData):
+			for curIndexSubTable in curStrike.indexSubTables:
+				dataLocations = []
+				for curName in curIndexSubTable.names:
+					# Handle the data placement based on seeing the glyph or not.
+					# Just save a reference to the location if the glyph has already
+					# been saved in compile. This code assumes that glyphs will only
+					# be referenced multiple times from indexFormat5. By luck the
+					# code may still work when referencing poorly ordered fonts with
+					# duplicate references. If there is a font that is unlucky the
+					# respective compile methods for the indexSubTables will fail
+					# their assertions. All fonts seem to follow this assumption.
+					# More complicated packing may be needed if a counter-font exists.
+					glyph = curGlyphDict[curName]
+					objectId = id(glyph)
+					if objectId not in glyphDict:
+						data = glyph.compile(ttFont)
+						data = curIndexSubTable.padBitmapData(data)
+						startByte = dataSize
+						dataSize += len(data)
+						endByte = dataSize
+						dataList.append(data)
+						dataLoc = (startByte, endByte)
+						glyphDict[objectId] = dataLoc
+					else:
+						dataLoc = glyphDict[objectId]
+					dataLocations.append(dataLoc)
+				# Just use the new data locations in the indexSubTable.
+				# The respective compile implementations will take care
+				# of any of the problems in the convertion that may arise.
+				curIndexSubTable.locations = dataLocations
+
+		return string.join(dataList, "")
+
+	def toXML(self, writer, ttFont):
+		# When exporting to XML if one of the data export formats
+		# requires metrics then those metrics may be in the locator.
+		# In this case populate the bitmaps with "export metrics".
+		if ttFont.bitmapGlyphDataFormat in ('row', 'bitwise'):
+			locator = ttFont[self.__class__.locatorName]
+			for curStrike, curGlyphDict in itertools.izip(locator.strikes, self.strikeData):
+				for curIndexSubTable in curStrike.indexSubTables:
+					for curName in curIndexSubTable.names:
+						glyph = curGlyphDict[curName]
+						# I'm not sure which metrics have priority here.
+						# For now if both metrics exist go with glyph metrics.
+						if hasattr(glyph, 'metrics'):
+							glyph.exportMetrics = glyph.metrics
+						else:
+							glyph.exportMetrics = curIndexSubTable.metrics
+						glyph.exportBitDepth = curStrike.bitmapSizeTable.bitDepth
+
+		writer.simpletag("header", [('version', self.version)])
+		writer.newline()
+		locator = ttFont[self.__class__.locatorName]
+		for strikeIndex, bitmapGlyphDict in enumerate(self.strikeData):
+			writer.begintag('strikedata', [('index', strikeIndex)])
+			writer.newline()
+			for curName, curBitmap in bitmapGlyphDict.items():
+				curBitmap.toXML(strikeIndex, curName, writer, ttFont)
+			writer.endtag('strikedata')
+			writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		if name == 'header':
+			self.version = safeEval(attrs['version'])
+		elif name == 'strikedata':
+			if not hasattr(self, 'strikeData'):
+				self.strikeData = []
+			strikeIndex = safeEval(attrs['index'])
+
+			bitmapGlyphDict = {}
+			for element in content:
+				if type(element) != TupleType:
+					continue
+				name, attrs, content = element
+				if name[4:].startswith(_bitmapGlyphSubclassPrefix[4:]):
+					imageFormat =	safeEval(name[len(_bitmapGlyphSubclassPrefix):])
+					glyphName = attrs['name']
+					imageFormatClass = self.getImageFormatClass(imageFormat)
+					curGlyph = imageFormatClass(None, None)
+					curGlyph.fromXML(element, ttFont)
+					assert glyphName not in bitmapGlyphDict, "Duplicate glyphs with the same name '%s' in the same strike." % glyphName
+					bitmapGlyphDict[glyphName] = curGlyph
+				else:
+					print "Warning: %s being ignored by %s", name, self.__class__.__name__
+
+			# Grow the strike data array to the appropriate size. The XML
+			# format allows the strike index value to be out of order.
+			if strikeIndex >= len(self.strikeData):
+				self.strikeData += [None] * (strikeIndex + 1 - len(self.strikeData))
+			assert self.strikeData[strikeIndex] == None, "Duplicate strike EBDT indices."
+			self.strikeData[strikeIndex] = bitmapGlyphDict
+
+class EbdtComponent:
+
+	def toXML(self, writer, ttFont):
+		writer.begintag('ebdtComponent', [('name', self.name)])
+		writer.newline()
+		for componentName in sstruct.getformat(ebdtComponentFormat)[1][1:]:
+			writer.simpletag(componentName, value=getattr(self, componentName))
+			writer.newline()
+		writer.endtag('ebdtComponent')
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		self.name = attrs['name']
+		componentNames = set(sstruct.getformat(ebdtComponentFormat)[1][1:])
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attrs, content = element
+			if name in componentNames:
+				vars(self)[name] = safeEval(attrs['value'])
+			else:
+				print "Warning: unknown name '%s' being ignored by EbdtComponent." % name
+
+# Helper functions for dealing with binary.
+
+def _data2binary(data, numBits):
+	binaryList = []
+	for curByte in data:
+		value = ord(curByte)
+		numBitsCut = min(8, numBits)
+		for i in xrange(numBitsCut):
+			if value & 0x1:
+				binaryList.append('1')
+			else:
+				binaryList.append('0')
+			value = value >> 1
+		numBits -= numBitsCut
+	return string.join(binaryList, "")
+
+def _binary2data(binary):
+	byteList = []
+	for bitLoc in xrange(0, len(binary), 8):
+		byteString = binary[bitLoc:bitLoc+8]
+		curByte = 0
+		for curBit in reversed(byteString):
+			curByte = curByte << 1
+			if curBit == '1':
+				curByte |= 1
+		byteList.append(chr(curByte))
+	return string.join(byteList, "")
+
+def _memoize(f):
+	class memodict(dict):
+		def __missing__(self, key):
+			ret = f(key)
+			if len(key) == 1:
+				self[key] = ret
+			return ret
+	return memodict().__getitem__
+
+# 00100111 -> 11100100 per byte, not to be confused with little/big endian.
+# Bitmap data per byte is in the order that binary is written on the page
+# with the least significant bit as far right as possible. This is the
+# opposite of what makes sense algorithmically and hence this function.
+@_memoize
+def _reverseBytes(data):
+	if len(data) != 1:
+		return string.join(map(_reverseBytes, data), "")
+	byte = ord(data)
+	result = 0
+	for i in xrange(8):
+		result = result << 1
+		result |= byte & 1
+		byte = byte >> 1
+	return chr(result)
+
+# This section of code is for reading and writing image data to/from XML.
+
+def _writeRawImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont):
+	writer.begintag('rawimagedata')
+	writer.newline()
+	writer.dumphex(bitmapObject.imageData)
+	writer.endtag('rawimagedata')
+	writer.newline()
+
+def _readRawImageData(bitmapObject, (name, attrs, content), ttFont):
+	bitmapObject.imageData = readHex(content)
+
+def _writeRowImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont):
+	metrics = bitmapObject.exportMetrics
+	del bitmapObject.exportMetrics
+	bitDepth = bitmapObject.exportBitDepth
+	del bitmapObject.exportBitDepth
+
+	writer.begintag('rowimagedata', bitDepth=bitDepth, width=metrics.width, height=metrics.height)
+	writer.newline()
+	for curRow in xrange(metrics.height):
+		rowData = bitmapObject.getRow(curRow, bitDepth=bitDepth, metrics=metrics)
+		writer.simpletag('row', value=hexStr(rowData))
+		writer.newline()
+	writer.endtag('rowimagedata')
+	writer.newline()
+
+def _readRowImageData(bitmapObject, (name, attrs, content), ttFont):
+	bitDepth = safeEval(attrs['bitDepth'])
+	metrics = SmallGlyphMetrics()
+	metrics.width = safeEval(attrs['width'])
+	metrics.height = safeEval(attrs['height'])
+
+	dataRows = []
+	for element in content:
+		if type(element) != TupleType:
+			continue
+		name, attr, content = element
+		# Chop off 'imagedata' from the tag to get just the option.
+		if name == 'row':
+			dataRows.append(deHexStr(attr['value']))
+	bitmapObject.setRows(dataRows, bitDepth=bitDepth, metrics=metrics)
+
+def _writeBitwiseImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont):
+	metrics = bitmapObject.exportMetrics
+	del bitmapObject.exportMetrics
+	bitDepth = bitmapObject.exportBitDepth
+	del bitmapObject.exportBitDepth
+
+	# A dict for mapping binary to more readable/artistic ASCII characters.
+	binaryConv = {'0':'.', '1':'@'}
+
+	writer.begintag('bitwiseimagedata', bitDepth=bitDepth, width=metrics.width, height=metrics.height)
+	writer.newline()
+	for curRow in xrange(metrics.height):
+		rowData = bitmapObject.getRow(curRow, bitDepth=1, metrics=metrics, reverseBytes=True)
+		rowData = _data2binary(rowData, metrics.width)
+		# Make the output a readable ASCII art form.
+		rowData = string.join(map(binaryConv.get, rowData), "")
+		writer.simpletag('row', value=rowData)
+		writer.newline()
+	writer.endtag('bitwiseimagedata')
+	writer.newline()
+
+def _readBitwiseImageData(bitmapObject, (name, attrs, content), ttFont):
+	bitDepth = safeEval(attrs['bitDepth'])
+	metrics = SmallGlyphMetrics()
+	metrics.width = safeEval(attrs['width'])
+	metrics.height = safeEval(attrs['height'])
+
+	# A dict for mapping from ASCII to binary. All characters are considered
+	# a '1' except space, period and '0' which maps to '0'.
+	binaryConv = {' ':'0', '.':'0', '0':'0'}
+
+	dataRows = []
+	for element in content:
+		if type(element) != TupleType:
+			continue
+		name, attr, content = element
+		if name == 'row':
+			mapParams = itertools.izip(attr['value'], itertools.repeat('1'))
+			rowData = string.join(itertools.starmap(binaryConv.get, mapParams), "")
+			dataRows.append(_binary2data(rowData))
+
+	bitmapObject.setRows(dataRows, bitDepth=bitDepth, metrics=metrics, reverseBytes=True)
+
+def _writeExtFileImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont):
+	folder = 'bitmaps/'
+	filename = glyphName + bitmapObject.fileExtension
+	if not os.path.isdir(folder):
+		os.makedirs(folder)
+	folder += 'strike%d/' % strikeIndex
+	if not os.path.isdir(folder):
+		os.makedirs(folder)
+
+	fullPath = folder + filename
+	writer.simpletag('extfileimagedata', value=fullPath)
+	writer.newline()
+
+	with open(fullPath, "wb") as file:
+		file.write(bitmapObject.imageData)
+
+def _readExtFileImageData(bitmapObject, (name, attrs, content), ttFont):
+	fullPath = attrs['value']
+	with open(fullPath, "rb") as file:
+		bitmapObject.imageData = file.read()
+
+# End of XML writing code.
+
+# Important information about the naming scheme. Used for identifying formats
+# in XML.
+_bitmapGlyphSubclassPrefix = 'ebdt_bitmap_format_'
+
+class BitmapGlyph:
+
+	# For the external file format. This can be changed in subclasses. This way
+	# when the extfile option is turned on files have the form: glyphName.ext
+	# The default is just a flat binary file with no meaning.
+	fileExtension = '.bin'
+
+	# Keep track of reading and writing of various forms.
+	xmlDataFunctions = {
+		'raw':       (_writeRawImageData, _readRawImageData),
+		'row':       (_writeRowImageData, _readRowImageData),
+		'bitwise':   (_writeBitwiseImageData, _readBitwiseImageData),
+		'extfile':   (_writeExtFileImageData, _readExtFileImageData),
+		}
+
+	def __init__(self, data, ttFont):
+		self.data = data
+		self.ttFont = ttFont
+
+	def __getattr__(self, attr):
+		# Allow lazy decompile.
+		if attr[:2] == '__':
+			raise AttributeError, attr
+		if self.data == None:
+			raise AttributeError, attr
+		self.decompile()
+		self.data = None
+		return getattr(self, attr)
+
+	# Not a fan of this but it is needed for safer safety checking.
+	def getFormat(self):
+		return safeEval(self.__class__.__name__[len(_bitmapGlyphSubclassPrefix):])
+
+	def toXML(self, strikeIndex, glyphName, writer, ttFont):
+		writer.begintag(self.__class__.__name__, [('name', glyphName)])
+		writer.newline()
+
+		self.writeMetrics(writer, ttFont)
+		# Use the internal write method to write using the correct output format.
+		self.writeData(strikeIndex, glyphName, writer, ttFont)
+
+		writer.endtag(self.__class__.__name__)
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		self.readMetrics((name, attrs, content), ttFont)
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attr, content = element
+			# Chop off 'imagedata' from the tag to get just the option.
+			option = name[:-len('imagedata')]
+			if option in self.__class__.xmlDataFunctions:
+				self.readData(element, ttFont)
+
+	# Some of the glyphs have the metrics. This allows for metrics to be
+	# added if the glyph format has them. Default behavior is to do nothing.
+	def writeMetrics(self, writer, ttFont):
+		pass
+
+	# The opposite of write metrics.
+	def readMetrics(self, (name, attrs, content), ttFont):
+		pass
+
+	def writeData(self, strikeIndex, glyphName, writer, ttFont):
+		try:
+			writeFunc, readFunc = self.__class__.xmlDataFunctions[ttFont.bitmapGlyphDataFormat]
+		except KeyError:
+			writeFunc = _writeRawImageData
+		writeFunc(strikeIndex, glyphName, self, writer, ttFont)
+
+	def readData(self, (name, attrs, content), ttFont):
+		# Chop off 'imagedata' from the tag to get just the option.
+		option = name[:-len('imagedata')]
+		writeFunc, readFunc = self.__class__.xmlDataFunctions[option]
+		readFunc(self, (name, attrs, content), ttFont)
+
+
+# A closure for creating a mixin for the two types of metrics handling.
+# Most of the code is very similar so its easier to deal with here.
+# Everything works just by passing the class that the mixin is for.
+def _createBitmapPlusMetricsMixin(metricsClass):
+	# Both metrics names are listed here to make meaningful error messages.
+	metricStrings = [BigGlyphMetrics.__name__, SmallGlyphMetrics.__name__]
+	curMetricsName = metricsClass.__name__
+	# Find which metrics this is for and determine the opposite name.
+	metricsId = metricStrings.index(curMetricsName)
+	oppositeMetricsName = metricStrings[1-metricsId]
+
+	class BitmapPlusMetricsMixin:
+
+		def writeMetrics(self, writer, ttFont):
+			self.metrics.toXML(writer, ttFont)
+
+		def readMetrics(self, (name, attrs, content), ttFont):
+			for element in content:
+				if type(element) != TupleType:
+					continue
+				name, attrs, content = element
+				if name == curMetricsName:
+					self.metrics = metricsClass()
+					self.metrics.fromXML(element, ttFont)
+				elif name == oppositeMetricsName:
+					print "Warning: %s being ignored in format %d." % oppositeMetricsName, self.getFormat()
+
+	return BitmapPlusMetricsMixin
+
+# Since there are only two types of mixin's just create them here.
+BitmapPlusBigMetricsMixin = _createBitmapPlusMetricsMixin(BigGlyphMetrics)
+BitmapPlusSmallMetricsMixin = _createBitmapPlusMetricsMixin(SmallGlyphMetrics)
+
+# Data that is bit aligned can be tricky to deal with. These classes implement
+# helper functionality for dealing with the data and getting a particular row
+# of bitwise data. Also helps implement fancy data export/import in XML.
+class BitAlignedBitmapMixin:
+
+	def _getBitRange(self, row, bitDepth, metrics):
+		rowBits = (bitDepth * metrics.width)
+		bitOffset = row * rowBits
+		return (bitOffset, bitOffset+rowBits)
+
+	def getRow(self, row, bitDepth=1, metrics=None, reverseBytes=False):
+		if metrics == None:
+			metrics = self.metrics
+		assert 0 <= row and row < metrics.height, "Illegal row access in bitmap"
+
+		# Loop through each byte. This can cover two bytes in the original data or
+		# a single byte if things happen to be aligned. The very last entry might
+		# not be aligned so take care to trim the binary data to size and pad with
+		# zeros in the row data. Bit aligned data is somewhat tricky.
+		#
+		# Example of data cut. Data cut represented in x's.
+		# '|' represents byte boundary.
+		# data = ...0XX|XXXXXX00|000... => XXXXXXXX
+		#		or
+		# data = ...0XX|XXXX0000|000... => XXXXXX00
+		#   or
+		# data = ...000|XXXXXXXX|000... => XXXXXXXX
+		#   or
+		# data = ...000|00XXXX00|000... => XXXX0000
+		#
+		dataList = []
+		bitRange = self._getBitRange(row, bitDepth, metrics)
+		stepRange = bitRange + (8,)
+		for curBit in xrange(*stepRange):
+			endBit = min(curBit+8, bitRange[1])
+			numBits = endBit - curBit
+			cutPoint = curBit % 8
+			firstByteLoc = curBit / 8
+			secondByteLoc = endBit / 8
+			if firstByteLoc < secondByteLoc:
+				numBitsCut = 8 - cutPoint
+			else:
+				numBitsCut = endBit - curBit
+			curByte = _reverseBytes(self.imageData[firstByteLoc])
+			firstHalf = ord(curByte) >> cutPoint
+			firstHalf = ((1<<numBitsCut)-1) & firstHalf
+			newByte = firstHalf
+			if firstByteLoc < secondByteLoc and secondByteLoc < len(self.imageData):
+				curByte = _reverseBytes(self.imageData[secondByteLoc])
+				secondHalf = ord(curByte) << numBitsCut
+				newByte = (firstHalf | secondHalf) & ((1<<numBits)-1)
+			dataList.append(chr(newByte))
+
+		# The way the data is kept is opposite the algorithm used.
+		data = string.join(dataList, "")
+		if not reverseBytes:
+			data = _reverseBytes(data)
+		return data
+
+	def setRows(self, dataRows, bitDepth=1, metrics=None, reverseBytes=False):
+		if metrics == None:
+			metrics = self.metrics
+		if not reverseBytes:
+			dataRows = map(_reverseBytes, dataRows)
+
+		# Keep track of a list of ordinal values as they are easier to modify
+		# than a list of strings. Map to actual strings later.
+		numBytes = (self._getBitRange(len(dataRows), bitDepth, metrics)[0] + 7) / 8
+		ordDataList = [0] * numBytes
+		for row, data in enumerate(dataRows):
+			bitRange = self._getBitRange(row, bitDepth, metrics)
+			stepRange = bitRange + (8,)
+			for curBit, curByte in itertools.izip(xrange(*stepRange), data):
+				endBit = min(curBit+8, bitRange[1])
+				cutPoint = curBit % 8
+				firstByteLoc = curBit / 8
+				secondByteLoc = endBit / 8
+				if firstByteLoc < secondByteLoc:
+					numBitsCut = 8 - cutPoint
+				else:
+					numBitsCut = endBit - curBit
+				curByte = ord(curByte)
+				firstByte = curByte & ((1<<numBitsCut)-1)
+				ordDataList[firstByteLoc] |= (firstByte << cutPoint)
+				if firstByteLoc < secondByteLoc and secondByteLoc < numBytes:
+					secondByte = (curByte >> numBitsCut) & ((1<<8-numBitsCut)-1)
+					ordDataList[secondByteLoc] |= secondByte
+
+		# Save the image data with the bits going the correct way.
+		self.imageData = _reverseBytes(string.join(map(chr, ordDataList), ""))
+
+class ByteAlignedBitmapMixin:
+
+	def _getByteRange(self, row, bitDepth, metrics):
+		rowBytes = (bitDepth * metrics.width + 7) / 8
+		byteOffset = row * rowBytes
+		return (byteOffset, byteOffset+rowBytes)
+
+	def getRow(self, row, bitDepth=1, metrics=None, reverseBytes=False):
+		if metrics == None:
+			metrics = self.metrics
+		assert 0 <= row and row < metrics.height, "Illegal row access in bitmap"
+		byteRange = self._getByteRange(row, bitDepth, metrics)
+		data = self.imageData[slice(*byteRange)]
+		if reverseBytes:
+			data = _reverseBytes(data)
+		return data
+
+	def setRows(self, dataRows, bitDepth=1, metrics=None, reverseBytes=False):
+		if metrics == None:
+			metrics = self.metrics
+		if reverseBytes:
+			dataRows = map(_reverseBytes, dataRows)
+		self.imageData = string.join(dataRows, "")
+
+class ebdt_bitmap_format_1(ByteAlignedBitmapMixin, BitmapPlusSmallMetricsMixin, BitmapGlyph):
+
+	def decompile(self):
+		self.metrics = SmallGlyphMetrics()
+		dummy, data = sstruct.unpack2(smallGlyphMetricsFormat, self.data, self.metrics)
+		self.imageData = data
+
+	def compile(self, ttFont):
+		data = sstruct.pack(smallGlyphMetricsFormat, self.metrics)
+		return data + self.imageData
+
+
+class ebdt_bitmap_format_2(BitAlignedBitmapMixin, BitmapPlusSmallMetricsMixin, BitmapGlyph):
+
+	def decompile(self):
+		self.metrics = SmallGlyphMetrics()
+		dummy, data = sstruct.unpack2(smallGlyphMetricsFormat, self.data, self.metrics)
+		self.imageData = data
+
+	def compile(self, ttFont):
+		data = sstruct.pack(smallGlyphMetricsFormat, self.metrics)
+		return data + self.imageData
+
+
+class ebdt_bitmap_format_5(BitAlignedBitmapMixin, BitmapGlyph):
+
+	def decompile(self):
+		self.imageData = self.data
+
+	def compile(self, ttFont):
+		return self.imageData
+
+class ebdt_bitmap_format_6(ByteAlignedBitmapMixin, BitmapPlusBigMetricsMixin, BitmapGlyph):
+
+	def decompile(self):
+		self.metrics = BigGlyphMetrics()
+		dummy, data = sstruct.unpack2(bigGlyphMetricsFormat, self.data, self.metrics)
+		self.imageData = data
+
+	def compile(self, ttFont):
+		data = sstruct.pack(bigGlyphMetricsFormat, self.metrics)
+		return data + self.imageData
+
+
+class ebdt_bitmap_format_7(BitAlignedBitmapMixin, BitmapPlusBigMetricsMixin, BitmapGlyph):
+
+	def decompile(self):
+		self.metrics = BigGlyphMetrics()
+		dummy, data = sstruct.unpack2(bigGlyphMetricsFormat, self.data, self.metrics)
+		self.imageData = data
+
+	def compile(self, ttFont):
+		data = sstruct.pack(bigGlyphMetricsFormat, self.metrics)
+		return data + self.imageData
+
+
+class ComponentBitmapGlyph(BitmapGlyph):
+
+	def toXML(self, strikeIndex, glyphName, writer, ttFont):
+		writer.begintag(self.__class__.__name__, [('name', glyphName)])
+		writer.newline()
+
+		self.writeMetrics(writer, ttFont)
+
+		writer.begintag('components')
+		writer.newline()
+		for curComponent in self.componentArray:
+			curComponent.toXML(writer, ttFont)
+		writer.endtag('components')
+		writer.newline()
+
+		writer.endtag(self.__class__.__name__)
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		self.readMetrics((name, attrs, content), ttFont)
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attr, content = element
+			if name == 'components':
+				self.componentArray = []
+				for compElement in content:
+					if type(compElement) != TupleType:
+						continue
+					name, attr, content = compElement
+					if name == 'ebdtComponent':
+						curComponent = EbdtComponent()
+						curComponent.fromXML(compElement, ttFont)
+						self.componentArray.append(curComponent)
+					else:
+						print "Warning: '%s' being ignored in component array." % name
+
+
+class ebdt_bitmap_format_8(BitmapPlusSmallMetricsMixin, ComponentBitmapGlyph):
+
+	def decompile(self):
+		self.metrics = SmallGlyphMetrics()
+		dummy, data = sstruct.unpack2(smallGlyphMetricsFormat, self.data, self.metrics)
+		data = data[1:]
+
+		(numComponents,) = struct.unpack(">H", data[:2])
+		data = data[2:]
+		self.componentArray = []
+		for i in xrange(numComponents):
+			curComponent = EbdtComponent()
+			dummy, data = sstruct.unpack2(ebdtComponentFormat, data, curComponent)
+			curComponent.name = self.ttFont.getGlyphName(curComponent.glyphCode)
+			self.componentArray.append(curComponent)
+
+	def compile(self, ttFont):
+		dataList = []
+		dataList.append(sstruct.pack(smallGlyphMetricsFormat, self.metrics))
+		dataList.append('\0')
+		dataList.append(struct.pack(">H", len(self.componentArray)))
+		for curComponent in self.componentArray:
+			curComponent.glyphCode = ttFont.getGlyphID(curComponent.name)
+			dataList.append(sstruct.pack(ebdtComponentFormat, curComponent))
+		return string.join(dataList, "")
+
+
+class ebdt_bitmap_format_9(BitmapPlusBigMetricsMixin, ComponentBitmapGlyph):
+
+	def decompile(self):
+		self.metrics = BigGlyphMetrics()
+		dummy, data = sstruct.unpack2(bigGlyphMetricsFormat, self.data, self.metrics)
+		(numComponents,) = struct.unpack(">H", data[:2])
+		data = data[2:]
+		self.componentArray = []
+		for i in xrange(numComponents):
+			curComponent = EbdtComponent()
+			dummy, data = sstruct.unpack2(ebdtComponentFormat, data, curComponent)
+			curComponent.name = self.ttFont.getGlyphName(curComponent.glyphCode)
+			self.componentArray.append(curComponent)
+
+	def compile(self, ttFont):
+		dataList = []
+		dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
+		dataList.append(struct.pack(">H", len(self.componentArray)))
+		for curComponent in self.componentArray:
+			curComponent.glyphCode = ttFont.getGlyphID(curComponent.name)
+			dataList.append(sstruct.pack(ebdtComponentFormat, curComponent))
+		return string.join(dataList, "")
+
+
+# Dictionary of bitmap formats to the class representing that format
+# currently only the ones listed in this map are the ones supported.
+ebdt_bitmap_classes = {
+		1: ebdt_bitmap_format_1,
+		2: ebdt_bitmap_format_2,
+		5: ebdt_bitmap_format_5,
+		6: ebdt_bitmap_format_6,
+		7: ebdt_bitmap_format_7,
+		8: ebdt_bitmap_format_8,
+		9: ebdt_bitmap_format_9,
+	}
diff --git a/Lib/fontTools/ttLib/tables/E_B_L_C_.py b/Lib/fontTools/ttLib/tables/E_B_L_C_.py
new file mode 100644
index 0000000..bb6e415
--- /dev/null
+++ b/Lib/fontTools/ttLib/tables/E_B_L_C_.py
@@ -0,0 +1,614 @@
+
+import DefaultTable
+import string
+import struct
+import sstruct
+import itertools
+from types import TupleType
+from collections import deque
+from fontTools.misc.textTools import safeEval
+from BitmapGlyphMetrics import BigGlyphMetrics, bigGlyphMetricsFormat, SmallGlyphMetrics, smallGlyphMetricsFormat
+
+eblcHeaderFormat = """
+	> # big endian
+	version:  16.16F
+	numSizes: I
+"""
+# The table format string is split to handle sbitLineMetrics simply.
+bitmapSizeTableFormatPart1 = """
+	> # big endian
+	indexSubTableArrayOffset: I
+	indexTablesSize:          I
+	numberOfIndexSubTables:   I
+	colorRef:                 I
+"""
+# The compound type for hori and vert.
+sbitLineMetricsFormat = """
+	> # big endian
+	ascender:              b
+	descender:             b
+	widthMax:              B
+	caretSlopeNumerator:   b
+	caretSlopeDenominator: b
+	caretOffset:           b
+	minOriginSB:           b
+	minAdvanceSB:          b
+	maxBeforeBL:           b
+	minAfterBL:            b
+	pad1:                  b
+	pad2:                  b
+"""
+# hori and vert go between the two parts.
+bitmapSizeTableFormatPart2 = """
+	> # big endian
+	startGlyphIndex: H
+	endGlyphIndex:   H
+	ppemX:           B
+	ppemY:           B
+	bitDepth:        B
+	flags:           b
+"""
+
+indexSubTableArrayFormat = ">HHL"
+indexSubTableArraySize = struct.calcsize(indexSubTableArrayFormat)
+
+indexSubHeaderFormat = ">HHL"
+indexSubHeaderSize = struct.calcsize(indexSubHeaderFormat)
+
+codeOffsetPairFormat = ">HH"
+codeOffsetPairSize = struct.calcsize(codeOffsetPairFormat)
+
+class table_E_B_L_C_(DefaultTable.DefaultTable):
+
+	dependencies = ['EBDT']
+
+	# This method can be overridden in subclasses to support new formats
+	# without changing the other implementation. Also can be used as a
+	# convenience method for coverting a font file to an alternative format.
+	def getIndexFormatClass(self, indexFormat):
+		return eblc_sub_table_classes[indexFormat]
+
+	def decompile(self, data, ttFont):
+
+		# Save the original data because offsets are from the start of the table.
+		origData = data
+
+		dummy, data = sstruct.unpack2(eblcHeaderFormat, data, self)
+
+		self.strikes = []
+		for curStrikeIndex in xrange(self.numSizes):
+			curStrike = Strike()
+			self.strikes.append(curStrike)
+			curTable = curStrike.bitmapSizeTable
+			dummy, data = sstruct.unpack2(bitmapSizeTableFormatPart1, data, curTable)
+			for metric in ('hori', 'vert'):
+				metricObj = SbitLineMetrics()
+				vars(curTable)[metric] = metricObj
+				dummy, data = sstruct.unpack2(sbitLineMetricsFormat, data, metricObj)
+			dummy, data = sstruct.unpack2(bitmapSizeTableFormatPart2, data, curTable)
+
+		for curStrike in self.strikes:
+			curTable = curStrike.bitmapSizeTable
+			for subtableIndex in xrange(curTable.numberOfIndexSubTables):
+				lowerBound = curTable.indexSubTableArrayOffset + subtableIndex * indexSubTableArraySize
+				upperBound = lowerBound + indexSubTableArraySize
+				data = origData[lowerBound:upperBound]
+
+				tup = struct.unpack(indexSubTableArrayFormat, data)
+				(firstGlyphIndex, lastGlyphIndex, additionalOffsetToIndexSubtable) = tup
+				offsetToIndexSubTable = curTable.indexSubTableArrayOffset + additionalOffsetToIndexSubtable
+				data = origData[offsetToIndexSubTable:]
+
+				tup = struct.unpack(indexSubHeaderFormat, data[:indexSubHeaderSize])
+				(indexFormat, imageFormat, imageDataOffset) = tup
+
+				indexFormatClass = self.getIndexFormatClass(indexFormat)
+				indexSubTable = indexFormatClass(data[indexSubHeaderSize:], ttFont)
+				indexSubTable.firstGlyphIndex = firstGlyphIndex
+				indexSubTable.lastGlyphIndex = lastGlyphIndex
+				indexSubTable.additionalOffsetToIndexSubtable = additionalOffsetToIndexSubtable
+				indexSubTable.indexFormat = indexFormat
+				indexSubTable.imageFormat = imageFormat
+				indexSubTable.imageDataOffset = imageDataOffset
+				curStrike.indexSubTables.append(indexSubTable)
+
+	def compile(self, ttFont):
+
+		dataList = []
+		self.numSizes = len(self.strikes)
+		dataList.append(sstruct.pack(eblcHeaderFormat, self))
+
+		# Data size of the header + bitmapSizeTable needs to be calculated
+		# in order to form offsets. This value will hold the size of the data
+		# in dataList after all the data is consolidated in dataList.
+		dataSize = len(dataList[0])
+
+		# The table will be structured in the following order:
+		# (0) header
+		# (1) Each bitmapSizeTable [1 ... self.numSizes]
+		# (2) Alternate between indexSubTableArray and indexSubTable
+		#     for each bitmapSizeTable present.
+		#
+		# The issue is maintaining the proper offsets when table information
+		# gets moved around. All offsets and size information must be recalculated
+		# when building the table to allow editing within ttLib and also allow easy
+		# import/export to and from XML. All of this offset information is lost
+		# when exporting to XML so everything must be calculated fresh so importing
+		# from XML will work cleanly. Only byte offset and size information is
+		# calculated fresh. Count information like numberOfIndexSubTables is
+		# checked through assertions. If the information in this table was not
+		# touched or was changed properly then these types of values should match.
+		#
+		# The table will be rebuilt the following way:
+		# (0) Precompute the size of all the bitmapSizeTables. This is needed to
+		#     compute the offsets properly.
+		# (1) For each bitmapSizeTable compute the indexSubTable and
+		#    	indexSubTableArray pair. The indexSubTable must be computed first
+		#     so that the offset information in indexSubTableArray can be
+		#     calculated. Update the data size after each pairing.
+		# (2) Build each bitmapSizeTable.
+		# (3) Consolidate all the data into the main dataList in the correct order.
+
+		for curStrike in self.strikes:
+			dataSize += sstruct.calcsize(bitmapSizeTableFormatPart1)
+			dataSize += len(('hori', 'vert')) * sstruct.calcsize(sbitLineMetricsFormat)
+			dataSize += sstruct.calcsize(bitmapSizeTableFormatPart2)
+
+		indexSubTablePairDataList = []
+		for curStrike in self.strikes:
+			curTable = curStrike.bitmapSizeTable
+			curTable.numberOfIndexSubTables = len(curStrike.indexSubTables)
+			curTable.indexSubTableArrayOffset = dataSize
+
+			# Precompute the size of the indexSubTableArray. This information
+			# is important for correctly calculating the new value for
+			# additionalOffsetToIndexSubtable.
+			sizeOfSubTableArray = curTable.numberOfIndexSubTables * indexSubTableArraySize
+			lowerBound = dataSize
+			dataSize += sizeOfSubTableArray
+			upperBound = dataSize
+
+			indexSubTableDataList = []
+			for indexSubTable in curStrike.indexSubTables:
+				indexSubTable.additionalOffsetToIndexSubtable = dataSize - curTable.indexSubTableArrayOffset
+				glyphIds = map(ttFont.getGlyphID, indexSubTable.names)
+				indexSubTable.firstGlyphIndex = min(glyphIds)
+				indexSubTable.lastGlyphIndex = max(glyphIds)
+				data = indexSubTable.compile(ttFont)
+				indexSubTableDataList.append(data)
+				dataSize += len(data)
+			curTable.startGlyphIndex = min(ist.firstGlyphIndex for ist in curStrike.indexSubTables)
+			curTable.endGlyphIndex = max(ist.lastGlyphIndex for ist in curStrike.indexSubTables)
+
+			for i in curStrike.indexSubTables:
+				data = struct.pack(indexSubHeaderFormat, i.firstGlyphIndex, i.lastGlyphIndex, i.additionalOffsetToIndexSubtable)
+				indexSubTablePairDataList.append(data)
+			indexSubTablePairDataList.extend(indexSubTableDataList)
+			curTable.indexTablesSize = dataSize - curTable.indexSubTableArrayOffset
+
+		for curStrike in self.strikes:
+			curTable = curStrike.bitmapSizeTable
+			data = sstruct.pack(bitmapSizeTableFormatPart1, curTable)
+			dataList.append(data)
+			for metric in ('hori', 'vert'):
+				metricObj = vars(curTable)[metric]
+				data = sstruct.pack(sbitLineMetricsFormat, metricObj)
+				dataList.append(data)
+			data = sstruct.pack(bitmapSizeTableFormatPart2, curTable)
+			dataList.append(data)
+		dataList.extend(indexSubTablePairDataList)
+
+		return string.join(dataList, "")
+
+	def toXML(self, writer, ttFont):
+		writer.simpletag('header', [('version', self.version)])
+		writer.newline()
+		for curIndex, curStrike in enumerate(self.strikes):
+			curStrike.toXML(curIndex, writer, ttFont)
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		if name == 'header':
+			self.version = safeEval(attrs['version'])
+		elif name == 'strike':
+			if not hasattr(self, 'strikes'):
+				self.strikes = []
+			strikeIndex = safeEval(attrs['index'])
+			curStrike = Strike()
+			curStrike.fromXML((name, attrs, content), ttFont, self)
+
+			# Grow the strike array to the appropriate size. The XML format
+			# allows for the strike index value to be out of order.
+			if strikeIndex >= len(self.strikes):
+				self.strikes += [None] * (strikeIndex + 1 - len(self.strikes))
+			assert self.strikes[strikeIndex] == None, "Duplicate strike EBLC indices."
+			self.strikes[strikeIndex] = curStrike
+
+class Strike:
+
+	def __init__(self):
+		self.bitmapSizeTable = BitmapSizeTable()
+		self.indexSubTables = []
+
+	def toXML(self, strikeIndex, writer, ttFont):
+		writer.begintag('strike', [('index', strikeIndex)])
+		writer.newline()
+		self.bitmapSizeTable.toXML(writer, ttFont)
+		writer.comment('GlyphIds are written but not read. The firstGlyphIndex and\nlastGlyphIndex values will be recalculated by the compiler.')
+		writer.newline()
+		for indexSubTable in self.indexSubTables:
+			indexSubTable.toXML(writer, ttFont)
+		writer.endtag('strike')
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont, locator):
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attrs, content = element
+			if name == 'bitmapSizeTable':
+				self.bitmapSizeTable.fromXML(element, ttFont)
+			elif name.startswith(_indexSubTableSubclassPrefix):
+				indexFormat = safeEval(name[len(_indexSubTableSubclassPrefix):])
+				indexFormatClass = locator.getIndexFormatClass(indexFormat)
+				indexSubTable = indexFormatClass(None, None)
+				indexSubTable.indexFormat = indexFormat
+				indexSubTable.fromXML(element, ttFont)
+				self.indexSubTables.append(indexSubTable)
+
+
+class BitmapSizeTable:
+
+	# Returns all the simple metric names that bitmap size table
+	# cares about in terms of XML creation.
+	def _getXMLMetricNames(self):
+		dataNames = sstruct.getformat(bitmapSizeTableFormatPart1)[1]
+		dataNames = dataNames + sstruct.getformat(bitmapSizeTableFormatPart2)[1]
+		# Skip the first 3 data names because they are byte offsets and counts.
+		return dataNames[3:]
+
+	def toXML(self, writer, ttFont):
+		writer.begintag('bitmapSizeTable')
+		writer.newline()
+		for metric in ('hori', 'vert'):
+			getattr(self, metric).toXML(metric, writer, ttFont)
+		for metricName in self._getXMLMetricNames():
+			writer.simpletag(metricName, value=getattr(self, metricName))
+			writer.newline()
+		writer.endtag('bitmapSizeTable')
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		# Create a lookup for all the simple names that make sense to
+		# bitmap size table. Only read the information from these names.
+		dataNames = set(self._getXMLMetricNames())
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attrs, content = element
+			if name == 'sbitLineMetrics':
+				direction = attrs['direction']
+				assert direction in ('hori', 'vert'), "SbitLineMetrics direction specified invalid."
+				metricObj = SbitLineMetrics()
+				metricObj.fromXML(element, ttFont)
+				vars(self)[direction] = metricObj
+			elif name in dataNames:
+				vars(self)[name] = safeEval(attrs['value'])
+			else:
+				print "Warning: unknown name '%s' being ignored in BitmapSizeTable." % name
+
+
+class SbitLineMetrics:
+
+	def toXML(self, name, writer, ttFont):
+		writer.begintag('sbitLineMetrics', [('direction', name)])
+		writer.newline()
+		for metricName in sstruct.getformat(sbitLineMetricsFormat)[1]:
+			writer.simpletag(metricName, value=getattr(self, metricName))
+			writer.newline()
+		writer.endtag('sbitLineMetrics')
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		metricNames = set(sstruct.getformat(sbitLineMetricsFormat)[1])
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attrs, content = element
+			if name in metricNames:
+				vars(self)[name] = safeEval(attrs['value'])
+
+# Important information about the naming scheme. Used for identifying subtables.
+_indexSubTableSubclassPrefix = 'eblc_index_sub_table_'
+
+class EblcIndexSubTable:
+
+	def __init__(self, data, ttFont):
+		self.data = data
+		self.ttFont = ttFont
+
+	def __getattr__(self, attr):
+		# Allow lazy decompile.
+		if attr[:2] == '__':
+			raise AttributeError, attr
+		if self.data == None:
+			raise AttributeError, attr
+		self.decompile()
+		self.data = None
+		self.ttFont = None
+		return getattr(self, attr)
+
+	# This method just takes care of the indexSubHeader. Implementing subclasses
+	# should call it to compile the indexSubHeader and then continue compiling
+	# the remainder of their unique format.
+	def compile(self, ttFont):
+		return struct.pack(indexSubHeaderFormat, self.indexFormat, self.imageFormat, self.imageDataOffset)
+
+	# Creates the XML for bitmap glyphs. Each index sub table basically makes
+	# the same XML except for specific metric information that is written
+	# out via a method call that a subclass implements optionally.
+	def toXML(self, writer, ttFont):
+		writer.begintag(self.__class__.__name__, [
+				('imageFormat', self.imageFormat),
+				('firstGlyphIndex', self.firstGlyphIndex),
+				('lastGlyphIndex', self.lastGlyphIndex),
+				])
+		writer.newline()
+		self.writeMetrics(writer, ttFont)
+		# Write out the names as thats all thats needed to rebuild etc.
+		# For font debugging of consecutive formats the ids are also written.
+		# The ids are not read when moving from the XML format.
+		glyphIds = map(ttFont.getGlyphID, self.names)
+		for glyphName, glyphId in itertools.izip(self.names, glyphIds):
+			writer.simpletag('glyphLoc', name=glyphName, id=glyphId)
+			writer.newline()
+		writer.endtag(self.__class__.__name__)
+		writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		# Read all the attributes. Even though the glyph indices are
+		# recalculated, they are still read in case there needs to
+		# be an immediate export of the data.
+		self.imageFormat = safeEval(attrs['imageFormat'])
+		self.firstGlyphIndex = safeEval(attrs['firstGlyphIndex'])
+		self.lastGlyphIndex = safeEval(attrs['lastGlyphIndex'])
+
+		self.readMetrics((name, attrs, content), ttFont)
+
+		self.names = []
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attrs, content = element
+			if name == 'glyphLoc':
+				self.names.append(attrs['name'])
+
+	# A helper method that writes the metrics for the index sub table. It also
+	# is responsible for writing the image size for fixed size data since fixed
+	# size is not recalculated on compile. Default behavior is to do nothing.
+	def writeMetrics(self, writer, ttFont):
+		pass
+
+	# A helper method that is the inverse of writeMetrics.
+	def readMetrics(self, (name, attrs, content), ttFont):
+		pass
+
+	# This method is for fixed glyph data sizes. There are formats where
+	# the glyph data is fixed but are actually composite glyphs. To handle
+	# this the font spec in indexSubTable makes the data the size of the
+	# fixed size by padding the component arrays. This function abstracts
+	# out this padding process. Input is data unpadded. Output is data
+	# padded only in fixed formats. Default behavior is to return the data.
+	def padBitmapData(self, data):
+		return data
+
+	# Remove any of the glyph locations and names that are flagged as skipped.
+	# This only occurs in formats {1,3}.
+	def removeSkipGlyphs(self):
+		# Determines if a name, location pair is a valid data location.
+		# Skip glyphs are marked when the size is equal to zero.
+		def isValidLocation((name, (startByte, endByte))):
+			return startByte < endByte
+		# Remove all skip glyphs.
+		dataPairs = filter(isValidLocation, zip(self.names, self.locations))
+		self.names, self.locations = map(list, zip(*dataPairs))
+
+# A closure for creating a custom mixin. This is done because formats 1 and 3
+# are very similar. The only difference between them is the size per offset
+# value. Code put in here should handle both cases generally.
+def _createOffsetArrayIndexSubTableMixin(formatStringForDataType):
+
+	# Prep the data size for the offset array data format.
+	dataFormat = '>'+formatStringForDataType
+	offsetDataSize = struct.calcsize(dataFormat)
+
+	class OffsetArrayIndexSubTableMixin:
+
+		def decompile(self):
+
+			numGlyphs = self.lastGlyphIndex - self.firstGlyphIndex + 1
+			indexingOffsets = [glyphIndex * offsetDataSize for glyphIndex in xrange(numGlyphs+2)]
+			indexingLocations = zip(indexingOffsets, indexingOffsets[1:])
+			offsetArray = [struct.unpack(dataFormat, self.data[slice(*loc)])[0] for loc in indexingLocations]
+
+			glyphIds = range(self.firstGlyphIndex, self.lastGlyphIndex+1)
+			modifiedOffsets = [offset + self.imageDataOffset for offset in offsetArray]
+			self.locations = zip(modifiedOffsets, modifiedOffsets[1:])
+
+			self.names = map(self.ttFont.getGlyphName, glyphIds)
+			self.removeSkipGlyphs()
+
+		def compile(self, ttFont):
+			# First make sure that all the data lines up properly. Formats 1 and 3
+			# must have all its data lined up consecutively. If not this will fail.
+			for curLoc, nxtLoc in itertools.izip(self.locations, self.locations[1:]):
+				assert curLoc[1] == nxtLoc[0], "Data must be consecutive in indexSubTable offset formats"
+
+			glyphIds = map(ttFont.getGlyphID, self.names)
+			# Make sure that all ids are sorted strictly increasing.
+			assert all(glyphIds[i] < glyphIds[i+1] for i in xrange(len(glyphIds)-1))
+
+			# Run a simple algorithm to add skip glyphs to the data locations at
+			# the places where an id is not present.
+			idQueue = deque(glyphIds)
+			locQueue = deque(self.locations)
+			allGlyphIds = range(self.firstGlyphIndex, self.lastGlyphIndex+1)
+			allLocations = []
+			for curId in allGlyphIds:
+				if curId != idQueue[0]:
+					allLocations.append((locQueue[0][0], locQueue[0][0]))
+				else:
+					idQueue.popleft()
+					allLocations.append(locQueue.popleft())
+
+			# Now that all the locations are collected, pack them appropriately into
+			# offsets. This is the form where offset[i] is the location and
+			# offset[i+1]-offset[i] is the size of the data location.
+			offsets = list(allLocations[0]) + [loc[1] for loc in allLocations[1:]]
+			# Image data offset must be less than or equal to the minimum of locations.
+			# This offset may change the value for round tripping but is safer and
+			# allows imageDataOffset to not be required to be in the XML version.
+			self.imageDataOffset = min(offsets)
+			offsetArray = [offset - self.imageDataOffset for offset in offsets]
+
+			dataList = [EblcIndexSubTable.compile(self, ttFont)]
+			dataList += [struct.pack(dataFormat, offsetValue) for offsetValue in offsetArray]
+			# Take care of any padding issues. Only occurs in format 3.
+			if offsetDataSize * len(dataList) % 4 != 0:
+				dataList.append(struct.pack(dataFormat, 0))
+			return string.join(dataList, "")
+
+	return OffsetArrayIndexSubTableMixin
+
+# A Mixin for functionality shared between the different kinds
+# of fixed sized data handling. Both kinds have big metrics so
+# that kind of special processing is also handled in this mixin.
+class FixedSizeIndexSubTableMixin:
+
+	def writeMetrics(self, writer, ttFont):
+		writer.simpletag('imageSize', value=self.imageSize)
+		writer.newline()
+		self.metrics.toXML(writer, ttFont)
+
+	def readMetrics(self, (name, attrs, content), ttFont):
+		for element in content:
+			if type(element) != TupleType:
+				continue
+			name, attrs, content = element
+			if name == 'imageSize':
+				self.imageSize = safeEval(attrs['value'])
+			elif name == BigGlyphMetrics.__name__:
+				self.metrics = BigGlyphMetrics()
+				self.metrics.fromXML(element, ttFont)
+			elif name == SmallGlyphMetrics.__name__:
+				print "Warning: SmallGlyphMetrics being ignored in format %d." % self.indexFormat
+
+	def padBitmapData(self, data):
+		# Make sure that the data isn't bigger than the fixed size.
+		assert len(data) <= self.imageSize, "Data in indexSubTable format %d must be less than the fixed size." % self.indexFormat
+		# Pad the data so that it matches the fixed size.
+		pad = (self.imageSize - len(data)) * '\0'
+		return data + pad
+
+class eblc_index_sub_table_1(_createOffsetArrayIndexSubTableMixin('L'), EblcIndexSubTable):
+	pass
+
+class eblc_index_sub_table_2(FixedSizeIndexSubTableMixin, EblcIndexSubTable):
+
+	def decompile(self):
+		(self.imageSize,) = struct.unpack(">L", self.data[:4])
+		self.metrics = BigGlyphMetrics()
+		sstruct.unpack2(bigGlyphMetricsFormat, self.data[4:], self.metrics)
+		glyphIds = range(self.firstGlyphIndex, self.lastGlyphIndex+1)
+		offsets = [self.imageSize * i + self.imageDataOffset for i in xrange(len(glyphIds)+1)]
+		self.locations = zip(offsets, offsets[1:])
+		self.names = map(self.ttFont.getGlyphName, glyphIds)
+
+	def compile(self, ttFont):
+		glyphIds = map(ttFont.getGlyphID, self.names)
+		# Make sure all the ids are consecutive. This is required by Format 2.
+		assert glyphIds == range(self.firstGlyphIndex, self.lastGlyphIndex+1), "Format 2 ids must be consecutive."
+		self.imageDataOffset = min(zip(*self.locations)[0])
+
+		dataList = [EblcIndexSubTable.compile(self, ttFont)]
+		dataList.append(struct.pack(">L", self.imageSize))
+		dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
+		return string.join(dataList, "")
+
+class eblc_index_sub_table_3(_createOffsetArrayIndexSubTableMixin('H'), EblcIndexSubTable):
+	pass
+
+class eblc_index_sub_table_4(EblcIndexSubTable):
+
+	def decompile(self):
+
+		(numGlyphs,) = struct.unpack(">L", self.data[:4])
+		data = self.data[4:]
+		indexingOffsets = [glyphIndex * codeOffsetPairSize for glyphIndex in xrange(numGlyphs+2)]
+		indexingLocations = zip(indexingOffsets, indexingOffsets[1:])
+		glyphArray = [struct.unpack(codeOffsetPairFormat, data[slice(*loc)]) for loc in indexingLocations]
+		glyphIds, offsets = map(list, zip(*glyphArray))
+		# There are one too many glyph ids. Get rid of the last one.
+		glyphIds.pop()
+
+		offsets = [offset + self.imageDataOffset for offset in offsets]
+		self.locations = zip(offsets, offsets[1:])
+		self.names = map(self.ttFont.getGlyphName, glyphIds)
+
+	def compile(self, ttFont):
+		# First make sure that all the data lines up properly. Format 4
+		# must have all its data lined up consecutively. If not this will fail.
+		for curLoc, nxtLoc in itertools.izip(self.locations, self.locations[1:]):
+			assert curLoc[1] == nxtLoc[0], "Data must be consecutive in indexSubTable format 4"
+
+		offsets = list(self.locations[0]) + [loc[1] for loc in self.locations[1:]]
+		# Image data offset must be less than or equal to the minimum of locations.
+		# Resetting this offset may change the value for round tripping but is safer
+		# and allows imageDataOffset to not be required to be in the XML version.
+		self.imageDataOffset = min(offsets)
+		offsets = [offset - self.imageDataOffset for offset in offsets]
+		glyphIds = map(ttFont.getGlyphID, self.names)
+		# Create an iterator over the ids plus a padding value.
+		idsPlusPad = list(itertools.chain(glyphIds, [0]))
+
+		dataList = [EblcIndexSubTable.compile(self, ttFont)]
+		dataList.append(struct.pack(">L", len(glyphIds)))
+		tmp = [struct.pack(codeOffsetPairFormat, *cop) for cop in itertools.izip(idsPlusPad, offsets)]
+		dataList += tmp
+		data = string.join(dataList, "")
+		return data
+
+class eblc_index_sub_table_5(FixedSizeIndexSubTableMixin, EblcIndexSubTable):
+
+	def decompile(self):
+		self.origDataLen = 0
+		(self.imageSize,) = struct.unpack(">L", self.data[:4])
+		data = self.data[4:]
+		self.metrics, data = sstruct.unpack2(bigGlyphMetricsFormat, data, BigGlyphMetrics())
+		(numGlyphs,) = struct.unpack(">L", data[:4])
+		data = data[4:]
+		glyphIds = [struct.unpack(">H", data[2*i:2*(i+1)])[0] for i in xrange(numGlyphs)]
+
+		offsets = [self.imageSize * i + self.imageDataOffset for i in xrange(len(glyphIds)+1)]
+		self.locations = zip(offsets, offsets[1:])
+		self.names = map(self.ttFont.getGlyphName, glyphIds)
+
+	def compile(self, ttFont):
+		self.imageDataOffset = min(zip(*self.locations)[0])
+		dataList = [EblcIndexSubTable.compile(self, ttFont)]
+		dataList.append(struct.pack(">L", self.imageSize))
+		dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
+		glyphIds = map(ttFont.getGlyphID, self.names)
+		dataList.append(struct.pack(">L", len(glyphIds)))
+		dataList += [struct.pack(">H", curId) for curId in glyphIds]
+		if len(glyphIds) % 2 == 1:
+			dataList.append(struct.pack(">H", 0))
+		return string.join(dataList, "")
+
+# Dictionary of indexFormat to the class representing that format.
+eblc_sub_table_classes = {
+		1: eblc_index_sub_table_1,
+		2: eblc_index_sub_table_2,
+		3: eblc_index_sub_table_3,
+		4: eblc_index_sub_table_4,
+		5: eblc_index_sub_table_5,
+	}
diff --git a/Lib/fontTools/ttLib/tables/__init__.py b/Lib/fontTools/ttLib/tables/__init__.py
index 84cbf04..76f363e 100644
--- a/Lib/fontTools/ttLib/tables/__init__.py
+++ b/Lib/fontTools/ttLib/tables/__init__.py
@@ -6,6 +6,8 @@
 	import B_A_S_E_
 	import C_F_F_
 	import D_S_I_G_
+	import E_B_D_T_
+	import E_B_L_C_
 	import G_D_E_F_
 	import G_M_A_P_
 	import G_P_K_G_
