from fontTools.misc.py23 import bytesjoin, tobytes, tostr
from fontTools.misc.fixedTools import (
	fixedToFloat as fi2fl,
	floatToFixed as fl2fi,
	floatToFixedToStr as fl2str,
	strToFixedToFloat as str2fl,
	ensureVersionIsLong as fi2ve,
	versionToFixed as ve2fi,
)
from fontTools.misc.roundTools import nearestMultipleShortestRepr, otRound
from fontTools.misc.textTools import pad, safeEval
from fontTools.ttLib import getSearchRange
from .otBase import (CountReference, FormatSwitchingBaseTable,
                     OTTableReader, OTTableWriter, ValueRecordFactory)
from .otTables import (lookupTypes, AATStateTable, AATState, AATAction,
                       ContextualMorphAction, LigatureMorphAction,
                       InsertionMorphAction, MorxSubtable,
                       ExtendMode as _ExtendMode,
                       CompositeMode as _CompositeMode)
from itertools import zip_longest
from functools import partial
import struct
import logging


log = logging.getLogger(__name__)
istuple = lambda t: isinstance(t, tuple)


def buildConverters(tableSpec, tableNamespace):
	"""Given a table spec from otData.py, build a converter object for each
	field of the table. This is called for each table in otData.py, and
	the results are assigned to the corresponding class in otTables.py."""
	converters = []
	convertersByName = {}
	for tp, name, repeat, aux, descr in tableSpec:
		tableName = name
		if name.startswith("ValueFormat"):
			assert tp == "uint16"
			converterClass = ValueFormat
		elif name.endswith("Count") or name in ("StructLength", "MorphType"):
			converterClass = {
				"uint8": ComputedUInt8,
				"uint16": ComputedUShort,
				"uint32": ComputedULong,
			}[tp]
		elif name == "SubTable":
			converterClass = SubTable
		elif name == "ExtSubTable":
			converterClass = ExtSubTable
		elif name == "SubStruct":
			converterClass = SubStruct
		elif name == "FeatureParams":
			converterClass = FeatureParams
		elif name in ("CIDGlyphMapping", "GlyphCIDMapping"):
			converterClass = StructWithLength
		else:
			if not tp in converterMapping and '(' not in tp:
				tableName = tp
				converterClass = Struct
			else:
				converterClass = eval(tp, tableNamespace, converterMapping)

		conv = converterClass(name, repeat, aux)

		if conv.tableClass:
			# A "template" such as OffsetTo(AType) knowss the table class already
			tableClass = conv.tableClass
		elif tp in ('MortChain', 'MortSubtable', 'MorxChain'):
			tableClass = tableNamespace.get(tp)
		else:
			tableClass = tableNamespace.get(tableName)

		if not conv.tableClass:
			conv.tableClass = tableClass

		if name in ["SubTable", "ExtSubTable", "SubStruct"]:
			conv.lookupTypes = tableNamespace['lookupTypes']
			# also create reverse mapping
			for t in conv.lookupTypes.values():
				for cls in t.values():
					convertersByName[cls.__name__] = Table(name, repeat, aux, cls)
		if name == "FeatureParams":
			conv.featureParamTypes = tableNamespace['featureParamTypes']
			conv.defaultFeatureParams = tableNamespace['FeatureParams']
			for cls in conv.featureParamTypes.values():
				convertersByName[cls.__name__] = Table(name, repeat, aux, cls)
		converters.append(conv)
		assert name not in convertersByName, name
		convertersByName[name] = conv
	return converters, convertersByName


class _MissingItem(tuple):
	__slots__ = ()


try:
	from collections import UserList
except ImportError:
	from UserList import UserList


class _LazyList(UserList):

	def __getslice__(self, i, j):
		return self.__getitem__(slice(i, j))

	def __getitem__(self, k):
		if isinstance(k, slice):
			indices = range(*k.indices(len(self)))
			return [self[i] for i in indices]
		item = self.data[k]
		if isinstance(item, _MissingItem):
			self.reader.seek(self.pos + item[0] * self.recordSize)
			item = self.conv.read(self.reader, self.font, {})
			self.data[k] = item
		return item

	def __add__(self, other):
		if isinstance(other, _LazyList):
			other = list(other)
		elif isinstance(other, list):
			pass
		else:
			return NotImplemented
		return list(self) + other

	def __radd__(self, other):
		if not isinstance(other, list):
			return NotImplemented
		return other + list(self)


class BaseConverter(object):

	"""Base class for converter objects. Apart from the constructor, this
	is an abstract class."""

	def __init__(self, name, repeat, aux, tableClass=None):
		self.name = name
		self.repeat = repeat
		self.aux = aux
		self.tableClass = tableClass
		self.isCount = name.endswith("Count") or name in ['DesignAxisRecordSize', 'ValueRecordSize']
		self.isLookupType = name.endswith("LookupType") or name == "MorphType"
		self.isPropagated = name in [
			"ClassCount",
			"Class2Count",
			"FeatureTag",
			"SettingsCount",
			"VarRegionCount",
			"MappingCount",
			"RegionAxisCount",
			"DesignAxisCount",
			"DesignAxisRecordSize",
			"AxisValueCount",
			"ValueRecordSize",
			"AxisCount",
			"BaseGlyphRecordCount",
			"LayerRecordCount",
		]

	def readArray(self, reader, font, tableDict, count):
		"""Read an array of values from the reader."""
		lazy = font.lazy and count > 8
		if lazy:
			recordSize = self.getRecordSize(reader)
			if recordSize is NotImplemented:
				lazy = False
		if not lazy:
			l = []
			for i in range(count):
				l.append(self.read(reader, font, tableDict))
			return l
		else:
			l = _LazyList()
			l.reader = reader.copy()
			l.pos = l.reader.pos
			l.font = font
			l.conv = self
			l.recordSize = recordSize
			l.extend(_MissingItem([i]) for i in range(count))
			reader.advance(count * recordSize)
			return l

	def getRecordSize(self, reader):
		if hasattr(self, 'staticSize'): return self.staticSize
		return NotImplemented

	def read(self, reader, font, tableDict):
		"""Read a value from the reader."""
		raise NotImplementedError(self)

	def writeArray(self, writer, font, tableDict, values):
		try:
			for i, value in enumerate(values):
				self.write(writer, font, tableDict, value, i)
		except Exception as e:
			e.args = e.args + (i,)
			raise

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		"""Write a value to the writer."""
		raise NotImplementedError(self)

	def xmlRead(self, attrs, content, font):
		"""Read a value from XML."""
		raise NotImplementedError(self)

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		"""Write a value to XML."""
		raise NotImplementedError(self)


class SimpleValue(BaseConverter):
	@staticmethod
	def toString(value):
		return value
	@staticmethod
	def fromString(value):
		return value
	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.simpletag(name, attrs + [("value", self.toString(value))])
		xmlWriter.newline()
	def xmlRead(self, attrs, content, font):
		return self.fromString(attrs["value"])

class OptionalValue(SimpleValue):
	DEFAULT = None
	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		if value != self.DEFAULT:
			attrs.append(("value", self.toString(value)))
		xmlWriter.simpletag(name, attrs)
		xmlWriter.newline()
	def xmlRead(self, attrs, content, font):
		if "value" in attrs:
			return self.fromString(attrs["value"])
		return self.DEFAULT

class IntValue(SimpleValue):
	@staticmethod
	def fromString(value):
		return int(value, 0)

class Long(IntValue):
	staticSize = 4
	def read(self, reader, font, tableDict):
		return reader.readLong()
	def readArray(self, reader, font, tableDict, count):
		return reader.readLongArray(count)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeLong(value)
	def writeArray(self, writer, font, tableDict, values):
		writer.writeLongArray(values)

