from __future__ import print_function, division, absolute_import, unicode_literals
from fontTools.misc.py23 import *
from fontTools import ttLib
from .woff2 import (WOFF2Reader, woff2DirectorySize, woff2DirectoryFormat,
	woff2FlagsSize, woff2UnknownTagSize, woff2Base128MaxSize, WOFF2DirectoryEntry,
	getKnownTagIndex, packBase128, base128Size, woff2UnknownTagIndex,
	WOFF2FlavorData, woff2TransformedTableTags, WOFF2GlyfTable, WOFF2LocaTable,
	WOFF2Writer)
import unittest
from fontTools.misc import sstruct
import os
import random
import copy
from collections import OrderedDict

haveBrotli = False
try:
	import brotli
	haveBrotli = True
except ImportError:
	pass


# Python 3 renamed 'assertRaisesRegexp' to 'assertRaisesRegex', and fires
# deprecation warnings if a program uses the old name.
if not hasattr(unittest.TestCase, 'assertRaisesRegex'):
	unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp


current_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
data_dir = os.path.join(current_dir, 'testdata')
TTX = os.path.join(data_dir, 'TestTTF-Regular.ttx')
OTX = os.path.join(data_dir, 'TestOTF-Regular.otx')
METADATA = os.path.join(data_dir, 'test_woff2_metadata.xml')

TT_WOFF2 = BytesIO()
CFF_WOFF2 = BytesIO()


def setUpModule():
	if not haveBrotli:
		raise unittest.SkipTest("No module named brotli")
	assert os.path.exists(TTX)
	assert os.path.exists(OTX)
	# import TT-flavoured test font and save it as WOFF2
	ttf = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
	ttf.importXML(TTX)
	ttf.flavor = "woff2"
	ttf.save(TT_WOFF2, reorderTables=None)
	# import CFF-flavoured test font and save it as WOFF2
	otf = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
	otf.importXML(OTX)
	otf.flavor = "woff2"
	otf.save(CFF_WOFF2, reorderTables=None)


class WOFF2ReaderTest(unittest.TestCase):

	@classmethod
	def setUpClass(cls):
		cls.file = BytesIO(CFF_WOFF2.getvalue())
		cls.font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
		cls.font.importXML(OTX)

	def setUp(self):
		self.file.seek(0)

	def test_bad_signature(self):
		with self.assertRaisesRegex(ttLib.TTLibError, 'bad signature'):
			WOFF2Reader(BytesIO(b"wOFF"))

	def test_not_enough_data_header(self):
		incomplete_header = self.file.read(woff2DirectorySize - 1)
		with self.assertRaisesRegex(ttLib.TTLibError, 'not enough data'):
			WOFF2Reader(BytesIO(incomplete_header))

	def test_incorrect_compressed_size(self):
		data = self.file.read(woff2DirectorySize)
		header = sstruct.unpack(woff2DirectoryFormat, data)
		header['totalCompressedSize'] = 0
		data = sstruct.pack(woff2DirectoryFormat, header)
		with self.assertRaises((brotli.error, ttLib.TTLibError)):
			WOFF2Reader(BytesIO(data + self.file.read()))

	def test_incorrect_uncompressed_size(self):
		decompress_backup = brotli.decompress
		brotli.decompress = lambda data: b""  # return empty byte string
		with self.assertRaisesRegex(ttLib.TTLibError, 'unexpected size for decompressed'):
			WOFF2Reader(self.file)
		brotli.decompress = decompress_backup

	def test_incorrect_file_size(self):
		data = self.file.read(woff2DirectorySize)
		header = sstruct.unpack(woff2DirectoryFormat, data)
		header['length'] -= 1
		data = sstruct.pack(woff2DirectoryFormat, header)
		with self.assertRaisesRegex(
				ttLib.TTLibError, "doesn't match the actual file size"):
			WOFF2Reader(BytesIO(data + self.file.read()))

	def test_num_tables(self):
		tags = [t for t in self.font.keys() if t not in ('GlyphOrder', 'DSIG')]
		data = self.file.read(woff2DirectorySize)
		header = sstruct.unpack(woff2DirectoryFormat, data)
		self.assertEqual(header['numTables'], len(tags))

	def test_table_tags(self):
		tags = set([t for t in self.font.keys() if t not in ('GlyphOrder', 'DSIG')])
		reader = WOFF2Reader(self.file)
		self.assertEqual(set(reader.keys()), tags)

	def test_get_normal_tables(self):
		woff2Reader = WOFF2Reader(self.file)
		specialTags = woff2TransformedTableTags + ('head', 'GlyphOrder', 'DSIG')
		for tag in [t for t in self.font.keys() if t not in specialTags]:
			origData = self.font.getTableData(tag)
			decompressedData = woff2Reader[tag]
			self.assertEqual(origData, decompressedData)

	def test_reconstruct_unknown(self):
		reader = WOFF2Reader(self.file)
		with self.assertRaisesRegex(ttLib.TTLibError, 'transform for table .* unknown'):
			reader.reconstructTable('ZZZZ')


