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 bytesjoin, tobytes, tostr, 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,
    NO_VARIATION_INDEX,
)
from itertools import zip_longest
from functools import partial
import re
import struct
from typing import Optional
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, description=descr)

        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, *, description=""):
        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",
        ]
        self.description = description

    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)

    varIndexBasePlusOffsetRE = re.compile(r"VarIndexBase\s*\+\s*(\d+)")

    def getVarIndexOffset(self) -> Optional[int]:
        """If description has `VarIndexBase + {offset}`, return the offset else None."""
        m = self.varIndexBasePlusOffsetRE.search(self.description)
        if not m:
            return None
        return int(m.group(1))


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 = NO_VARIATION_INDEX


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):
        return font.getGlyphNameMany(
            reader.readArray(self.typecode, self.staticSize, count)
        )

    def read(self, reader, font, tableDict):
        return font.getGlyphName(reader.readValue(self.typecode, self.staticSize))

    def writeArray(self, writer, font, tableDict, values):
        writer.writeArray(self.typecode, font.getGlyphIDMany(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 BaseFixedValue(FloatValue):
    staticSize = NotImplemented
    precisionBits = NotImplemented
    readerMethod = NotImplemented
    writerMethod = NotImplemented

    def read(self, reader, font, tableDict):
        return self.fromInt(getattr(reader, self.readerMethod)())

    def write(self, writer, font, tableDict, value, repeatIndex=None):
        getattr(writer, self.writerMethod)(self.toInt(value))

    @classmethod
    def fromInt(cls, value):
        return fi2fl(value, cls.precisionBits)

    @classmethod
    def toInt(cls, value):
        return fl2fi(value, cls.precisionBits)

    @classmethod
    def fromString(cls, value):
        return str2fl(value, cls.precisionBits)

    @classmethod
    def toString(cls, value):
        return fl2str(value, cls.precisionBits)


class Fixed(BaseFixedValue):
    staticSize = 4
    precisionBits = 16
    readerMethod = "readLong"
    writerMethod = "writeLong"


class F2Dot14(BaseFixedValue):
    staticSize = 2
    precisionBits = 14
    readerMethod = "readShort"
    writerMethod = "writeShort"


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.
    bias = 0.0
    factor = 1.0 / (1 << 14) * 180  # 0.010986328125

    @classmethod
    def fromInt(cls, value):
        return (super().fromInt(value) + cls.bias) * 180

    @classmethod
    def toInt(cls, value):
        return super().toInt((value / 180) - cls.bias)

    @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 BiasedAngle(Angle):
    # A bias of 1.0 is used in the representation of start and end angles
    # of COLRv1 PaintSweepGradients to allow for encoding +360deg
    bias = 1.0


class Version(SimpleValue):
    staticSize = 4

    def read(self, reader, font, tableDict):
        value = reader.readLong()
        return value

    def write(self, writer, font, tableDict, value, repeatIndex=None):
        value = fi2ve(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()
            subWriter.name = self.name
            if repeatIndex is not None:
                subWriter.repeatIndex = repeatIndex
            writer.writeSubTable(subWriter, offsetSize=self.staticSize)
            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, *, description=""):
        BaseConverter.__init__(
            self, name, repeat, aux, tableClass, description=description
        )
        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, *, description=""):
        BaseConverter.__init__(
            self, name, repeat, aux, tableClass, description=description
        )
        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()
        lookup = AATLookup("DataOffsets", None, None, UShort)
        lookup.write(lookupWriter, font, tableDict, offsetByGlyph, None)

        dataWriter = writer.getSubWriter()
        writer.writeSubTable(lookupWriter, offsetSize=4)
        writer.writeSubTable(dataWriter, offsetSize=4)
        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, tableClass=None, *, description=""):
        BaseConverter.__init__(
            self, name, repeat, aux, tableClass, description=description
        )

    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, *, description=""):
        BaseConverter.__init__(
            self, name, repeat, aux, tableClass, description=description
        )
        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.getGlyphNameMany(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()
            self.perGlyphLookup.write(lookupWriter, font, {}, lookup, None)
            writer.writeSubTable(lookupWriter, offsetSize=4)
        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,
    "BiasedAngle": BiasedAngle,
    "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),
}