class ULong(IntValue):
	staticSize = 4
	def read(self, reader, font, tableDict):
		return reader.readULong()
	def readArray(self, reader, font, tableDict, count):
		return reader.readULongArray(count)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeULong(value)
	def writeArray(self, writer, font, tableDict, values):
		writer.writeULongArray(values)

class Flags32(ULong):
	@staticmethod
	def toString(value):
		return "0x%08X" % value

class VarIndex(OptionalValue, ULong):
	DEFAULT = 0xFFFFFFFF

class Short(IntValue):
	staticSize = 2
	def read(self, reader, font, tableDict):
		return reader.readShort()
	def readArray(self, reader, font, tableDict, count):
		return reader.readShortArray(count)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeShort(value)
	def writeArray(self, writer, font, tableDict, values):
		writer.writeShortArray(values)

class UShort(IntValue):
	staticSize = 2
	def read(self, reader, font, tableDict):
		return reader.readUShort()
	def readArray(self, reader, font, tableDict, count):
		return reader.readUShortArray(count)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeUShort(value)
	def writeArray(self, writer, font, tableDict, values):
		writer.writeUShortArray(values)

class Int8(IntValue):
	staticSize = 1
	def read(self, reader, font, tableDict):
		return reader.readInt8()
	def readArray(self, reader, font, tableDict, count):
		return reader.readInt8Array(count)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeInt8(value)
	def writeArray(self, writer, font, tableDict, values):
		writer.writeInt8Array(values)

class UInt8(IntValue):
	staticSize = 1
	def read(self, reader, font, tableDict):
		return reader.readUInt8()
	def readArray(self, reader, font, tableDict, count):
		return reader.readUInt8Array(count)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeUInt8(value)
	def writeArray(self, writer, font, tableDict, values):
		writer.writeUInt8Array(values)

class UInt24(IntValue):
	staticSize = 3
	def read(self, reader, font, tableDict):
		return reader.readUInt24()
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeUInt24(value)

class ComputedInt(IntValue):
	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		if value is not None:
			xmlWriter.comment("%s=%s" % (name, value))
			xmlWriter.newline()

class ComputedUInt8(ComputedInt, UInt8):
	pass
class ComputedUShort(ComputedInt, UShort):
	pass
class ComputedULong(ComputedInt, ULong):
	pass

class Tag(SimpleValue):
	staticSize = 4
	def read(self, reader, font, tableDict):
		return reader.readTag()
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeTag(value)

class GlyphID(SimpleValue):
	staticSize = 2
	typecode = "H"
	def readArray(self, reader, font, tableDict, count):
		glyphOrder = font.getGlyphOrder()
		gids = reader.readArray(self.typecode, self.staticSize, count)
		try:
			l = [glyphOrder[gid] for gid in gids]
		except IndexError:
			# Slower, but will not throw an IndexError on an invalid glyph id.
			l = [font.getGlyphName(gid) for gid in gids]
		return l
	def read(self, reader, font, tableDict):
		return font.getGlyphName(reader.readValue(self.typecode, self.staticSize))
	def writeArray(self, writer, font, tableDict, values):
		glyphMap = font.getReverseGlyphMap()
		try:
			values = [glyphMap[glyphname] for glyphname in values]
		except KeyError:
			# Slower, but will not throw a KeyError on an out-of-range glyph name.
			values = [font.getGlyphID(glyphname) for glyphname in values]
		writer.writeArray(self.typecode, values)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeValue(self.typecode, font.getGlyphID(value))


class GlyphID32(GlyphID):
	staticSize = 4
	typecode = "L"


class NameID(UShort):
	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.simpletag(name, attrs + [("value", value)])
		if font and value:
			nameTable = font.get("name")
			if nameTable:
				name = nameTable.getDebugName(value)
				xmlWriter.write("  ")
				if name:
					xmlWriter.comment(name)
				else:
					xmlWriter.comment("missing from name table")
					log.warning("name id %d missing from name table" % value)
		xmlWriter.newline()

class STATFlags(UShort):
	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.simpletag(name, attrs + [("value", value)])
		flags = []
		if value & 0x01:
			flags.append("OlderSiblingFontAttribute")
		if value & 0x02:
			flags.append("ElidableAxisValueName")
		if flags:
			xmlWriter.write("  ")
			xmlWriter.comment(" ".join(flags))
		xmlWriter.newline()

class FloatValue(SimpleValue):
	@staticmethod
	def fromString(value):
		return float(value)

class DeciPoints(FloatValue):
	staticSize = 2
	def read(self, reader, font, tableDict):
		return reader.readUShort() / 10

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeUShort(round(value * 10))

class Fixed(FloatValue):
	staticSize = 4
	def read(self, reader, font, tableDict):
		return  fi2fl(reader.readLong(), 16)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeLong(fl2fi(value, 16))
	@staticmethod
	def fromString(value):
		return str2fl(value, 16)
	@staticmethod
	def toString(value):
		return fl2str(value, 16)

class F2Dot14(FloatValue):
	staticSize = 2
	def read(self, reader, font, tableDict):
		return  fi2fl(reader.readShort(), 14)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.writeShort(fl2fi(value, 14))
	@staticmethod
	def fromString(value):
		return str2fl(value, 14)
	@staticmethod
	def toString(value):
		return fl2str(value, 14)

class Angle(F2Dot14):
	# angles are specified in degrees, and encoded as F2Dot14 fractions of half
	# circle: e.g. 1.0 => 180, -0.5 => -90, -2.0 => -360, etc.
	factor = 1.0/(1<<14) * 180  # 0.010986328125
	def read(self, reader, font, tableDict):
		return super().read(reader, font, tableDict) * 180
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		super().write(writer, font, tableDict, value / 180, repeatIndex=repeatIndex)
	@classmethod
	def fromString(cls, value):
		# quantize to nearest multiples of minimum fixed-precision angle
		return otRound(float(value) / cls.factor) * cls.factor
	@classmethod
	def toString(cls, value):
		return nearestMultipleShortestRepr(value, cls.factor)

class Version(SimpleValue):
	staticSize = 4
	def read(self, reader, font, tableDict):
		value = reader.readLong()
		assert (value >> 16) == 1, "Unsupported version 0x%08x" % value
		return value
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		value = fi2ve(value)
		assert (value >> 16) == 1, "Unsupported version 0x%08x" % value
		writer.writeLong(value)
	@staticmethod
	def fromString(value):
		return ve2fi(value)
	@staticmethod
	def toString(value):
		return "0x%08x" % value
	@staticmethod
	def fromFloat(v):
		return fl2fi(v, 16)


class Char64(SimpleValue):
	"""An ASCII string with up to 64 characters.

	Unused character positions are filled with 0x00 bytes.
	Used in Apple AAT fonts in the `gcid` table.
	"""
	staticSize = 64

	def read(self, reader, font, tableDict):
		data = reader.readData(self.staticSize)
		zeroPos = data.find(b"\0")
		if zeroPos >= 0:
			data = data[:zeroPos]
		s = tostr(data, encoding="ascii", errors="replace")
		if s != tostr(data, encoding="ascii", errors="ignore"):
			log.warning('replaced non-ASCII characters in "%s"' %
			            s)
		return s

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		data = tobytes(value, encoding="ascii", errors="replace")
		if data != tobytes(value, encoding="ascii", errors="ignore"):
			log.warning('replacing non-ASCII characters in "%s"' %
			            value)
		if len(data) > self.staticSize:
			log.warning('truncating overlong "%s" to %d bytes' %
			            (value, self.staticSize))
		data = (data + b"\0" * self.staticSize)[:self.staticSize]
		writer.writeData(data)


