from __future__ import print_function, division, absolute_import, unicode_literals
from fontTools.misc.py23 import *
from fontTools import ttLib
from fontTools.ttLib import woff2
from fontTools.ttLib.woff2 import (
	WOFF2Reader, woff2DirectorySize, woff2DirectoryFormat,
	woff2FlagsSize, woff2UnknownTagSize, woff2Base128MaxSize, WOFF2DirectoryEntry,
	getKnownTagIndex, packBase128, base128Size, woff2UnknownTagIndex,
	WOFF2FlavorData, woff2TransformedTableTags, WOFF2GlyfTable, WOFF2LocaTable,
	WOFF2HmtxTable, WOFF2Writer, unpackBase128, unpack255UShort, pack255UShort)
import unittest
from fontTools.misc import sstruct
from fontTools import fontBuilder
from fontTools.pens.ttGlyphPen import TTGlyphPen
import struct
import os
import random
import copy
from collections import OrderedDict
from functools import partial
import pytest

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, 'data')
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('head')


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.font.getTableData("glyf")  # 'glyf' needs to be compiled before '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_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)

	def test_glyf_loca_transform_flags(self):
		for tag in ("glyf", "loca"):
			entry = WOFF2DirectoryEntry()
			entry.tag = Tag(tag)
			entry.flags = getKnownTagIndex(entry.tag)

			self.assertEqual(entry.transformVersion, 0)
			self.assertTrue(entry.transformed)

			entry.transformed = False

			self.assertEqual(entry.transformVersion, 3)
			self.assertEqual(entry.flags & 0b11000000, (3 << 6))
			self.assertFalse(entry.transformed)

	def test_other_transform_flags(self):
		entry = WOFF2DirectoryEntry()
		entry.tag = Tag('ZZZZ')
		entry.flags = woff2UnknownTagIndex

		self.assertEqual(entry.transformVersion, 0)
		self.assertFalse(entry.transformed)

		entry.transformed = True

		self.assertEqual(entry.transformVersion, 1)
		self.assertEqual(entry.flags & 0b11000000, (1 << 6))
		self.assertTrue(entry.transformed)


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)
		self.tables = {}


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)

	def test_mutually_exclusive_args(self):
		msg = "arguments are mutually exclusive"
		reader = DummyReader(self.file)
		with self.assertRaisesRegex(TypeError, msg):
			WOFF2FlavorData(reader, transformedTables={"hmtx"})
		with self.assertRaisesRegex(TypeError, msg):
			WOFF2FlavorData(reader, data=WOFF2FlavorData())

	def test_transformedTables_default(self):
		flavorData = WOFF2FlavorData()
		self.assertEqual(flavorData.transformedTables, set(woff2TransformedTableTags))

	def test_transformedTables_invalid(self):
		msg = r"'glyf' and 'loca' must be transformed \(or not\) together"

		with self.assertRaisesRegex(ValueError, msg):
			WOFF2FlavorData(transformedTables={"glyf"})

		with self.assertRaisesRegex(ValueError, msg):
			WOFF2FlavorData(transformedTables={"loca"})


class WOFF2WriterTest(unittest.TestCase):

	@classmethod
	def setUpClass(cls):
		cls.font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False, flavor="woff2")
		cls.font.importXML(OTX)
		cls.tags = sorted(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())

	def test_hmtx_trasform(self):
		tableTransforms = {"glyf", "loca", "hmtx"}

		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=tableTransforms)

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		# enabling hmtx transform has no effect when font has no glyf table
		self.assertEqual(writer.file.getvalue(), CFF_WOFF2.getvalue())

	def test_no_transforms(self):
		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=())

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		# transforms settings have no effect when font is CFF-flavored, since
		# all the current transforms only apply to TrueType-flavored fonts.
		self.assertEqual(writer.file.getvalue(), CFF_WOFF2.getvalue())