class WOFF2ReaderTTFTest(WOFF2ReaderTest):
	""" Tests specific to TT-flavored fonts. """

	@classmethod
	def setUpClass(cls):
		cls.file = BytesIO(TT_WOFF2.getvalue())
		cls.font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
		cls.font.importXML(TTX)

	def setUp(self):
		self.file.seek(0)

	def test_reconstruct_glyf(self):
		woff2Reader = WOFF2Reader(self.file)
		reconstructedData = woff2Reader['glyf']
		self.assertEqual(self.font.getTableData('glyf'), reconstructedData)

	def test_reconstruct_loca(self):
		woff2Reader = WOFF2Reader(self.file)
		reconstructedData = woff2Reader['loca']
		self.assertEqual(self.font.getTableData('loca'), reconstructedData)
		self.assertTrue(hasattr(woff2Reader.tables['glyf'], 'data'))

	def test_reconstruct_loca_not_match_orig_size(self):
		reader = WOFF2Reader(self.file)
		reader.tables['loca'].origLength -= 1
		with self.assertRaisesRegex(
				ttLib.TTLibError, "'loca' table doesn't match original size"):
			reader.reconstructTable('loca')


def normalise_table(font, tag, padding=4):
	""" Return normalised table data. Keep 'font' instance unmodified. """
	assert tag in ('glyf', 'loca', 'head')
	assert tag in font
	if tag == 'head':
		origHeadFlags = font['head'].flags
		font['head'].flags |= (1 << 11)
		tableData = font['head'].compile(font)
	if font.sfntVersion in ("\x00\x01\x00\x00", "true"):
		assert {'glyf', 'loca', 'head'}.issubset(font.keys())
		origIndexFormat = font['head'].indexToLocFormat
		if hasattr(font['loca'], 'locations'):
			origLocations = font['loca'].locations[:]
		else:
			origLocations = []
		glyfTable = ttLib.newTable('glyf')
		glyfTable.decompile(font.getTableData('glyf'), font)
		glyfTable.padding = padding
		if tag == 'glyf':
			tableData = glyfTable.compile(font)
		elif tag == 'loca':
			glyfTable.compile(font)
			tableData = font['loca'].compile(font)
		if tag == 'head':
			glyfTable.compile(font)
			font['loca'].compile(font)
			tableData = font['head'].compile(font)
		font['head'].indexToLocFormat = origIndexFormat
		font['loca'].set(origLocations)
	if tag == 'head':
		font['head'].flags = origHeadFlags
	return tableData