class Struct(BaseConverter):

	def getRecordSize(self, reader):
		return self.tableClass and self.tableClass.getRecordSize(reader)

	def read(self, reader, font, tableDict):
		table = self.tableClass()
		table.decompile(reader, font)
		return table

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		value.compile(writer, font)

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		if value is None:
			if attrs:
				# If there are attributes (probably index), then
				# don't drop this even if it's NULL.  It will mess
				# up the array indices of the containing element.
				xmlWriter.simpletag(name, attrs + [("empty", 1)])
				xmlWriter.newline()
			else:
				pass # NULL table, ignore
		else:
			value.toXML(xmlWriter, font, attrs, name=name)

	def xmlRead(self, attrs, content, font):
		if "empty" in attrs and safeEval(attrs["empty"]):
			return None
		table = self.tableClass()
		Format = attrs.get("Format")
		if Format is not None:
			table.Format = int(Format)

		noPostRead = not hasattr(table, 'postRead')
		if noPostRead:
			# TODO Cache table.hasPropagated.
			cleanPropagation = False
			for conv in table.getConverters():
				if conv.isPropagated:
					cleanPropagation = True
					if not hasattr(font, '_propagator'):
						font._propagator = {}
					propagator = font._propagator
					assert conv.name not in propagator, (conv.name, propagator)
					setattr(table, conv.name, None)
					propagator[conv.name] = CountReference(table.__dict__, conv.name)

		for element in content:
			if isinstance(element, tuple):
				name, attrs, content = element
				table.fromXML(name, attrs, content, font)
			else:
				pass

		table.populateDefaults(propagator=getattr(font, '_propagator', None))

		if noPostRead:
			if cleanPropagation:
				for conv in table.getConverters():
					if conv.isPropagated:
						propagator = font._propagator
						del propagator[conv.name]
						if not propagator:
							del font._propagator

		return table

	def __repr__(self):
		return "Struct of " + repr(self.tableClass)


class StructWithLength(Struct):
	def read(self, reader, font, tableDict):
		pos = reader.pos
		table = self.tableClass()
		table.decompile(reader, font)
		reader.seek(pos + table.StructLength)
		return table

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		for convIndex, conv in enumerate(value.getConverters()):
			if conv.name == "StructLength":
				break
		lengthIndex = len(writer.items) + convIndex
		if isinstance(value, FormatSwitchingBaseTable):
			lengthIndex += 1  # implicit Format field
		deadbeef = {1:0xDE, 2:0xDEAD, 4:0xDEADBEEF}[conv.staticSize]

		before = writer.getDataLength()
		value.StructLength = deadbeef
		value.compile(writer, font)
		length = writer.getDataLength() - before
		lengthWriter = writer.getSubWriter()
		conv.write(lengthWriter, font, tableDict, length)
		assert(writer.items[lengthIndex] ==
		       b"\xde\xad\xbe\xef"[:conv.staticSize])
		writer.items[lengthIndex] = lengthWriter.getAllData()


class Table(Struct):

	staticSize = 2

	def readOffset(self, reader):
		return reader.readUShort()

	def writeNullOffset(self, writer):
		writer.writeUShort(0)

	def read(self, reader, font, tableDict):
		offset = self.readOffset(reader)
		if offset == 0:
			return None
		table = self.tableClass()
		reader = reader.getSubReader(offset)
		if font.lazy:
			table.reader = reader
			table.font = font
		else:
			table.decompile(reader, font)
		return table

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		if value is None:
			self.writeNullOffset(writer)
		else:
			subWriter = writer.getSubWriter(offsetSize=self.staticSize, name = self.name)
			if repeatIndex is not None:
				subWriter.repeatIndex = repeatIndex
			writer.writeSubTable(subWriter)
			value.compile(subWriter, font)

class LTable(Table):

	staticSize = 4

	def readOffset(self, reader):
		return reader.readULong()

	def writeNullOffset(self, writer):
		writer.writeULong(0)


# Table pointed to by a 24-bit, 3-byte long offset
class Table24(Table):

	staticSize = 3

	def readOffset(self, reader):
		return reader.readUInt24()

	def writeNullOffset(self, writer):
		writer.writeUInt24(0)


# TODO Clean / merge the SubTable and SubStruct

class SubStruct(Struct):
	def getConverter(self, tableType, lookupType):
		tableClass = self.lookupTypes[tableType][lookupType]
		return self.__class__(self.name, self.repeat, self.aux, tableClass)

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		super(SubStruct, self).xmlWrite(xmlWriter, font, value, None, attrs)

class SubTable(Table):
	def getConverter(self, tableType, lookupType):
		tableClass = self.lookupTypes[tableType][lookupType]
		return self.__class__(self.name, self.repeat, self.aux, tableClass)

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		super(SubTable, self).xmlWrite(xmlWriter, font, value, None, attrs)

class ExtSubTable(LTable, SubTable):

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer.Extension = True # actually, mere presence of the field flags it as an Ext Subtable writer.
		Table.write(self, writer, font, tableDict, value, repeatIndex)


class FeatureParams(Table):
	def getConverter(self, featureTag):
		tableClass = self.featureParamTypes.get(featureTag, self.defaultFeatureParams)
		return self.__class__(self.name, self.repeat, self.aux, tableClass)


class ValueFormat(IntValue):
	staticSize = 2
	def __init__(self, name, repeat, aux, tableClass=None):
		BaseConverter.__init__(self, name, repeat, aux, tableClass)
		self.which = "ValueFormat" + ("2" if name[-1] == "2" else "1")
	def read(self, reader, font, tableDict):
		format = reader.readUShort()
		reader[self.which] = ValueRecordFactory(format)
		return format
	def write(self, writer, font, tableDict, format, repeatIndex=None):
		writer.writeUShort(format)
		writer[self.which] = ValueRecordFactory(format)


class ValueRecord(ValueFormat):
	def getRecordSize(self, reader):
		return 2 * len(reader[self.which])
	def read(self, reader, font, tableDict):
		return reader[self.which].readValueRecord(reader, font)
	def write(self, writer, font, tableDict, value, repeatIndex=None):
		writer[self.which].writeValueRecord(writer, font, value)
	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		if value is None:
			pass  # NULL table, ignore
		else:
			value.toXML(xmlWriter, font, self.name, attrs)
	def xmlRead(self, attrs, content, font):
		from .otBase import ValueRecord
		value = ValueRecord()
		value.fromXML(None, attrs, content, font)
		return value