class WOFF2WriterTTFTest(WOFF2WriterTest):

	@classmethod
	def setUpClass(cls):
		cls.font = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False, flavor="woff2")
		cls.font.importXML(TTX)
		cls.tags = sorted(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])

	def test_hmtx_trasform(self):
		tableTransforms = {"glyf", "loca", "hmtx"}

		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=tableTransforms)

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		length = len(writer.file.getvalue())

		# enabling optional hmtx transform shaves off a few bytes
		self.assertLess(length, len(TT_WOFF2.getvalue()))

	def test_no_transforms(self):
		writer = WOFF2Writer(BytesIO(), self.numTables, self.font.sfntVersion)
		writer.flavorData = WOFF2FlavorData(transformedTables=())

		for tag in self.tags:
			writer[tag] = self.font.getTableData(tag)
		writer.close()

		self.assertNotEqual(writer.file.getvalue(), TT_WOFF2.getvalue())

		writer.file.seek(0)
		reader = WOFF2Reader(writer.file)
		self.assertEqual(len(reader.flavorData.transformedTables), 0)


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_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)


@pytest.fixture(scope="module")
def fontfile():

	class Glyph(object):
		def __init__(self, empty=False, **kwargs):
			if not empty:
				self.draw = partial(self.drawRect, **kwargs)
			else:
				self.draw = lambda pen: None

		@staticmethod
		def drawRect(pen, xMin, xMax):
			pen.moveTo((xMin, 0))
			pen.lineTo((xMin, 1000))
			pen.lineTo((xMax, 1000))
			pen.lineTo((xMax, 0))
			pen.closePath()

	class CompositeGlyph(object):
		def __init__(self, components):
			self.components = components

		def draw(self, pen):
			for baseGlyph, (offsetX, offsetY) in self.components:
				pen.addComponent(baseGlyph, (1, 0, 0, 1, offsetX, offsetY))

	fb = fontBuilder.FontBuilder(unitsPerEm=1000, isTTF=True)
	fb.setupGlyphOrder(
		[".notdef", "space", "A", "acutecomb", "Aacute", "zero", "one", "two"]
	)
	fb.setupCharacterMap(
		{
			0x20: "space",
			0x41: "A",
			0x0301: "acutecomb",
			0xC1: "Aacute",
			0x30: "zero",
			0x31: "one",
			0x32: "two",
		}
	)
	fb.setupHorizontalMetrics(
		{
			".notdef": (500, 50),
			"space": (600, 0),
			"A": (550, 40),
			"acutecomb": (0, -40),
			"Aacute": (550, 40),
			"zero": (500, 30),
			"one": (500, 50),
			"two": (500, 40),
		}
	)
	fb.setupHorizontalHeader(ascent=1000, descent=-200)

	srcGlyphs = {
		".notdef": Glyph(xMin=50, xMax=450),
		"space": Glyph(empty=True),
		"A": Glyph(xMin=40, xMax=510),
		"acutecomb": Glyph(xMin=-40, xMax=60),
		"Aacute": CompositeGlyph([("A", (0, 0)), ("acutecomb", (200, 0))]),
		"zero": Glyph(xMin=30, xMax=470),
		"one": Glyph(xMin=50, xMax=450),
		"two": Glyph(xMin=40, xMax=460),
	}
	pen = TTGlyphPen(srcGlyphs)
	glyphSet = {}
	for glyphName, glyph in srcGlyphs.items():
		glyph.draw(pen)
		glyphSet[glyphName] = pen.glyph()
	fb.setupGlyf(glyphSet)

	fb.setupNameTable(
		{
			"familyName": "TestWOFF2",
			"styleName": "Regular",
			"uniqueFontIdentifier": "TestWOFF2 Regular; Version 1.000; ABCD",
			"fullName": "TestWOFF2 Regular",
			"version": "Version 1.000",
			"psName": "TestWOFF2-Regular",
		}
	)
	fb.setupOS2()
	fb.setupPost()

	buf = BytesIO()
	fb.save(buf)
	buf.seek(0)

	assert fb.font["maxp"].numGlyphs == 8
	assert fb.font["hhea"].numberOfHMetrics == 6
	for glyphName in fb.font.getGlyphOrder():
		xMin = getattr(fb.font["glyf"][glyphName], "xMin", 0)
		assert xMin == fb.font["hmtx"][glyphName][1]

	return buf


@pytest.fixture
def ttFont(fontfile):
	return ttLib.TTFont(fontfile, recalcBBoxes=False, recalcTimestamp=False)