def normalise_font(font, padding=4):
	""" Return normalised font data. Keep 'font' instance unmodified. """
	# drop DSIG but keep a copy
	DSIG_copy = copy.deepcopy(font['DSIG'])
	del font['DSIG']
	# ovverride TTFont attributes
	origFlavor = font.flavor
	origRecalcBBoxes = font.recalcBBoxes
	origRecalcTimestamp = font.recalcTimestamp
	origLazy = font.lazy
	font.flavor = None
	font.recalcBBoxes = False
	font.recalcTimestamp = False
	font.lazy = True
	# save font to temporary stream
	infile = BytesIO()
	font.save(infile)
	infile.seek(0)
	# reorder tables alphabetically
	outfile = BytesIO()
	reader = ttLib.sfnt.SFNTReader(infile)
	writer = ttLib.sfnt.SFNTWriter(
		outfile, len(reader.tables), reader.sfntVersion, reader.flavor, reader.flavorData)
	for tag in sorted(reader.keys()):
		if tag in woff2TransformedTableTags + ('head',):
			writer[tag] = normalise_table(font, tag, padding)
		else:
			writer[tag] = reader[tag]
	writer.close()
	# restore font attributes
	font['DSIG'] = DSIG_copy
	font.flavor = origFlavor
	font.recalcBBoxes = origRecalcBBoxes
	font.recalcTimestamp = origRecalcTimestamp
	font.lazy = origLazy
	return outfile.getvalue()


class WOFF2DirectoryEntryTest(unittest.TestCase):

	def setUp(self):
		self.entry = WOFF2DirectoryEntry()

	def test_not_enough_data_table_flags(self):
		with self.assertRaisesRegex(ttLib.TTLibError, "can't read table 'flags'"):
			self.entry.fromString(b"")

	def test_not_enough_data_table_tag(self):
		incompleteData = bytearray([0x3F, 0, 0, 0])
		with self.assertRaisesRegex(ttLib.TTLibError, "can't read table 'tag'"):
			self.entry.fromString(bytes(incompleteData))

	def test_table_reserved_flags(self):
		with self.assertRaisesRegex(ttLib.TTLibError, "bits 6-7 are reserved"):
			self.entry.fromString(bytechr(0xC0))

	def test_loca_zero_transformLength(self):
		data = bytechr(getKnownTagIndex('loca'))  # flags
		data += packBase128(random.randint(1, 100))  # origLength
		data += packBase128(1)  # non-zero transformLength
		with self.assertRaisesRegex(
				ttLib.TTLibError, "transformLength of the 'loca' table must be 0"):
			self.entry.fromString(data)

	def test_fromFile(self):
		unknownTag = Tag('ZZZZ')
		data = bytechr(getKnownTagIndex(unknownTag))
		data += unknownTag.tobytes()
		data += packBase128(random.randint(1, 100))
		expectedPos = len(data)
		f = BytesIO(data + b'\0'*100)
		self.entry.fromFile(f)
		self.assertEqual(f.tell(), expectedPos)

	def test_transformed_toString(self):
		self.entry.tag = Tag('glyf')
		self.entry.flags = getKnownTagIndex(self.entry.tag)
		self.entry.origLength = random.randint(101, 200)
		self.entry.length = random.randint(1, 100)
		expectedSize = (woff2FlagsSize + base128Size(self.entry.origLength) +
			base128Size(self.entry.length))
		data = self.entry.toString()
		self.assertEqual(len(data), expectedSize)

	def test_known_toString(self):
		self.entry.tag = Tag('head')
		self.entry.flags = getKnownTagIndex(self.entry.tag)
		self.entry.origLength = 54
		expectedSize = (woff2FlagsSize + base128Size(self.entry.origLength))
		data = self.entry.toString()
		self.assertEqual(len(data), expectedSize)

	def test_unknown_toString(self):
		self.entry.tag = Tag('ZZZZ')
		self.entry.flags = woff2UnknownTagIndex
		self.entry.origLength = random.randint(1, 100)
		expectedSize = (woff2FlagsSize + woff2UnknownTagSize +
			base128Size(self.entry.origLength))
		data = self.entry.toString()
		self.assertEqual(len(data), expectedSize)


class DummyReader(WOFF2Reader):

	def __init__(self, file, checkChecksums=1, fontNumber=-1):
		self.file = file
		for attr in ('majorVersion', 'minorVersion', 'metaOffset', 'metaLength',
				'metaOrigLength', 'privLength', 'privOffset'):
			setattr(self, attr, 0)


