def compile(self, ttFont):
    if self.data:
        return (struct.pack('>HHLLL', self.format, self.reserved, self.length, self.language, self.nGroups) + self.data)
    charCodes = list(self.cmap.keys())
    lenCharCodes = len(charCodes)
    names = list(self.cmap.values())
    nameMap = ttFont.getReverseGlyphMap()
    try:
        gids = list(map(operator.getitem, ([nameMap] * lenCharCodes), names))
    except KeyError:
        nameMap = ttFont.getReverseGlyphMap(rebuild=True)
        try:
            gids = list(map(operator.getitem, ([nameMap] * lenCharCodes), names))
        except KeyError:
            gids = []
            for name in names:
                try:
                    gid = nameMap[name]
                except KeyError:
                    try:
                        if (name[:3] == 'gid'):
                            gid = eval(name[3:])
                        else:
                            gid = ttFont.getGlyphID(name)
                    except:
                        raise KeyError(name)
                gids.append(gid)
    cmap = {}
    list(map(operator.setitem, ([cmap] * len(charCodes)), charCodes, gids))
    charCodes.sort()
    index = 0
    startCharCode = charCodes[0]
    startGlyphID = cmap[startCharCode]
    lastGlyphID = (startGlyphID - self._format_step)
    lastCharCode = (startCharCode - 1)
    nGroups = 0
    dataList = []
    maxIndex = len(charCodes)
    for index in range(maxIndex):
        charCode = charCodes[index]
        glyphID = cmap[charCode]
        if (not self._IsInSameRun(glyphID, lastGlyphID, charCode, lastCharCode)):
            dataList.append(struct.pack('>LLL', startCharCode, lastCharCode, startGlyphID))
            startCharCode = charCode
            startGlyphID = glyphID
            nGroups = (nGroups + 1)
        lastGlyphID = glyphID
        lastCharCode = charCode
    dataList.append(struct.pack('>LLL', startCharCode, lastCharCode, startGlyphID))
    nGroups = (nGroups + 1)
    data = bytesjoin(dataList)
    lengthSubtable = (len(data) + 16)
    assert (len(data) == (nGroups * 12) == (lengthSubtable - 16))
    return (struct.pack('>HHLLL', self.format, self.reserved, lengthSubtable, self.language, nGroups) + data)
def compile(self, ttFont):
    if self.data:
        return (struct.pack('>HHLLL', self.format, self.reserved, self.length, self.language, self.nGroups) + self.data)
    charCodes = list(self.cmap.keys())
    lenCharCodes = len(charCodes)
    names = list(self.cmap.values())
    nameMap = ttFont.getReverseGlyphMap()
    try:
        gids = list(map(operator.getitem, ([nameMap] * lenCharCodes), names))
    except KeyError:
        nameMap = ttFont.getReverseGlyphMap(rebuild=True)
        try:
            gids = list(map(operator.getitem, ([nameMap] * lenCharCodes), names))
        except KeyError:
            gids = []
            for name in names:
                try:
                    gid = nameMap[name]
                except KeyError:
                    try:
                        if (name[:3] == 'gid'):
                            gid = eval(name[3:])
                        else:
                            gid = ttFont.getGlyphID(name)
                    except:
                        raise KeyError(name)
                gids.append(gid)
    cmap = {}
    list(map(operator.setitem, ([cmap] * len(charCodes)), charCodes, gids))
    charCodes.sort()
    index = 0
    startCharCode = charCodes[0]
    startGlyphID = cmap[startCharCode]
    lastGlyphID = (startGlyphID - self._format_step)
    lastCharCode = (startCharCode - 1)
    nGroups = 0
    dataList = []
    maxIndex = len(charCodes)
    for index in range(maxIndex):
        charCode = charCodes[index]
        glyphID = cmap[charCode]
        if (not self._IsInSameRun(glyphID, lastGlyphID, charCode, lastCharCode)):
            dataList.append(struct.pack('>LLL', startCharCode, lastCharCode, startGlyphID))
            startCharCode = charCode
            startGlyphID = glyphID
            nGroups = (nGroups + 1)
        lastGlyphID = glyphID
        lastCharCode = charCode
    dataList.append(struct.pack('>LLL', startCharCode, lastCharCode, startGlyphID))
    nGroups = (nGroups + 1)
    data = bytesjoin(dataList)
    lengthSubtable = (len(data) + 16)
    assert (len(data) == (nGroups * 12) == (lengthSubtable - 16))
    return (struct.pack('>HHLLL', self.format, self.reserved, lengthSubtable, self.language, nGroups) + data)