class WOFF2HmtxTableTest(object):
	def test_transform_no_sidebearings(self, ttFont):
		hmtxTable = WOFF2HmtxTable()
		hmtxTable.metrics = ttFont["hmtx"].metrics

		data = hmtxTable.transform(ttFont)

		assert data == (
			b"\x03"  # 00000011 | bits 0 and 1 are set (no sidebearings arrays)

			# advanceWidthArray
			b'\x01\xf4'  # .notdef: 500
			b'\x02X'     # space: 600
			b'\x02&'     # A: 550
			b'\x00\x00'  # acutecomb: 0
			b'\x02&'     # Aacute: 550
			b'\x01\xf4'  # zero: 500
		)

	def test_transform_proportional_sidebearings(self, ttFont):
		hmtxTable = WOFF2HmtxTable()
		metrics = ttFont["hmtx"].metrics
		# force one of the proportional glyphs to have its left sidebearing be
		# different from its xMin (40)
		metrics["A"] = (550, 39)
		hmtxTable.metrics = metrics

		assert ttFont["glyf"]["A"].xMin != metrics["A"][1]

		data = hmtxTable.transform(ttFont)

		assert data == (
			b"\x02"  # 00000010 | bits 0 unset: explicit proportional sidebearings

			# advanceWidthArray
			b'\x01\xf4'  # .notdef: 500
			b'\x02X'     # space: 600
			b'\x02&'     # A: 550
			b'\x00\x00'  # acutecomb: 0
			b'\x02&'     # Aacute: 550
			b'\x01\xf4'  # zero: 500

			# lsbArray
			b'\x002'     # .notdef: 50
			b'\x00\x00'  # space: 0
			b"\x00'"     # A: 39 (xMin: 40)
			b'\xff\xd8'  # acutecomb: -40
			b'\x00('     # Aacute: 40
			b'\x00\x1e'  # zero: 30
		)

	def test_transform_monospaced_sidebearings(self, ttFont):
		hmtxTable = WOFF2HmtxTable()
		metrics = ttFont["hmtx"].metrics
		hmtxTable.metrics = metrics

		# force one of the monospaced glyphs at the end of hmtx table to have
		# its xMin different from its left sidebearing (50)
		ttFont["glyf"]["one"].xMin = metrics["one"][1] + 1

		data = hmtxTable.transform(ttFont)

		assert data == (
			b"\x01"  # 00000001 | bits 1 unset: explicit monospaced sidebearings

			# advanceWidthArray
			b'\x01\xf4'  # .notdef: 500
			b'\x02X'     # space: 600
			b'\x02&'     # A: 550
			b'\x00\x00'  # acutecomb: 0
			b'\x02&'     # Aacute: 550
			b'\x01\xf4'  # zero: 500

			# leftSideBearingArray
			b'\x002'     # one: 50 (xMin: 51)
			b'\x00('     # two: 40
		)

	def test_transform_not_applicable(self, ttFont):
		hmtxTable = WOFF2HmtxTable()
		metrics = ttFont["hmtx"].metrics
		# force both a proportional and monospaced glyph to have sidebearings
		# different from the respective xMin coordinates
		metrics["A"] = (550, 39)
		metrics["one"] = (500, 51)
		hmtxTable.metrics = metrics

		# 'None' signals to fall back using untransformed hmtx table data
		assert hmtxTable.transform(ttFont) is None

	def test_reconstruct_no_sidebearings(self, ttFont):
		hmtxTable = WOFF2HmtxTable()

		data = (
			b"\x03"  # 00000011 | bits 0 and 1 are set (no sidebearings arrays)

			# advanceWidthArray
			b'\x01\xf4'  # .notdef: 500
			b'\x02X'     # space: 600
			b'\x02&'     # A: 550
			b'\x00\x00'  # acutecomb: 0
			b'\x02&'     # Aacute: 550
			b'\x01\xf4'  # zero: 500
		)

		hmtxTable.reconstruct(data, ttFont)

		assert hmtxTable.metrics == {
			".notdef": (500, 50),
			"space": (600, 0),
			"A": (550, 40),
			"acutecomb": (0, -40),
			"Aacute": (550, 40),
			"zero": (500, 30),
			"one": (500, 50),
			"two": (500, 40),
		}

	def test_reconstruct_proportional_sidebearings(self, ttFont):
		hmtxTable = WOFF2HmtxTable()

		data = (
			b"\x02"  # 00000010 | bits 0 unset: explicit proportional sidebearings

			# advanceWidthArray
			b'\x01\xf4'  # .notdef: 500
			b'\x02X'     # space: 600
			b'\x02&'     # A: 550
			b'\x00\x00'  # acutecomb: 0
			b'\x02&'     # Aacute: 550
			b'\x01\xf4'  # zero: 500

			# lsbArray
			b'\x002'     # .notdef: 50
			b'\x00\x00'  # space: 0
			b"\x00'"     # A: 39 (xMin: 40)
			b'\xff\xd8'  # acutecomb: -40
			b'\x00('     # Aacute: 40
			b'\x00\x1e'  # zero: 30
		)

		hmtxTable.reconstruct(data, ttFont)

		assert hmtxTable.metrics == {
			".notdef": (500, 50),
			"space": (600, 0),
			"A": (550, 39),
			"acutecomb": (0, -40),
			"Aacute": (550, 40),
			"zero": (500, 30),
			"one": (500, 50),
			"two": (500, 40),
		}

		assert ttFont["glyf"]["A"].xMin == 40

	def test_reconstruct_monospaced_sidebearings(self, ttFont):
		hmtxTable = WOFF2HmtxTable()

		data = (
			b"\x01"  # 00000001 | bits 1 unset: explicit monospaced sidebearings

			# advanceWidthArray
			b'\x01\xf4'  # .notdef: 500
			b'\x02X'     # space: 600
			b'\x02&'     # A: 550
			b'\x00\x00'  # acutecomb: 0
			b'\x02&'     # Aacute: 550
			b'\x01\xf4'  # zero: 500

			# leftSideBearingArray
			b'\x003'     # one: 51 (xMin: 50)
			b'\x00('     # two: 40
		)

		hmtxTable.reconstruct(data, ttFont)

		assert hmtxTable.metrics == {
			".notdef": (500, 50),
			"space": (600, 0),
			"A": (550, 40),
			"acutecomb": (0, -40),
			"Aacute": (550, 40),
			"zero": (500, 30),
			"one": (500, 51),
			"two": (500, 40),
		}

		assert ttFont["glyf"]["one"].xMin == 50

	def test_reconstruct_flags_reserved_bits(self):
		hmtxTable = WOFF2HmtxTable()

		with pytest.raises(
			ttLib.TTLibError, match="Bits 2-7 of 'hmtx' flags are reserved"
		):
			hmtxTable.reconstruct(b"\xFF", ttFont=None)

	def test_reconstruct_flags_required_bits(self):
		hmtxTable = WOFF2HmtxTable()

		with pytest.raises(ttLib.TTLibError, match="either bits 0 or 1 .* must set"):
			hmtxTable.reconstruct(b"\x00", ttFont=None)

	def test_reconstruct_too_much_data(self, ttFont):
		ttFont["hhea"].numberOfHMetrics = 2
		data = b'\x03\x01\xf4\x02X\x02&'
		hmtxTable = WOFF2HmtxTable()

		with pytest.raises(ttLib.TTLibError, match="too much 'hmtx' table data"):
			hmtxTable.reconstruct(data, ttFont)