class AATLookup(BaseConverter):
	BIN_SEARCH_HEADER_SIZE = 10

	def __init__(self, name, repeat, aux, tableClass):
		BaseConverter.__init__(self, name, repeat, aux, tableClass)
		if issubclass(self.tableClass, SimpleValue):
			self.converter = self.tableClass(name='Value', repeat=None, aux=None)
		else:
			self.converter = Table(name='Value', repeat=None, aux=None, tableClass=self.tableClass)

	def read(self, reader, font, tableDict):
		format = reader.readUShort()
		if format == 0:
			return self.readFormat0(reader, font)
		elif format == 2:
			return self.readFormat2(reader, font)
		elif format == 4:
			return self.readFormat4(reader, font)
		elif format == 6:
			return self.readFormat6(reader, font)
		elif format == 8:
			return self.readFormat8(reader, font)
		else:
			assert False, "unsupported lookup format: %d" % format

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		values = list(sorted([(font.getGlyphID(glyph), val)
		                      for glyph, val in value.items()]))
		# TODO: Also implement format 4.
		formats = list(sorted(filter(None, [
			self.buildFormat0(writer, font, values),
			self.buildFormat2(writer, font, values),
			self.buildFormat6(writer, font, values),
			self.buildFormat8(writer, font, values),
		])))
		# We use the format ID as secondary sort key to make the output
		# deterministic when multiple formats have same encoded size.
		dataSize, lookupFormat, writeMethod = formats[0]
		pos = writer.getDataLength()
		writeMethod()
		actualSize = writer.getDataLength() - pos
		assert actualSize == dataSize, (
			"AATLookup format %d claimed to write %d bytes, but wrote %d" %
			(lookupFormat, dataSize, actualSize))

	@staticmethod
	def writeBinSearchHeader(writer, numUnits, unitSize):
		writer.writeUShort(unitSize)
		writer.writeUShort(numUnits)
		searchRange, entrySelector, rangeShift = \
			getSearchRange(n=numUnits, itemSize=unitSize)
		writer.writeUShort(searchRange)
		writer.writeUShort(entrySelector)
		writer.writeUShort(rangeShift)

	def buildFormat0(self, writer, font, values):
		numGlyphs = len(font.getGlyphOrder())
		if len(values) != numGlyphs:
			return None
		valueSize = self.converter.staticSize
		return (2 + numGlyphs * valueSize, 0,
			lambda: self.writeFormat0(writer, font, values))

	def writeFormat0(self, writer, font, values):
		writer.writeUShort(0)
		for glyphID_, value in values:
			self.converter.write(
				writer, font, tableDict=None,
				value=value, repeatIndex=None)

	def buildFormat2(self, writer, font, values):
		segStart, segValue = values[0]
		segEnd = segStart
		segments = []
		for glyphID, curValue in values[1:]:
			if glyphID != segEnd + 1 or curValue != segValue:
				segments.append((segStart, segEnd, segValue))
				segStart = segEnd = glyphID
				segValue = curValue
			else:
				segEnd = glyphID
		segments.append((segStart, segEnd, segValue))
		valueSize = self.converter.staticSize
		numUnits, unitSize = len(segments) + 1, valueSize + 4
		return (2 + self.BIN_SEARCH_HEADER_SIZE + numUnits * unitSize, 2,
		        lambda: self.writeFormat2(writer, font, segments))

	def writeFormat2(self, writer, font, segments):
		writer.writeUShort(2)
		valueSize = self.converter.staticSize
		numUnits, unitSize = len(segments), valueSize + 4
		self.writeBinSearchHeader(writer, numUnits, unitSize)
		for firstGlyph, lastGlyph, value in segments:
			writer.writeUShort(lastGlyph)
			writer.writeUShort(firstGlyph)
			self.converter.write(
				writer, font, tableDict=None,
				value=value, repeatIndex=None)
		writer.writeUShort(0xFFFF)
		writer.writeUShort(0xFFFF)
		writer.writeData(b'\x00' * valueSize)

	def buildFormat6(self, writer, font, values):
		valueSize = self.converter.staticSize
		numUnits, unitSize = len(values), valueSize + 2
		return (2 + self.BIN_SEARCH_HEADER_SIZE + (numUnits + 1) * unitSize, 6,
			lambda: self.writeFormat6(writer, font, values))

	def writeFormat6(self, writer, font, values):
		writer.writeUShort(6)
		valueSize = self.converter.staticSize
		numUnits, unitSize = len(values), valueSize + 2
		self.writeBinSearchHeader(writer, numUnits, unitSize)
		for glyphID, value in values:
			writer.writeUShort(glyphID)
			self.converter.write(
				writer, font, tableDict=None,
				value=value, repeatIndex=None)
		writer.writeUShort(0xFFFF)
		writer.writeData(b'\x00' * valueSize)

	def buildFormat8(self, writer, font, values):
		minGlyphID, maxGlyphID = values[0][0], values[-1][0]
		if len(values) != maxGlyphID - minGlyphID + 1:
			return None
		valueSize = self.converter.staticSize
		return (6 + len(values) * valueSize, 8,
                        lambda: self.writeFormat8(writer, font, values))

	def writeFormat8(self, writer, font, values):
		firstGlyphID = values[0][0]
		writer.writeUShort(8)
		writer.writeUShort(firstGlyphID)
		writer.writeUShort(len(values))
		for _, value in values:
			self.converter.write(
				writer, font, tableDict=None,
				value=value, repeatIndex=None)

	def readFormat0(self, reader, font):
		numGlyphs = len(font.getGlyphOrder())
		data = self.converter.readArray(
			reader, font, tableDict=None, count=numGlyphs)
		return {font.getGlyphName(k): value
		        for k, value in enumerate(data)}

	def readFormat2(self, reader, font):
		mapping = {}
		pos = reader.pos - 2  # start of table is at UShort for format
		unitSize, numUnits = reader.readUShort(), reader.readUShort()
		assert unitSize >= 4 + self.converter.staticSize, unitSize
		for i in range(numUnits):
			reader.seek(pos + i * unitSize + 12)
			last = reader.readUShort()
			first = reader.readUShort()
			value = self.converter.read(reader, font, tableDict=None)
			if last != 0xFFFF:
				for k in range(first, last + 1):
					mapping[font.getGlyphName(k)] = value
		return mapping

	def readFormat4(self, reader, font):
		mapping = {}
		pos = reader.pos - 2  # start of table is at UShort for format
		unitSize = reader.readUShort()
		assert unitSize >= 6, unitSize
		for i in range(reader.readUShort()):
			reader.seek(pos + i * unitSize + 12)
			last = reader.readUShort()
			first = reader.readUShort()
			offset = reader.readUShort()
			if last != 0xFFFF:
				dataReader = reader.getSubReader(0)  # relative to current position
				dataReader.seek(pos + offset)  # relative to start of table
				data = self.converter.readArray(
					dataReader, font, tableDict=None,
					count=last - first + 1)
				for k, v in enumerate(data):
					mapping[font.getGlyphName(first + k)] = v
		return mapping

	def readFormat6(self, reader, font):
		mapping = {}
		pos = reader.pos - 2  # start of table is at UShort for format
		unitSize = reader.readUShort()
		assert unitSize >= 2 + self.converter.staticSize, unitSize
		for i in range(reader.readUShort()):
			reader.seek(pos + i * unitSize + 12)
			glyphID = reader.readUShort()
			value = self.converter.read(
				reader, font, tableDict=None)
			if glyphID != 0xFFFF:
				mapping[font.getGlyphName(glyphID)] = value
		return mapping

	def readFormat8(self, reader, font):
		first = reader.readUShort()
		count = reader.readUShort()
		data = self.converter.readArray(
			reader, font, tableDict=None, count=count)
		return {font.getGlyphName(first + k): value
		        for (k, value) in enumerate(data)}

	def xmlRead(self, attrs, content, font):
		value = {}
		for element in content:
			if isinstance(element, tuple):
				name, a, eltContent = element
				if name == "Lookup":
					value[a["glyph"]] = self.converter.xmlRead(a, eltContent, font)
		return value

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.begintag(name, attrs)
		xmlWriter.newline()
		for glyph, value in sorted(value.items()):
			self.converter.xmlWrite(
				xmlWriter, font, value=value,
				name="Lookup", attrs=[("glyph", glyph)])
		xmlWriter.endtag(name)
		xmlWriter.newline()


