from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from . import DefaultTable
from fontTools.misc.textTools import safeEval
from .BitmapGlyphMetrics import BigGlyphMetrics, bigGlyphMetricsFormat, SmallGlyphMetrics, smallGlyphMetricsFormat
import struct
import itertools
from collections import deque
import logging


log = logging.getLogger(__name__)

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
		i = 0;

		dummy = sstruct.unpack(eblcHeaderFormat, data[:8], self)
		i += 8;

		self.strikes = []
		for curStrikeIndex in range(self.numSizes):
			curStrike = Strike()
			self.strikes.append(curStrike)
			curTable = curStrike.bitmapSizeTable
			dummy = sstruct.unpack2(bitmapSizeTableFormatPart1, data[i:i+16], curTable)
			i += 16
			for metric in ('hori', 'vert'):
				metricObj = SbitLineMetrics()
				vars(curTable)[metric] = metricObj
				dummy = sstruct.unpack2(sbitLineMetricsFormat, data[i:i+12], metricObj)
				i += 12
			dummy = sstruct.unpack(bitmapSizeTableFormatPart2, data[i:i+8], curTable)
			i += 8

		for curStrike in self.strikes:
			curTable = curStrike.bitmapSizeTable
			for subtableIndex in range(curTable.numberOfIndexSubTables):
				i = curTable.indexSubTableArrayOffset + subtableIndex * indexSubTableArraySize

				tup = struct.unpack(indexSubTableArrayFormat, data[i:i+indexSubTableArraySize])
				(firstGlyphIndex, lastGlyphIndex, additionalOffsetToIndexSubtable) = tup
				i = curTable.indexSubTableArrayOffset + additionalOffsetToIndexSubtable

				tup = struct.unpack(indexSubHeaderFormat, data[i:i+indexSubHeaderSize])
				(indexFormat, imageFormat, imageDataOffset) = tup

				indexFormatClass = self.getIndexFormatClass(indexFormat)
				indexSubTable = indexFormatClass(data[i+indexSubHeaderSize:], ttFont)
				indexSubTable.firstGlyphIndex = firstGlyphIndex
				indexSubTable.lastGlyphIndex = lastGlyphIndex
				indexSubTable.additionalOffsetToIndexSubtable = additionalOffsetToIndexSubtable
				indexSubTable.indexFormat = indexFormat
				indexSubTable.imageFormat = imageFormat
				indexSubTable.imageDataOffset = imageDataOffset
				indexSubTable.decompile() # https://github.com/fonttools/fonttools/issues/317
				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 = list(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 bytesjoin(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] is None, "Duplicate strike EBLC indices."
			self.strikes[strikeIndex] = curStrike

class Strike(object):

	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 not isinstance(element, tuple):
				continue
			name, attrs, content = element
			if name == 'bitmapSizeTable':
				self.bitmapSizeTable.fromXML(name, attrs, content, ttFont)
			elif name.startswith(_indexSubTableSubclassPrefix):
				indexFormat = safeEval(name[len(_indexSubTableSubclassPrefix):])
				indexFormatClass = locator.getIndexFormatClass(indexFormat)
				indexSubTable = indexFormatClass(None, None)
				indexSubTable.indexFormat = indexFormat
				indexSubTable.fromXML(name, attrs, content, ttFont)
				self.indexSubTables.append(indexSubTable)


class BitmapSizeTable(object):

	# 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 not isinstance(element, tuple):
				continue
			name, attrs, content = element
			if name == 'sbitLineMetrics':
				direction = attrs['direction']
				assert direction in ('hori', 'vert'), "SbitLineMetrics direction specified invalid."
				metricObj = SbitLineMetrics()
				metricObj.fromXML(name, attrs, content, ttFont)
				vars(self)[direction] = metricObj
			elif name in dataNames:
				vars(self)[name] = safeEval(attrs['value'])
			else:
				log.warning("unknown name '%s' being ignored in BitmapSizeTable.", name)


class SbitLineMetrics(object):

	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 not isinstance(element, tuple):
				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(object):

	def __init__(self, data, ttFont):
		self.data = data
		self.ttFont = ttFont
		# TODO Currently non-lazy decompiling doesn't work for this class...
		#if not ttFont.lazy:
		#	self.decompile()
		#	del self.data, self.ttFont

	def __getattr__(self, attr):
		# Allow lazy decompile.
		if attr[:2] == '__':
			raise AttributeError(attr)
		if not hasattr(self, "data"):
			raise AttributeError(attr)
		self.decompile()
		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 zip(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 not isinstance(element, tuple):
				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(args):
			(name, (startByte, endByte)) = args
			return startByte < endByte
		# Remove all skip glyphs.
		dataPairs = list(filter(isValidLocation, zip(self.names, self.locations)))
		self.names, self.locations = list(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(object):

		def decompile(self):

			numGlyphs = self.lastGlyphIndex - self.firstGlyphIndex + 1
			indexingOffsets = [glyphIndex * offsetDataSize for glyphIndex in range(numGlyphs+2)]
			indexingLocations = zip(indexingOffsets, indexingOffsets[1:])
			offsetArray = [struct.unpack(dataFormat, self.data[slice(*loc)])[0] for loc in indexingLocations]

			glyphIds = list(range(self.firstGlyphIndex, self.lastGlyphIndex+1))
			modifiedOffsets = [offset + self.imageDataOffset for offset in offsetArray]
			self.locations = list(zip(modifiedOffsets, modifiedOffsets[1:]))

			self.names = list(map(self.ttFont.getGlyphName, glyphIds))
			self.removeSkipGlyphs()
			del self.data, self.ttFont

		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 zip(self.locations, self.locations[1:]):
				assert curLoc[1] == nxtLoc[0], "Data must be consecutive in indexSubTable offset formats"

			glyphIds = list(map(ttFont.getGlyphID, self.names))
			# Make sure that all ids are sorted strictly increasing.
			assert all(glyphIds[i] < glyphIds[i+1] for i in range(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 = list(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 bytesjoin(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(object):

	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 not isinstance(element, tuple):
				continue
			name, attrs, content = element
			if name == 'imageSize':
				self.imageSize = safeEval(attrs['value'])
			elif name == BigGlyphMetrics.__name__:
				self.metrics = BigGlyphMetrics()
				self.metrics.fromXML(name, attrs, content, ttFont)
			elif name == SmallGlyphMetrics.__name__:
				log.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)) * b'\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 = list(range(self.firstGlyphIndex, self.lastGlyphIndex+1))
		offsets = [self.imageSize * i + self.imageDataOffset for i in range(len(glyphIds)+1)]
		self.locations = list(zip(offsets, offsets[1:]))
		self.names = list(map(self.ttFont.getGlyphName, glyphIds))
		del self.data, self.ttFont

	def compile(self, ttFont):
		glyphIds = list(map(ttFont.getGlyphID, self.names))
		# Make sure all the ids are consecutive. This is required by Format 2.
		assert glyphIds == list(range(self.firstGlyphIndex, self.lastGlyphIndex+1)), "Format 2 ids must be consecutive."
		self.imageDataOffset = min(next(iter(zip(*self.locations))))

		dataList = [EblcIndexSubTable.compile(self, ttFont)]
		dataList.append(struct.pack(">L", self.imageSize))
		dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
		return bytesjoin(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 range(numGlyphs+2)]
		indexingLocations = zip(indexingOffsets, indexingOffsets[1:])
		glyphArray = [struct.unpack(codeOffsetPairFormat, data[slice(*loc)]) for loc in indexingLocations]
		glyphIds, offsets = list(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 = list(zip(offsets, offsets[1:]))
		self.names = list(map(self.ttFont.getGlyphName, glyphIds))
		del self.data, self.ttFont

	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 zip(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 = list(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 zip(idsPlusPad, offsets)]
		dataList += tmp
		data = bytesjoin(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 range(numGlyphs)]

		offsets = [self.imageSize * i + self.imageDataOffset for i in range(len(glyphIds)+1)]
		self.locations = list(zip(offsets, offsets[1:]))
		self.names = list(map(self.ttFont.getGlyphName, glyphIds))
		del self.data, self.ttFont

	def compile(self, ttFont):
		self.imageDataOffset = min(next(iter(zip(*self.locations))))
		dataList = [EblcIndexSubTable.compile(self, ttFont)]
		dataList.append(struct.pack(">L", self.imageSize))
		dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics))
		glyphIds = list(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 bytesjoin(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,
	}