class WOFF2RoundtripTest(object):
	@staticmethod
	def roundtrip(infile):
		infile.seek(0)
		ttFont = ttLib.TTFont(infile, recalcBBoxes=False, recalcTimestamp=False)
		outfile = BytesIO()
		ttFont.save(outfile)
		return outfile, ttFont

	def test_roundtrip_default_transforms(self, ttFont):
		ttFont.flavor = "woff2"
		# ttFont.flavorData = None
		tmp = BytesIO()
		ttFont.save(tmp)

		tmp2, ttFont2 = self.roundtrip(tmp)

		assert tmp.getvalue() == tmp2.getvalue()
		assert ttFont2.reader.flavorData.transformedTables == {"glyf", "loca"}

	def test_roundtrip_no_transforms(self, ttFont):
		ttFont.flavor = "woff2"
		ttFont.flavorData = WOFF2FlavorData(transformedTables=[])
		tmp = BytesIO()
		ttFont.save(tmp)

		tmp2, ttFont2 = self.roundtrip(tmp)

		assert tmp.getvalue() == tmp2.getvalue()
		assert not ttFont2.reader.flavorData.transformedTables

	def test_roundtrip_all_transforms(self, ttFont):
		ttFont.flavor = "woff2"
		ttFont.flavorData = WOFF2FlavorData(transformedTables=["glyf", "loca", "hmtx"])
		tmp = BytesIO()
		ttFont.save(tmp)

		tmp2, ttFont2 = self.roundtrip(tmp)

		assert tmp.getvalue() == tmp2.getvalue()
		assert ttFont2.reader.flavorData.transformedTables == {"glyf", "loca", "hmtx"}

	def test_roundtrip_only_hmtx_no_glyf_transform(self, ttFont):
		ttFont.flavor = "woff2"
		ttFont.flavorData = WOFF2FlavorData(transformedTables=["hmtx"])
		tmp = BytesIO()
		ttFont.save(tmp)

		tmp2, ttFont2 = self.roundtrip(tmp)

		assert tmp.getvalue() == tmp2.getvalue()
		assert ttFont2.reader.flavorData.transformedTables == {"hmtx"}