# The AAT 'ankr' table has an unusual structure: An offset to an AATLookup
# followed by an offset to a glyph data table. Other than usual, the
# offsets in the AATLookup are not relative to the beginning of
# the beginning of the 'ankr' table, but relative to the glyph data table.
# So, to find the anchor data for a glyph, one needs to add the offset
# to the data table to the offset found in the AATLookup, and then use
# the sum of these two offsets to find the actual data.
class AATLookupWithDataOffset(BaseConverter):
	def read(self, reader, font, tableDict):
		lookupOffset = reader.readULong()
		dataOffset = reader.readULong()
		lookupReader = reader.getSubReader(lookupOffset)
		lookup = AATLookup('DataOffsets', None, None, UShort)
		offsets = lookup.read(lookupReader, font, tableDict)
		result = {}
		for glyph, offset in offsets.items():
			dataReader = reader.getSubReader(offset + dataOffset)
			item = self.tableClass()
			item.decompile(dataReader, font)
			result[glyph] = item
		return result

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		# We do not work with OTTableWriter sub-writers because
		# the offsets in our AATLookup are relative to our data
		# table, for which we need to provide an offset value itself.
		# It might have been possible to somehow make a kludge for
		# performing this indirect offset computation directly inside
		# OTTableWriter. But this would have made the internal logic
		# of OTTableWriter even more complex than it already is,
		# so we decided to roll our own offset computation for the
		# contents of the AATLookup and associated data table.
		offsetByGlyph, offsetByData, dataLen = {}, {}, 0
		compiledData = []
		for glyph in sorted(value, key=font.getGlyphID):
			subWriter = OTTableWriter()
			value[glyph].compile(subWriter, font)
			data = subWriter.getAllData()
			offset = offsetByData.get(data, None)
			if offset == None:
				offset = dataLen
				dataLen = dataLen + len(data)
				offsetByData[data] = offset
				compiledData.append(data)
			offsetByGlyph[glyph] = offset
		# For calculating the offsets to our AATLookup and data table,
		# we can use the regular OTTableWriter infrastructure.
		lookupWriter = writer.getSubWriter(offsetSize=4)
		lookup = AATLookup('DataOffsets', None, None, UShort)
		lookup.write(lookupWriter, font, tableDict, offsetByGlyph, None)

		dataWriter = writer.getSubWriter(offsetSize=4)

		writer.writeSubTable(lookupWriter)
		writer.writeSubTable(dataWriter)
		for d in compiledData:
			dataWriter.writeData(d)

	def xmlRead(self, attrs, content, font):
		lookup = AATLookup('DataOffsets', None, None, self.tableClass)
		return lookup.xmlRead(attrs, content, font)

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		lookup = AATLookup('DataOffsets', None, None, self.tableClass)
		lookup.xmlWrite(xmlWriter, font, value, name, attrs)


class MorxSubtableConverter(BaseConverter):
	_PROCESSING_ORDERS = {
		# bits 30 and 28 of morx.CoverageFlags; see morx spec
		(False, False): "LayoutOrder",
		(True, False): "ReversedLayoutOrder",
		(False, True): "LogicalOrder",
		(True, True): "ReversedLogicalOrder",
	}

	_PROCESSING_ORDERS_REVERSED = {
		val: key for key, val in _PROCESSING_ORDERS.items()
	}

	def __init__(self, name, repeat, aux):
		BaseConverter.__init__(self, name, repeat, aux)

	def _setTextDirectionFromCoverageFlags(self, flags, subtable):
		if (flags & 0x20) != 0:
			subtable.TextDirection = "Any"
		elif (flags & 0x80) != 0:
			subtable.TextDirection = "Vertical"
		else:
			subtable.TextDirection = "Horizontal"

	def read(self, reader, font, tableDict):
		pos = reader.pos
		m = MorxSubtable()
		m.StructLength = reader.readULong()
		flags = reader.readUInt8()
		orderKey = ((flags & 0x40) != 0, (flags & 0x10) != 0)
		m.ProcessingOrder = self._PROCESSING_ORDERS[orderKey]
		self._setTextDirectionFromCoverageFlags(flags, m)
		m.Reserved = reader.readUShort()
		m.Reserved |= (flags & 0xF) << 16
		m.MorphType = reader.readUInt8()
		m.SubFeatureFlags = reader.readULong()
		tableClass = lookupTypes["morx"].get(m.MorphType)
		if tableClass is None:
			assert False, ("unsupported 'morx' lookup type %s" %
			               m.MorphType)
		# To decode AAT ligatures, we need to know the subtable size.
		# The easiest way to pass this along is to create a new reader
		# that works on just the subtable as its data.
		headerLength = reader.pos - pos
		data = reader.data[
			reader.pos
			: reader.pos + m.StructLength - headerLength]
		assert len(data) == m.StructLength - headerLength
		subReader = OTTableReader(data=data, tableTag=reader.tableTag)
		m.SubStruct = tableClass()
		m.SubStruct.decompile(subReader, font)
		reader.seek(pos + m.StructLength)
		return m

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.begintag(name, attrs)
		xmlWriter.newline()
		xmlWriter.comment("StructLength=%d" % value.StructLength)
		xmlWriter.newline()
		xmlWriter.simpletag("TextDirection", value=value.TextDirection)
		xmlWriter.newline()
		xmlWriter.simpletag("ProcessingOrder",
		                    value=value.ProcessingOrder)
		xmlWriter.newline()
		if value.Reserved != 0:
			xmlWriter.simpletag("Reserved",
			                    value="0x%04x" % value.Reserved)
			xmlWriter.newline()
		xmlWriter.comment("MorphType=%d" % value.MorphType)
		xmlWriter.newline()
		xmlWriter.simpletag("SubFeatureFlags",
		                    value="0x%08x" % value.SubFeatureFlags)
		xmlWriter.newline()
		value.SubStruct.toXML(xmlWriter, font)
		xmlWriter.endtag(name)
		xmlWriter.newline()

	def xmlRead(self, attrs, content, font):
		m = MorxSubtable()
		covFlags = 0
		m.Reserved = 0
		for eltName, eltAttrs, eltContent in filter(istuple, content):
			if eltName == "CoverageFlags":
				# Only in XML from old versions of fonttools.
				covFlags = safeEval(eltAttrs["value"])
				orderKey = ((covFlags & 0x40) != 0,
				            (covFlags & 0x10) != 0)
				m.ProcessingOrder = self._PROCESSING_ORDERS[
					orderKey]
				self._setTextDirectionFromCoverageFlags(
					covFlags, m)
			elif eltName == "ProcessingOrder":
				m.ProcessingOrder = eltAttrs["value"]
				assert m.ProcessingOrder in self._PROCESSING_ORDERS_REVERSED, "unknown ProcessingOrder: %s" % m.ProcessingOrder
			elif eltName == "TextDirection":
				m.TextDirection = eltAttrs["value"]
				assert m.TextDirection in {"Horizontal", "Vertical", "Any"}, "unknown TextDirection %s" % m.TextDirection
			elif eltName == "Reserved":
				m.Reserved = safeEval(eltAttrs["value"])
			elif eltName == "SubFeatureFlags":
				m.SubFeatureFlags = safeEval(eltAttrs["value"])
			elif eltName.endswith("Morph"):
				m.fromXML(eltName, eltAttrs, eltContent, font)
			else:
				assert False, eltName
		m.Reserved = (covFlags & 0xF) << 16 | m.Reserved
		return m

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		covFlags = (value.Reserved & 0x000F0000) >> 16
		reverseOrder, logicalOrder = self._PROCESSING_ORDERS_REVERSED[
			value.ProcessingOrder]
		covFlags |= 0x80 if value.TextDirection == "Vertical" else 0
		covFlags |= 0x40 if reverseOrder else 0
		covFlags |= 0x20 if value.TextDirection == "Any" else 0
		covFlags |= 0x10 if logicalOrder else 0
		value.CoverageFlags = covFlags
		lengthIndex = len(writer.items)
		before = writer.getDataLength()
		value.StructLength = 0xdeadbeef
		# The high nibble of value.Reserved is actuallly encoded
		# into coverageFlags, so we need to clear it here.
		origReserved = value.Reserved # including high nibble
		value.Reserved = value.Reserved & 0xFFFF # without high nibble
		value.compile(writer, font)
		value.Reserved = origReserved  # restore original value
		assert writer.items[lengthIndex] == b"\xde\xad\xbe\xef"
		length = writer.getDataLength() - before
		writer.items[lengthIndex] = struct.pack(">L", length)


# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6Tables.html#ExtendedStateHeader
# TODO: Untangle the implementation of the various lookup-specific formats.
class STXHeader(BaseConverter):
	def __init__(self, name, repeat, aux, tableClass):
		BaseConverter.__init__(self, name, repeat, aux, tableClass)
		assert issubclass(self.tableClass, AATAction)
		self.classLookup = AATLookup("GlyphClasses", None, None, UShort)
		if issubclass(self.tableClass, ContextualMorphAction):
			self.perGlyphLookup = AATLookup("PerGlyphLookup",
			                                None, None, GlyphID)
		else:
			self.perGlyphLookup = None

	def read(self, reader, font, tableDict):
		table = AATStateTable()
		pos = reader.pos
		classTableReader = reader.getSubReader(0)
		stateArrayReader = reader.getSubReader(0)
		entryTableReader = reader.getSubReader(0)
		actionReader = None
		ligaturesReader = None
		table.GlyphClassCount = reader.readULong()
		classTableReader.seek(pos + reader.readULong())
		stateArrayReader.seek(pos + reader.readULong())
		entryTableReader.seek(pos + reader.readULong())
		if self.perGlyphLookup is not None:
			perGlyphTableReader = reader.getSubReader(0)
			perGlyphTableReader.seek(pos + reader.readULong())
		if issubclass(self.tableClass, LigatureMorphAction):
			actionReader = reader.getSubReader(0)
			actionReader.seek(pos + reader.readULong())
			ligComponentReader = reader.getSubReader(0)
			ligComponentReader.seek(pos + reader.readULong())
			ligaturesReader = reader.getSubReader(0)
			ligaturesReader.seek(pos + reader.readULong())
			numLigComponents = (ligaturesReader.pos
			                    - ligComponentReader.pos) // 2
			assert numLigComponents >= 0
			table.LigComponents = \
				ligComponentReader.readUShortArray(numLigComponents)
			table.Ligatures = self._readLigatures(ligaturesReader, font)
		elif issubclass(self.tableClass, InsertionMorphAction):
			actionReader = reader.getSubReader(0)
			actionReader.seek(pos + reader.readULong())
		table.GlyphClasses = self.classLookup.read(classTableReader,
		                                           font, tableDict)
		numStates = int((entryTableReader.pos - stateArrayReader.pos)
		                 / (table.GlyphClassCount * 2))
		for stateIndex in range(numStates):
			state = AATState()
			table.States.append(state)
			for glyphClass in range(table.GlyphClassCount):
				entryIndex = stateArrayReader.readUShort()
				state.Transitions[glyphClass] = \
					self._readTransition(entryTableReader,
					                     entryIndex, font,
					                     actionReader)
		if self.perGlyphLookup is not None:
			table.PerGlyphLookups = self._readPerGlyphLookups(
				table, perGlyphTableReader, font)
		return table

	def _readTransition(self, reader, entryIndex, font, actionReader):
		transition = self.tableClass()
		entryReader = reader.getSubReader(
			reader.pos + entryIndex * transition.staticSize)
		transition.decompile(entryReader, font, actionReader)
		return transition

	def _readLigatures(self, reader, font):
		limit = len(reader.data)
		numLigatureGlyphs = (limit - reader.pos) // 2
		return [font.getGlyphName(g)
		        for g in reader.readUShortArray(numLigatureGlyphs)]

	def _countPerGlyphLookups(self, table):
		# Somewhat annoyingly, the morx table does not encode
		# the size of the per-glyph table. So we need to find
		# the maximum value that MorphActions use as index
		# into this table.
		numLookups = 0
		for state in table.States:
			for t in state.Transitions.values():
				if isinstance(t, ContextualMorphAction):
					if t.MarkIndex != 0xFFFF:
						numLookups = max(
							numLookups,
							t.MarkIndex + 1)
					if t.CurrentIndex != 0xFFFF:
						numLookups = max(
							numLookups,
							t.CurrentIndex + 1)
		return numLookups

	def _readPerGlyphLookups(self, table, reader, font):
		pos = reader.pos
		lookups = []
		for _ in range(self._countPerGlyphLookups(table)):
			lookupReader = reader.getSubReader(0)
			lookupReader.seek(pos + reader.readULong())
			lookups.append(
				self.perGlyphLookup.read(lookupReader, font, {}))
		return lookups

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		glyphClassWriter = OTTableWriter()
		self.classLookup.write(glyphClassWriter, font, tableDict,
		                       value.GlyphClasses, repeatIndex=None)
		glyphClassData = pad(glyphClassWriter.getAllData(), 2)
		glyphClassCount = max(value.GlyphClasses.values()) + 1
		glyphClassTableOffset = 16  # size of STXHeader
		if self.perGlyphLookup is not None:
			glyphClassTableOffset += 4

		glyphClassTableOffset += self.tableClass.actionHeaderSize
		actionData, actionIndex = \
			self.tableClass.compileActions(font, value.States)
		stateArrayData, entryTableData = self._compileStates(
			font, value.States, glyphClassCount, actionIndex)
		stateArrayOffset = glyphClassTableOffset + len(glyphClassData)
		entryTableOffset = stateArrayOffset + len(stateArrayData)
		perGlyphOffset = entryTableOffset + len(entryTableData)
		perGlyphData = \
			pad(self._compilePerGlyphLookups(value, font), 4)
		if actionData is not None:
			actionOffset = entryTableOffset + len(entryTableData)
		else:
			actionOffset = None

		ligaturesOffset, ligComponentsOffset = None, None
		ligComponentsData = self._compileLigComponents(value, font)
		ligaturesData = self._compileLigatures(value, font)
		if ligComponentsData is not None:
			assert len(perGlyphData) == 0
			ligComponentsOffset = actionOffset + len(actionData)
			ligaturesOffset = ligComponentsOffset + len(ligComponentsData)

		writer.writeULong(glyphClassCount)
		writer.writeULong(glyphClassTableOffset)
		writer.writeULong(stateArrayOffset)
		writer.writeULong(entryTableOffset)
		if self.perGlyphLookup is not None:
			writer.writeULong(perGlyphOffset)
		if actionOffset is not None:
			writer.writeULong(actionOffset)
		if ligComponentsOffset is not None:
			writer.writeULong(ligComponentsOffset)
			writer.writeULong(ligaturesOffset)
		writer.writeData(glyphClassData)
		writer.writeData(stateArrayData)
		writer.writeData(entryTableData)
		writer.writeData(perGlyphData)
		if actionData is not None:
			writer.writeData(actionData)
		if ligComponentsData is not None:
			writer.writeData(ligComponentsData)
		if ligaturesData is not None:
			writer.writeData(ligaturesData)

	def _compileStates(self, font, states, glyphClassCount, actionIndex):
		stateArrayWriter = OTTableWriter()
		entries, entryIDs = [], {}
		for state in states:
			for glyphClass in range(glyphClassCount):
				transition = state.Transitions[glyphClass]
				entryWriter = OTTableWriter()
				transition.compile(entryWriter, font,
				                   actionIndex)
				entryData = entryWriter.getAllData()
				assert len(entryData)  == transition.staticSize, ( \
					"%s has staticSize %d, "
					"but actually wrote %d bytes" % (
						repr(transition),
						transition.staticSize,
						len(entryData)))
				entryIndex = entryIDs.get(entryData)
				if entryIndex is None:
					entryIndex = len(entries)
					entryIDs[entryData] = entryIndex
					entries.append(entryData)
				stateArrayWriter.writeUShort(entryIndex)
		stateArrayData = pad(stateArrayWriter.getAllData(), 4)
		entryTableData = pad(bytesjoin(entries), 4)
		return stateArrayData, entryTableData

	def _compilePerGlyphLookups(self, table, font):
		if self.perGlyphLookup is None:
			return b""
		numLookups = self._countPerGlyphLookups(table)
		assert len(table.PerGlyphLookups) == numLookups, (
			"len(AATStateTable.PerGlyphLookups) is %d, "
			"but the actions inside the table refer to %d" %
				(len(table.PerGlyphLookups), numLookups))
		writer = OTTableWriter()
		for lookup in table.PerGlyphLookups:
			lookupWriter = writer.getSubWriter(offsetSize=4)
			self.perGlyphLookup.write(lookupWriter, font,
			                          {}, lookup, None)
			writer.writeSubTable(lookupWriter)
		return writer.getAllData()

	def _compileLigComponents(self, table, font):
		if not hasattr(table, "LigComponents"):
			return None
		writer = OTTableWriter()
		for component in table.LigComponents:
			writer.writeUShort(component)
		return writer.getAllData()

	def _compileLigatures(self, table, font):
		if not hasattr(table, "Ligatures"):
			return None
		writer = OTTableWriter()
		for glyphName in table.Ligatures:
			writer.writeUShort(font.getGlyphID(glyphName))
		return writer.getAllData()

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.begintag(name, attrs)
		xmlWriter.newline()
		xmlWriter.comment("GlyphClassCount=%s" %value.GlyphClassCount)
		xmlWriter.newline()
		for g, klass in sorted(value.GlyphClasses.items()):
			xmlWriter.simpletag("GlyphClass", glyph=g, value=klass)
			xmlWriter.newline()
		for stateIndex, state in enumerate(value.States):
			xmlWriter.begintag("State", index=stateIndex)
			xmlWriter.newline()
			for glyphClass, trans in sorted(state.Transitions.items()):
				trans.toXML(xmlWriter, font=font,
				            attrs={"onGlyphClass": glyphClass},
				            name="Transition")
			xmlWriter.endtag("State")
			xmlWriter.newline()
		for i, lookup in enumerate(value.PerGlyphLookups):
			xmlWriter.begintag("PerGlyphLookup", index=i)
			xmlWriter.newline()
			for glyph, val in sorted(lookup.items()):
				xmlWriter.simpletag("Lookup", glyph=glyph,
				                    value=val)
				xmlWriter.newline()
			xmlWriter.endtag("PerGlyphLookup")
			xmlWriter.newline()
		if hasattr(value, "LigComponents"):
			xmlWriter.begintag("LigComponents")
			xmlWriter.newline()
			for i, val in enumerate(getattr(value, "LigComponents")):
				xmlWriter.simpletag("LigComponent", index=i,
				                    value=val)
				xmlWriter.newline()
			xmlWriter.endtag("LigComponents")
			xmlWriter.newline()
		self._xmlWriteLigatures(xmlWriter, font, value, name, attrs)
		xmlWriter.endtag(name)
		xmlWriter.newline()

	def _xmlWriteLigatures(self, xmlWriter, font, value, name, attrs):
		if not hasattr(value, "Ligatures"):
			return
		xmlWriter.begintag("Ligatures")
		xmlWriter.newline()
		for i, g in enumerate(getattr(value, "Ligatures")):
			xmlWriter.simpletag("Ligature", index=i, glyph=g)
			xmlWriter.newline()
		xmlWriter.endtag("Ligatures")
		xmlWriter.newline()

	def xmlRead(self, attrs, content, font):
		table = AATStateTable()
		for eltName, eltAttrs, eltContent in filter(istuple, content):
			if eltName == "GlyphClass":
				glyph = eltAttrs["glyph"]
				value = eltAttrs["value"]
				table.GlyphClasses[glyph] = safeEval(value)
			elif eltName == "State":
				state = self._xmlReadState(eltAttrs, eltContent, font)
				table.States.append(state)
			elif eltName == "PerGlyphLookup":
				lookup = self.perGlyphLookup.xmlRead(
					eltAttrs, eltContent, font)
				table.PerGlyphLookups.append(lookup)
			elif eltName == "LigComponents":
				table.LigComponents = \
					self._xmlReadLigComponents(
						eltAttrs, eltContent, font)
			elif eltName == "Ligatures":
				table.Ligatures = \
					self._xmlReadLigatures(
						eltAttrs, eltContent, font)
		table.GlyphClassCount = max(table.GlyphClasses.values()) + 1
		return table

	def _xmlReadState(self, attrs, content, font):
		state = AATState()
		for eltName, eltAttrs, eltContent in filter(istuple, content):
			if eltName == "Transition":
				glyphClass = safeEval(eltAttrs["onGlyphClass"])
				transition = self.tableClass()
				transition.fromXML(eltName, eltAttrs,
				                   eltContent, font)
				state.Transitions[glyphClass] = transition
		return state

	def _xmlReadLigComponents(self, attrs, content, font):
		ligComponents = []
		for eltName, eltAttrs, _eltContent in filter(istuple, content):
			if eltName == "LigComponent":
				ligComponents.append(
					safeEval(eltAttrs["value"]))
		return ligComponents

	def _xmlReadLigatures(self, attrs, content, font):
		ligs = []
		for eltName, eltAttrs, _eltContent in filter(istuple, content):
			if eltName == "Ligature":
				ligs.append(eltAttrs["glyph"])
		return ligs