class WOFF2FlavorDataTest(unittest.TestCase):

	@classmethod
	def setUpClass(cls):
		assert os.path.exists(METADATA)
		with open(METADATA, 'rb') as f:
			cls.xml_metadata = f.read()
		cls.compressed_metadata = brotli.compress(cls.xml_metadata, mode=brotli.MODE_TEXT)
		# make random byte strings; font data must be 4-byte aligned
		cls.fontdata = bytes(bytearray(random.sample(range(0, 256), 80)))
		cls.privData = bytes(bytearray(random.sample(range(0, 256), 20)))

	def setUp(self):
		self.file = BytesIO(self.fontdata)
		self.file.seek(0, 2)

	def test_get_metaData_no_privData(self):
		self.file.write(self.compressed_metadata)
		reader = DummyReader(self.file)
		reader.metaOffset = len(self.fontdata)
		reader.metaLength = len(self.compressed_metadata)
		reader.metaOrigLength = len(self.xml_metadata)
		flavorData = WOFF2FlavorData(reader)
		self.assertEqual(self.xml_metadata, flavorData.metaData)

	def test_get_privData_no_metaData(self):
		self.file.write(self.privData)
		reader = DummyReader(self.file)
		reader.privOffset = len(self.fontdata)
		reader.privLength = len(self.privData)
		flavorData = WOFF2FlavorData(reader)
		self.assertEqual(self.privData, flavorData.privData)

	def test_get_metaData_and_privData(self):
		self.file.write(self.compressed_metadata + self.privData)
		reader = DummyReader(self.file)
		reader.metaOffset = len(self.fontdata)
		reader.metaLength = len(self.compressed_metadata)
		reader.metaOrigLength = len(self.xml_metadata)
		reader.privOffset = reader.metaOffset + reader.metaLength
		reader.privLength = len(self.privData)
		flavorData = WOFF2FlavorData(reader)
		self.assertEqual(self.xml_metadata, flavorData.metaData)
		self.assertEqual(self.privData, flavorData.privData)

	def test_get_major_minorVersion(self):
		reader = DummyReader(self.file)
		reader.majorVersion = reader.minorVersion = 1
		flavorData = WOFF2FlavorData(reader)
		self.assertEqual(flavorData.majorVersion, 1)
		self.assertEqual(flavorData.minorVersion, 1)