class MainTest(object):

	@staticmethod
	def make_ttf(tmpdir):
		ttFont = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
		ttFont.importXML(TTX)
		filename = str(tmpdir / "TestTTF-Regular.ttf")
		ttFont.save(filename)
		return filename

	def test_compress_ttf(self, tmpdir):
		input_file = self.make_ttf(tmpdir)

		assert woff2.main(["compress", input_file]) is None

		assert (tmpdir / "TestTTF-Regular.woff2").check(file=True)

	def test_compress_ttf_no_glyf_transform(self, tmpdir):
		input_file = self.make_ttf(tmpdir)

		assert woff2.main(["compress", "--no-glyf-transform", input_file]) is None

		assert (tmpdir / "TestTTF-Regular.woff2").check(file=True)

	def test_compress_ttf_hmtx_transform(self, tmpdir):
		input_file = self.make_ttf(tmpdir)

		assert woff2.main(["compress", "--hmtx-transform", input_file]) is None

		assert (tmpdir / "TestTTF-Regular.woff2").check(file=True)

	def test_compress_ttf_no_glyf_transform_hmtx_transform(self, tmpdir):
		input_file = self.make_ttf(tmpdir)

		assert woff2.main(
			["compress", "--no-glyf-transform", "--hmtx-transform", input_file]
		) is None

		assert (tmpdir / "TestTTF-Regular.woff2").check(file=True)

	def test_compress_output_file(self, tmpdir):
		input_file = self.make_ttf(tmpdir)
		output_file = tmpdir / "TestTTF.woff2"

		assert woff2.main(
			["compress", "-o", str(output_file), str(input_file)]
		) is None

		assert output_file.check(file=True)

	def test_compress_otf(self, tmpdir):
		ttFont = ttLib.TTFont(recalcBBoxes=False, recalcTimestamp=False)
		ttFont.importXML(OTX)
		input_file = str(tmpdir / "TestOTF-Regular.otf")
		ttFont.save(input_file)

		assert woff2.main(["compress", input_file]) is None

		assert (tmpdir / "TestOTF-Regular.woff2").check(file=True)

	def test_recompress_woff2_keeps_flavorData(self, tmpdir):
		woff2_font = ttLib.TTFont(BytesIO(TT_WOFF2.getvalue()))
		woff2_font.flavorData.privData = b"FOOBAR"
		woff2_file = tmpdir / "TestTTF-Regular.woff2"
		woff2_font.save(str(woff2_file))

		assert woff2_font.flavorData.transformedTables == {"glyf", "loca"}

		woff2.main(["compress", "--hmtx-transform", str(woff2_file)])

		output_file = tmpdir / "TestTTF-Regular#1.woff2"
		assert output_file.check(file=True)

		new_woff2_font = ttLib.TTFont(str(output_file))

		assert new_woff2_font.flavorData.transformedTables == {"glyf", "loca", "hmtx"}
		assert new_woff2_font.flavorData.privData == b"FOOBAR"

	def test_decompress_ttf(self, tmpdir):
		input_file = tmpdir / "TestTTF-Regular.woff2"
		input_file.write_binary(TT_WOFF2.getvalue())

		assert woff2.main(["decompress", str(input_file)]) is None

		assert (tmpdir / "TestTTF-Regular.ttf").check(file=True)

	def test_decompress_otf(self, tmpdir):
		input_file = tmpdir / "TestTTF-Regular.woff2"
		input_file.write_binary(CFF_WOFF2.getvalue())

		assert woff2.main(["decompress", str(input_file)]) is None

		assert (tmpdir / "TestTTF-Regular.otf").check(file=True)

	def test_decompress_output_file(self, tmpdir):
		input_file = tmpdir / "TestTTF-Regular.woff2"
		input_file.write_binary(TT_WOFF2.getvalue())
		output_file = tmpdir / "TestTTF.ttf"

		assert woff2.main(
			["decompress", "-o", str(output_file), str(input_file)]
		) is None

		assert output_file.check(file=True)

	def test_no_subcommand_show_help(self, capsys):
		with pytest.raises(SystemExit):
			woff2.main(["--help"])

		captured = capsys.readouterr()
		assert "usage: fonttools ttLib.woff2" in captured.out