class CIDGlyphMap(BaseConverter):
	def read(self, reader, font, tableDict):
		numCIDs = reader.readUShort()
		result = {}
		for cid, glyphID in enumerate(reader.readUShortArray(numCIDs)):
			if glyphID != 0xFFFF:
				result[cid] = font.getGlyphName(glyphID)
		return result

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		items = {cid: font.getGlyphID(glyph)
		         for cid, glyph in value.items()}
		count = max(items) + 1 if items else 0
		writer.writeUShort(count)
		for cid in range(count):
			writer.writeUShort(items.get(cid, 0xFFFF))

	def xmlRead(self, attrs, content, font):
		result = {}
		for eName, eAttrs, _eContent in filter(istuple, content):
			if eName == "CID":
				result[safeEval(eAttrs["cid"])] = \
					eAttrs["glyph"].strip()
		return result

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.begintag(name, attrs)
		xmlWriter.newline()
		for cid, glyph in sorted(value.items()):
			if glyph is not None and glyph != 0xFFFF:
				xmlWriter.simpletag(
					"CID", cid=cid, glyph=glyph)
				xmlWriter.newline()
		xmlWriter.endtag(name)
		xmlWriter.newline()


class GlyphCIDMap(BaseConverter):
	def read(self, reader, font, tableDict):
		glyphOrder = font.getGlyphOrder()
		count = reader.readUShort()
		cids = reader.readUShortArray(count)
		if count > len(glyphOrder):
			log.warning("GlyphCIDMap has %d elements, "
			            "but the font has only %d glyphs; "
			            "ignoring the rest" %
			             (count, len(glyphOrder)))
		result = {}
		for glyphID in range(min(len(cids), len(glyphOrder))):
			cid = cids[glyphID]
			if cid != 0xFFFF:
				result[glyphOrder[glyphID]] = cid
		return result

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		items = {font.getGlyphID(g): cid
		         for g, cid in value.items()
		         if cid is not None and cid != 0xFFFF}
		count = max(items) + 1 if items else 0
		writer.writeUShort(count)
		for glyphID in range(count):
			writer.writeUShort(items.get(glyphID, 0xFFFF))

	def xmlRead(self, attrs, content, font):
		result = {}
		for eName, eAttrs, _eContent in filter(istuple, content):
			if eName == "CID":
				result[eAttrs["glyph"]] = \
					safeEval(eAttrs["value"])
		return result

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.begintag(name, attrs)
		xmlWriter.newline()
		for glyph, cid in sorted(value.items()):
			if cid is not None and cid != 0xFFFF:
				xmlWriter.simpletag(
					"CID", glyph=glyph, value=cid)
				xmlWriter.newline()
		xmlWriter.endtag(name)
		xmlWriter.newline()