class WOFF2WriterTest(unittest.TestCase):

	@classmethod
	def setUpClass(cls):
		cls.font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False, flavor="woff2")
		cls.font.importXML(OTX)
		cls.tags = [t for t in cls.font.keys() if t != 'GlyphOrder']
		cls.numTables = len(cls.tags)
		cls.file = BytesIO(CFF_WOFF2.getvalue())
		cls.file.seek(0, 2)
		cls.length = (cls.file.tell() + 3) & ~3
		cls.setUpFlavorData()

	@classmethod
	def setUpFlavorData(cls):
		assert os.path.exists(METADATA)
		with open(METADATA, 'rb') as f:
			cls.xml_metadata = f.read()
		cls.compressed_metadata = brotli.compress(cls.xml_metadata, mode=brotli.MODE_TEXT)
		cls.privData = bytes(bytearray(random.sample(range(0, 256), 20)))

	def setUp(self):
		self.file.seek(0)
		self.writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)

	def test_DSIG_dropped(self):
		self.writer['DSIG'] = b"\0"
		self.assertEqual(len(self.writer.tables), 0)
		self.assertEqual(self.writer.numTables, self.numTables-1)

	def test_no_rewrite_table(self):
		self.writer['ZZZZ'] = b"\0"
		with self.assertRaisesRegex(ttLib.TTLibError, "cannot rewrite"):
			self.writer['ZZZZ'] = b"\0"

	def test_num_tables(self):
		self.writer['ABCD'] = b"\0"
		with self.assertRaisesRegex(ttLib.TTLibError, "wrong number of tables"):
			self.writer.close()

	def test_required_tables(self):
		font = ttLib.TTFont(flavor="woff2")
		with self.assertRaisesRegex(ttLib.TTLibError, "missing required table"):
			font.save(BytesIO())

	def test_head_transform_flag(self):
		headData = self.font.getTableData('head')
		origFlags = byteord(headData[16])
		woff2font = ttLib.TTFont(self.file)
		newHeadData = woff2font.getTableData('head')
		modifiedFlags = byteord(newHeadData[16])
		self.assertNotEqual(origFlags, modifiedFlags)
		restoredFlags = modifiedFlags & ~0x08  # turn off bit 11
		self.assertEqual(origFlags, restoredFlags)

	def test_tables_sorted_alphabetically(self):
		expected = sorted([t for t in self.tags if t != 'DSIG'])
		woff2font = ttLib.TTFont(self.file)
		self.assertEqual(expected, list(woff2font.reader.keys()))

	def test_checksums(self):
		normFile = BytesIO(normalise_font(self.font, padding=4))
		normFile.seek(0)
		normFont = ttLib.TTFont(normFile, checkChecksums=2)
		w2font = ttLib.TTFont(self.file)
		# force reconstructing glyf table using 4-byte padding
		w2font.reader.padding = 4
		for tag in [t for t in self.tags if t != 'DSIG']:
			w2data = w2font.reader[tag]
			normData = normFont.reader[tag]
			if tag == "head":
				w2data = w2data[:8] + b'\0\0\0\0' + w2data[12:]
				normData = normData[:8] + b'\0\0\0\0' + normData[12:]
			w2CheckSum = ttLib.sfnt.calcChecksum(w2data)
			normCheckSum = ttLib.sfnt.calcChecksum(normData)
			self.assertEqual(w2CheckSum, normCheckSum)
		normCheckSumAdjustment = normFont['head'].checkSumAdjustment
		self.assertEqual(normCheckSumAdjustment, w2font['head'].checkSumAdjustment)

	def test_calcSFNTChecksumsLengthsAndOffsets(self):
		normFont = ttLib.TTFont(BytesIO(normalise_font(self.font, padding=4)))
		for tag in self.tags:
			self.writer[tag] = self.font.getTableData(tag)
		self.writer._normaliseGlyfAndLoca(padding=4)
		self.writer._setHeadTransformFlag()
		self.writer.tables = OrderedDict(sorted(self.writer.tables.items()))
		self.writer._calcSFNTChecksumsLengthsAndOffsets()
		for tag, entry in normFont.reader.tables.items():
			self.assertEqual(entry.offset, self.writer.tables[tag].origOffset)
			self.assertEqual(entry.length, self.writer.tables[tag].origLength)
			self.assertEqual(entry.checkSum, self.writer.tables[tag].checkSum)

	def test_bad_sfntVersion(self):
		for i in range(self.numTables):
			self.writer[bytechr(65 + i)*4] = b"\0"
		self.writer.sfntVersion = 'ZZZZ'
		with self.assertRaisesRegex(ttLib.TTLibError, "bad sfntVersion"):
			self.writer.close()

	def test_calcTotalSize_no_flavorData(self):
		expected = self.length
		self.writer.file = BytesIO()
		for tag in self.tags:
			self.writer[tag] = self.font.getTableData(tag)
		self.writer.close()
		self.assertEqual(expected, self.writer.length)
		self.assertEqual(expected, self.writer.file.tell())

	def test_calcTotalSize_with_metaData(self):
		expected = self.length + len(self.compressed_metadata)
		flavorData = self.writer.flavorData = WOFF2FlavorData()
		flavorData.metaData = self.xml_metadata
		self.writer.file = BytesIO()
		for tag in self.tags:
			self.writer[tag] = self.font.getTableData(tag)
		self.writer.close()
		self.assertEqual(expected, self.writer.length)
		self.assertEqual(expected, self.writer.file.tell())

	def test_calcTotalSize_with_privData(self):
		expected = self.length + len(self.privData)
		flavorData = self.writer.flavorData = WOFF2FlavorData()
		flavorData.privData = self.privData
		self.writer.file = BytesIO()
		for tag in self.tags:
			self.writer[tag] = self.font.getTableData(tag)
		self.writer.close()
		self.assertEqual(expected, self.writer.length)
		self.assertEqual(expected, self.writer.file.tell())

	def test_calcTotalSize_with_metaData_and_privData(self):
		metaDataLength = (len(self.compressed_metadata) + 3) & ~3
		expected = self.length + metaDataLength + len(self.privData)
		flavorData = self.writer.flavorData = WOFF2FlavorData()
		flavorData.metaData = self.xml_metadata
		flavorData.privData = self.privData
		self.writer.file = BytesIO()
		for tag in self.tags:
			self.writer[tag] = self.font.getTableData(tag)
		self.writer.close()
		self.assertEqual(expected, self.writer.length)
		self.assertEqual(expected, self.writer.file.tell())

	def test_getVersion(self):
		# no version
		self.assertEqual((0, 0), self.writer._getVersion())
		# version from head.fontRevision
		fontRevision = self.font['head'].fontRevision
		versionTuple = tuple(int(i) for i in str(fontRevision).split("."))
		entry = self.writer.tables['head'] = ttLib.newTable('head')
		entry.data = self.font.getTableData('head')
		self.assertEqual(versionTuple, self.writer._getVersion())
		# version from writer.flavorData
		flavorData = self.writer.flavorData = WOFF2FlavorData()
		flavorData.majorVersion, flavorData.minorVersion = (10, 11)
		self.assertEqual((10, 11), self.writer._getVersion())