class Base128Test(unittest.TestCase):

	def test_unpackBase128(self):
		self.assertEqual(unpackBase128(b'\x3f\x00\x00'), (63, b"\x00\x00"))
		self.assertEqual(unpackBase128(b'\x8f\xff\xff\xff\x7f')[0], 4294967295)

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"UIntBase128 value must not start with leading zeros",
			unpackBase128, b'\x80\x80\x3f')

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"UIntBase128-encoded sequence is longer than 5 bytes",
			unpackBase128, b'\x8f\xff\xff\xff\xff\x7f')

		self.assertRaisesRegex(
			ttLib.TTLibError,
			r"UIntBase128 value exceeds 2\*\*32-1",
			unpackBase128, b'\x90\x80\x80\x80\x00')

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"not enough data to unpack UIntBase128",
			unpackBase128, b'')

	def test_base128Size(self):
		self.assertEqual(base128Size(0), 1)
		self.assertEqual(base128Size(24567), 3)
		self.assertEqual(base128Size(2**32-1), 5)

	def test_packBase128(self):
		self.assertEqual(packBase128(63), b"\x3f")
		self.assertEqual(packBase128(2**32-1), b'\x8f\xff\xff\xff\x7f')
		self.assertRaisesRegex(
			ttLib.TTLibError,
			r"UIntBase128 format requires 0 <= integer <= 2\*\*32-1",
			packBase128, 2**32+1)
		self.assertRaisesRegex(
			ttLib.TTLibError,
			r"UIntBase128 format requires 0 <= integer <= 2\*\*32-1",
			packBase128, -1)


class UShort255Test(unittest.TestCase):

	def test_unpack255UShort(self):
		self.assertEqual(unpack255UShort(bytechr(252))[0], 252)
		# some numbers (e.g. 506) can have multiple encodings
		self.assertEqual(
			unpack255UShort(struct.pack(b"BB", 254, 0))[0], 506)
		self.assertEqual(
			unpack255UShort(struct.pack(b"BB", 255, 253))[0], 506)
		self.assertEqual(
			unpack255UShort(struct.pack(b"BBB", 253, 1, 250))[0], 506)

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"not enough data to unpack 255UInt16",
			unpack255UShort, struct.pack(b"BB", 253, 0))

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"not enough data to unpack 255UInt16",
			unpack255UShort, struct.pack(b"B", 254))

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"not enough data to unpack 255UInt16",
			unpack255UShort, struct.pack(b"B", 255))

	def test_pack255UShort(self):
		self.assertEqual(pack255UShort(252), b'\xfc')
		self.assertEqual(pack255UShort(505), b'\xff\xfc')
		self.assertEqual(pack255UShort(506), b'\xfe\x00')
		self.assertEqual(pack255UShort(762), b'\xfd\x02\xfa')

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"255UInt16 format requires 0 <= integer <= 65535",
			pack255UShort, -1)

		self.assertRaisesRegex(
			ttLib.TTLibError,
			"255UInt16 format requires 0 <= integer <= 65535",
			pack255UShort, 0xFFFF+1)


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