class DeltaValue(BaseConverter):

	def read(self, reader, font, tableDict):
		StartSize = tableDict["StartSize"]
		EndSize = tableDict["EndSize"]
		DeltaFormat = tableDict["DeltaFormat"]
		assert DeltaFormat in (1, 2, 3), "illegal DeltaFormat"
		nItems = EndSize - StartSize + 1
		nBits = 1 << DeltaFormat
		minusOffset = 1 << nBits
		mask = (1 << nBits) - 1
		signMask = 1 << (nBits - 1)

		DeltaValue = []
		tmp, shift = 0, 0
		for i in range(nItems):
			if shift == 0:
				tmp, shift = reader.readUShort(), 16
			shift = shift - nBits
			value = (tmp >> shift) & mask
			if value & signMask:
				value = value - minusOffset
			DeltaValue.append(value)
		return DeltaValue

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		StartSize = tableDict["StartSize"]
		EndSize = tableDict["EndSize"]
		DeltaFormat = tableDict["DeltaFormat"]
		DeltaValue = value
		assert DeltaFormat in (1, 2, 3), "illegal DeltaFormat"
		nItems = EndSize - StartSize + 1
		nBits = 1 << DeltaFormat
		assert len(DeltaValue) == nItems
		mask = (1 << nBits) - 1

		tmp, shift = 0, 16
		for value in DeltaValue:
			shift = shift - nBits
			tmp = tmp | ((value & mask) << shift)
			if shift == 0:
				writer.writeUShort(tmp)
				tmp, shift = 0, 16
		if shift != 16:
			writer.writeUShort(tmp)

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.simpletag(name, attrs + [("value", value)])
		xmlWriter.newline()

	def xmlRead(self, attrs, content, font):
		return safeEval(attrs["value"])


class VarIdxMapValue(BaseConverter):

	def read(self, reader, font, tableDict):
		fmt = tableDict['EntryFormat']
		nItems = tableDict['MappingCount']

		innerBits = 1 + (fmt & 0x000F)
		innerMask = (1<<innerBits) - 1
		outerMask = 0xFFFFFFFF - innerMask
		outerShift = 16 - innerBits

		entrySize = 1 + ((fmt & 0x0030) >> 4)
		readArray = {
			1: reader.readUInt8Array,
			2: reader.readUShortArray,
			3: reader.readUInt24Array,
			4: reader.readULongArray,
		}[entrySize]

		return [(((raw & outerMask) << outerShift) | (raw & innerMask))
			for raw in readArray(nItems)]

	def write(self, writer, font, tableDict, value, repeatIndex=None):
		fmt = tableDict['EntryFormat']
		mapping = value
		writer['MappingCount'].setValue(len(mapping))

		innerBits = 1 + (fmt & 0x000F)
		innerMask = (1<<innerBits) - 1
		outerShift = 16 - innerBits

		entrySize = 1 + ((fmt & 0x0030) >> 4)
		writeArray = {
			1: writer.writeUInt8Array,
			2: writer.writeUShortArray,
			3: writer.writeUInt24Array,
			4: writer.writeULongArray,
		}[entrySize]

		writeArray([(((idx & 0xFFFF0000) >> outerShift) | (idx & innerMask))
			    for idx in mapping])


class VarDataValue(BaseConverter):

	def read(self, reader, font, tableDict):
		values = []

		regionCount = tableDict["VarRegionCount"]
		wordCount = tableDict["NumShorts"]

		# https://github.com/fonttools/fonttools/issues/2279
		longWords = bool(wordCount & 0x8000)
		wordCount = wordCount & 0x7FFF

		if longWords:
			readBigArray, readSmallArray = reader.readLongArray, reader.readShortArray
		else:
			readBigArray, readSmallArray = reader.readShortArray, reader.readInt8Array

		n1, n2 = min(regionCount, wordCount), max(regionCount, wordCount)
		values.extend(readBigArray(n1))
		values.extend(readSmallArray(n2 - n1))
		if n2 > regionCount: # Padding
			del values[regionCount:]

		return values

	def write(self, writer, font, tableDict, values, repeatIndex=None):
		regionCount = tableDict["VarRegionCount"]
		wordCount = tableDict["NumShorts"]

		# https://github.com/fonttools/fonttools/issues/2279
		longWords = bool(wordCount & 0x8000)
		wordCount = wordCount & 0x7FFF

		(writeBigArray, writeSmallArray) = {
			False: (writer.writeShortArray, writer.writeInt8Array),
			True:  (writer.writeLongArray,  writer.writeShortArray),
		}[longWords]

		n1, n2 = min(regionCount, wordCount), max(regionCount, wordCount)
		writeBigArray(values[:n1])
		writeSmallArray(values[n1:regionCount])
		if n2 > regionCount: # Padding
			writer.writeSmallArray([0] * (n2 - regionCount))

	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.simpletag(name, attrs + [("value", value)])
		xmlWriter.newline()

	def xmlRead(self, attrs, content, font):
		return safeEval(attrs["value"])

class LookupFlag(UShort):
	def xmlWrite(self, xmlWriter, font, value, name, attrs):
		xmlWriter.simpletag(name, attrs + [("value", value)])
		flags = []
		if value & 0x01: flags.append("rightToLeft")
		if value & 0x02: flags.append("ignoreBaseGlyphs")
		if value & 0x04: flags.append("ignoreLigatures")
		if value & 0x08: flags.append("ignoreMarks")
		if value & 0x10: flags.append("useMarkFilteringSet")
		if value & 0xff00: flags.append("markAttachmentType[%i]" % (value >> 8))
		if flags:
			xmlWriter.comment(" ".join(flags))
		xmlWriter.newline()


class _UInt8Enum(UInt8):
	enumClass = NotImplemented

	def read(self, reader, font, tableDict):
		return self.enumClass(super().read(reader, font, tableDict))
	@classmethod
	def fromString(cls, value):
		return getattr(cls.enumClass, value.upper())
	@classmethod
	def toString(cls, value):
		return cls.enumClass(value).name.lower()


class ExtendMode(_UInt8Enum):
	enumClass = _ExtendMode


class CompositeMode(_UInt8Enum):
	enumClass = _CompositeMode


converterMapping = {
	# type		class
	"int8":		Int8,
	"int16":	Short,
	"uint8":	UInt8,
	"uint16":	UShort,
	"uint24":	UInt24,
	"uint32":	ULong,
	"char64":	Char64,
	"Flags32":	Flags32,
	"VarIndex":	VarIndex,
	"Version":	Version,
	"Tag":		Tag,
	"GlyphID":	GlyphID,
	"GlyphID32":	GlyphID32,
	"NameID":	NameID,
	"DeciPoints":	DeciPoints,
	"Fixed":	Fixed,
	"F2Dot14":	F2Dot14,
	"Angle":	Angle,
	"struct":	Struct,
	"Offset":	Table,
	"LOffset":	LTable,
	"Offset24":	Table24,
	"ValueRecord":	ValueRecord,
	"DeltaValue":	DeltaValue,
	"VarIdxMapValue":	VarIdxMapValue,
	"VarDataValue":	VarDataValue,
	"LookupFlag": LookupFlag,
	"ExtendMode": ExtendMode,
	"CompositeMode": CompositeMode,
	"STATFlags": STATFlags,

	# AAT
	"CIDGlyphMap":	CIDGlyphMap,
	"GlyphCIDMap":	GlyphCIDMap,
	"MortChain":	StructWithLength,
	"MortSubtable": StructWithLength,
	"MorxChain":	StructWithLength,
	"MorxSubtable": MorxSubtableConverter,

	# "Template" types
	"AATLookup":	lambda C: partial(AATLookup, tableClass=C),
	"AATLookupWithDataOffset":	lambda C: partial(AATLookupWithDataOffset, tableClass=C),
	"STXHeader":	lambda C: partial(STXHeader, tableClass=C),
	"OffsetTo":	lambda C: partial(Table, tableClass=C),
	"LOffsetTo":	lambda C: partial(LTable, tableClass=C),
	"LOffset24To":	lambda C: partial(Table24, tableClass=C),
}