class WOFF2WriterTTFTest(WOFF2WriterTest):

	@classmethod
	def setUpClass(cls):
		cls.font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False, flavor="woff2")
		cls.font.importXML(TTX)
		cls.tags = [t for t in cls.font.keys() if t != 'GlyphOrder']
		cls.numTables = len(cls.tags)
		cls.file = BytesIO(TT_WOFF2.getvalue())
		cls.file.seek(0, 2)
		cls.length = (cls.file.tell() + 3) & ~3
		cls.setUpFlavorData()

	def test_normaliseGlyfAndLoca(self):
		normTables = {}
		for tag in ('head', 'loca', 'glyf'):
			normTables[tag] = normalise_table(self.font, tag, padding=4)
		for tag in self.tags:
			tableData = self.font.getTableData(tag)
			self.writer[tag] = tableData
			if tag in normTables:
				self.assertNotEqual(tableData, normTables[tag])
		self.writer._normaliseGlyfAndLoca(padding=4)
		self.writer._setHeadTransformFlag()
		for tag in normTables:
			self.assertEqual(self.writer.tables[tag].data, normTables[tag])


class WOFF2LocaTableTest(unittest.TestCase):

	def setUp(self):
		self.font = font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
		font['head'] = ttLib.newTable('head')
		font['loca'] = WOFF2LocaTable()
		font['glyf'] = WOFF2GlyfTable()

	def test_compile_short_loca(self):
		locaTable = self.font['loca']
		locaTable.set(list(range(0, 0x20000, 2)))
		self.font['glyf'].indexFormat = 0
		locaData = locaTable.compile(self.font)
		self.assertEqual(len(locaData), 0x20000)

	def test_compile_short_loca_overflow(self):
		locaTable = self.font['loca']
		locaTable.set(list(range(0x20000 + 1)))
		self.font['glyf'].indexFormat = 0
		with self.assertRaisesRegex(
				ttLib.TTLibError, "indexFormat is 0 but local offsets > 0x20000"):
			locaTable.compile(self.font)

	def test_compile_short_loca_not_multiples_of_2(self):
		locaTable = self.font['loca']
		locaTable.set([1, 3, 5, 7])
		self.font['glyf'].indexFormat = 0
		with self.assertRaisesRegex(ttLib.TTLibError, "offsets not multiples of 2"):
			locaTable.compile(self.font)

	def test_compile_long_loca(self):
		locaTable = self.font['loca']
		locaTable.set(list(range(0x20001)))
		self.font['glyf'].indexFormat = 1
		locaData = locaTable.compile(self.font)
		self.assertEqual(len(locaData), 0x20001 * 4)

	def test_compile_set_indexToLocFormat_0(self):
		locaTable = self.font['loca']
		# offsets are all multiples of 2 and max length is < 0x10000
		locaTable.set(list(range(0, 0x20000, 2)))
		locaTable.compile(self.font)
		newIndexFormat = self.font['head'].indexToLocFormat
		self.assertEqual(0, newIndexFormat)

	def test_compile_set_indexToLocFormat_1(self):
		locaTable = self.font['loca']
		# offsets are not multiples of 2
		locaTable.set(list(range(10)))
		locaTable.compile(self.font)
		newIndexFormat = self.font['head'].indexToLocFormat
		self.assertEqual(1, newIndexFormat)
		# max length is >= 0x10000
		locaTable.set(list(range(0, 0x20000 + 1, 2)))
		locaTable.compile(self.font)
		newIndexFormat = self.font['head'].indexToLocFormat
		self.assertEqual(1, newIndexFormat)


class WOFF2GlyfTableTest(unittest.TestCase):

	@classmethod
	def setUpClass(cls):
		font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
		font.importXML(TTX)
		cls.tables = {}
		cls.transformedTags = ('maxp', 'head', 'loca', 'glyf')
		for tag in reversed(cls.transformedTags):  # compile in inverse order
			cls.tables[tag] = font.getTableData(tag)
		infile = BytesIO(TT_WOFF2.getvalue())
		reader = WOFF2Reader(infile)
		cls.transformedGlyfData = reader.tables['glyf'].loadData(
			reader.transformBuffer)
		cls.glyphOrder = ['.notdef'] + ["glyph%.5d" % i for i in range(1, font['maxp'].numGlyphs)]

	def setUp(self):
		self.font = font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
		font.setGlyphOrder(self.glyphOrder)
		font['head'] = ttLib.newTable('head')
		font['maxp'] = ttLib.newTable('maxp')
		font['loca'] = WOFF2LocaTable()
		font['glyf'] = WOFF2GlyfTable()
		for tag in self.transformedTags:
			font[tag].decompile(self.tables[tag], font)

	def test_reconstruct_glyf_padded_4(self):
		glyfTable = WOFF2GlyfTable()
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		glyfTable.padding = 4
		data = glyfTable.compile(self.font)
		normGlyfData = normalise_table(self.font, 'glyf', glyfTable.padding)
		self.assertEqual(normGlyfData, data)

	def test_reconstruct_glyf_padded_2(self):
		glyfTable = WOFF2GlyfTable()
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		glyfTable.padding = 2
		data = glyfTable.compile(self.font)
		normGlyfData = normalise_table(self.font, 'glyf', glyfTable.padding)
		self.assertEqual(normGlyfData, data)

	def test_reconstruct_glyf_unpadded(self):
		glyfTable = WOFF2GlyfTable()
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		data = glyfTable.compile(self.font)
		self.assertEqual(self.tables['glyf'], data)

	def test_reconstruct_glyf_incorrect_glyphOrder(self):
		glyfTable = WOFF2GlyfTable()
		badGlyphOrder = self.font.getGlyphOrder()[:-1]
		self.font.setGlyphOrder(badGlyphOrder)
		with self.assertRaisesRegex(ttLib.TTLibError, "incorrect glyphOrder"):
			glyfTable.reconstruct(self.transformedGlyfData, self.font)

	def test_reconstruct_glyf_missing_glyphOrder(self):
		glyfTable = WOFF2GlyfTable()
		del self.font.glyphOrder
		numGlyphs = self.font['maxp'].numGlyphs
		del self.font['maxp']
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		expected = [".notdef"]
		expected.extend(["glyph%.5d" % i for i in range(1, numGlyphs)])
		self.assertEqual(expected, glyfTable.glyphOrder)

	def test_reconstruct_loca_padded_4(self):
		locaTable = self.font['loca'] = WOFF2LocaTable()
		glyfTable = self.font['glyf'] = WOFF2GlyfTable()
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		glyfTable.padding = 4
		glyfTable.compile(self.font)
		data = locaTable.compile(self.font)
		normLocaData = normalise_table(self.font, 'loca', glyfTable.padding)
		self.assertEqual(normLocaData, data)

	def test_reconstruct_loca_padded_2(self):
		locaTable = self.font['loca'] = WOFF2LocaTable()
		glyfTable = self.font['glyf'] = WOFF2GlyfTable()
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		glyfTable.padding = 2
		glyfTable.compile(self.font)
		data = locaTable.compile(self.font)
		normLocaData = normalise_table(self.font, 'loca', glyfTable.padding)
		self.assertEqual(normLocaData, data)

	def test_reconstruct_loca_unpadded(self):
		locaTable = self.font['loca'] = WOFF2LocaTable()
		glyfTable = self.font['glyf'] = WOFF2GlyfTable()
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		glyfTable.compile(self.font)
		data = locaTable.compile(self.font)
		self.assertEqual(self.tables['loca'], data)

	def test_reconstruct_glyf_header_not_enough_data(self):
		with self.assertRaisesRegex(ttLib.TTLibError, "not enough 'glyf' data"):
			WOFF2GlyfTable().reconstruct(b"", self.font)

	def test_reconstruct_glyf_table_incorrect_size(self):
		msg = "incorrect size of transformed 'glyf'"
		with self.assertRaisesRegex(ttLib.TTLibError, msg):
			WOFF2GlyfTable().reconstruct(self.transformedGlyfData + b"\x00", self.font)
		with self.assertRaisesRegex(ttLib.TTLibError, msg):
			WOFF2GlyfTable().reconstruct(self.transformedGlyfData[:-1], self.font)

	def test_transform_glyf(self):
		glyfTable = self.font['glyf']
		data = glyfTable.transform(self.font)
		self.assertEqual(self.transformedGlyfData, data)

	def test_transform_glyf_incorrect_glyphOrder(self):
		glyfTable = self.font['glyf']
		badGlyphOrder = self.font.getGlyphOrder()[:-1]
		del glyfTable.glyphOrder
		self.font.setGlyphOrder(badGlyphOrder)
		with self.assertRaisesRegex(ttLib.TTLibError, "incorrect glyphOrder"):
			glyfTable.transform(self.font)
		glyfTable.glyphOrder = badGlyphOrder
		with self.assertRaisesRegex(ttLib.TTLibError, "incorrect glyphOrder"):
			glyfTable.transform(self.font)

	def test_transform_glyf_missing_glyphOrder(self):
		glyfTable = self.font['glyf']
		del glyfTable.glyphOrder
		del self.font.glyphOrder
		numGlyphs = self.font['maxp'].numGlyphs
		del self.font['maxp']
		glyfTable.transform(self.font)
		expected = [".notdef"]
		expected.extend(["glyph%.5d" % i for i in range(1, numGlyphs)])
		self.assertEqual(expected, glyfTable.glyphOrder)

	def test_roundtrip_glyf_reconstruct_and_transform(self):
		glyfTable = WOFF2GlyfTable()
		glyfTable.reconstruct(self.transformedGlyfData, self.font)
		data = glyfTable.transform(self.font)
		self.assertEqual(self.transformedGlyfData, data)

	def test_roundtrip_glyf_transform_and_reconstruct(self):
		glyfTable = self.font['glyf']
		transformedData = glyfTable.transform(self.font)
		newGlyfTable = WOFF2GlyfTable()
		newGlyfTable.reconstruct(transformedData, self.font)
		newGlyfTable.padding = 4
		reconstructedData = newGlyfTable.compile(self.font)
		normGlyfData = normalise_table(self.font, 'glyf', newGlyfTable.padding)
		self.assertEqual(normGlyfData, reconstructedData)


if __name__ == "__main__":
	import sys
	sys.exit(unittest.main())
