Upgrade fonttools to 3.43.1
am: 9b4ad0c3d9

Change-Id: I7bf0eb18e3d4dd9f81bae39497638e9ee786eb75
diff --git a/Lib/fontTools/__init__.py b/Lib/fontTools/__init__.py
index 6a066d7..d6919b2 100644
--- a/Lib/fontTools/__init__.py
+++ b/Lib/fontTools/__init__.py
@@ -5,6 +5,6 @@
 
 log = logging.getLogger(__name__)
 
-version = __version__ = "3.42.0"
+version = __version__ = "3.43.1"
 
 __all__ = ["version", "log", "configLogger"]
diff --git a/Lib/fontTools/misc/loggingTools.py b/Lib/fontTools/misc/loggingTools.py
index aacc085..b4b9a9b 100644
--- a/Lib/fontTools/misc/loggingTools.py
+++ b/Lib/fontTools/misc/loggingTools.py
@@ -250,8 +250,8 @@
 	upon exiting the with-statement.
 
 	>>> import logging
-	>>> log = logging.getLogger("fontTools")
-	>>> configLogger(level="DEBUG", format="%(message)s", stream=sys.stdout)
+	>>> log = logging.getLogger("my-fancy-timer-logger")
+	>>> configLogger(logger=log, level="DEBUG", format="%(message)s", stream=sys.stdout)
 	>>> with Timer(log, 'do something'):
 	...     time.sleep(0.01)
 	Took ... to do something
@@ -530,67 +530,6 @@
 	return decorator
 
 
-class LastResortLogger(logging.Logger):
-	""" Adds support for 'lastResort' handler introduced in Python 3.2.
-	It allows to print messages to sys.stderr even when no explicit handler
-	was configured.
-	To enable it, you can do:
-
-		import logging
-		logging.lastResort = StderrHandler(logging.WARNING)
-		logging.setLoggerClass(LastResortLogger)
-	"""
-
-	def callHandlers(self, record):
-		# this is the same as Python 3.5's logging.Logger.callHandlers
-		c = self
-		found = 0
-		while c:
-			for hdlr in c.handlers:
-				found = found + 1
-				if record.levelno >= hdlr.level:
-					hdlr.handle(record)
-			if not c.propagate:
-				c = None  # break out
-			else:
-				c = c.parent
-		if found == 0:
-			if logging.lastResort:
-				if record.levelno >= logging.lastResort.level:
-					logging.lastResort.handle(record)
-			elif (
-				logging.raiseExceptions
-				and not self.manager.emittedNoHandlerWarning
-			):
-				sys.stderr.write(
-					"No handlers could be found for logger"
-					' "%s"\n' % self.name
-				)
-				self.manager.emittedNoHandlerWarning = True
-
-
-class StderrHandler(logging.StreamHandler):
-	""" This class is like a StreamHandler using sys.stderr, but always uses
-	whateve sys.stderr is currently set to rather than the value of
-	sys.stderr at handler construction time.
-	"""
-
-	def __init__(self, level=logging.NOTSET):
-		"""
-		Initialize the handler.
-		"""
-		logging.Handler.__init__(self, level)
-
-	@property
-	def stream(self):
-		# the try/execept avoids failures during interpreter shutdown, when
-		# globals are set to None
-		try:
-			return sys.stderr
-		except AttributeError:
-			return __import__("sys").stderr
-
-
 if __name__ == "__main__":
 	import doctest
 	sys.exit(doctest.testmod(optionflags=doctest.ELLIPSIS).failed)
diff --git a/Lib/fontTools/otlLib/builder.py b/Lib/fontTools/otlLib/builder.py
index f8b3ce3..a087b2d 100644
--- a/Lib/fontTools/otlLib/builder.py
+++ b/Lib/fontTools/otlLib/builder.py
@@ -1,4 +1,5 @@
 from __future__ import print_function, division, absolute_import
+from collections import namedtuple
 from fontTools import ttLib
 from fontTools.ttLib.tables import otTables as ot
 from fontTools.ttLib.tables.otBase import ValueRecord, valueRecordFormatDict
@@ -488,17 +489,25 @@
     return tuple(result)
 
 
+_DeviceTuple = namedtuple("_DeviceTuple", "DeltaFormat StartSize EndSize DeltaValue")
+
+
 def _makeDeviceTuple(device):
     """otTables.Device --> tuple, for making device tables unique"""
-    return (device.DeltaFormat, device.StartSize, device.EndSize,
-            tuple(device.DeltaValue))
+    return _DeviceTuple(
+        device.DeltaFormat,
+        device.StartSize,
+        device.EndSize,
+        () if device.DeltaFormat & 0x8000 else tuple(device.DeltaValue)
+    )
+
 
 def _getSinglePosValueSize(valueKey):
     """Returns how many ushorts this valueKey (short form of ValueRecord) takes up"""
     count = 0
-    for k in valueKey[1:]:
-        if hasattr(k[1], '__len__') and len(k[1]):
-            count += len(k[1][3]) + 3
+    for _, v in valueKey[1:]:
+        if isinstance(v, _DeviceTuple):
+            count += len(v.DeltaValue) + 3
         else:
             count += 1
     return count
diff --git a/Lib/fontTools/subset/__init__.py b/Lib/fontTools/subset/__init__.py
index 8cf82c1..6863bb6 100644
--- a/Lib/fontTools/subset/__init__.py
+++ b/Lib/fontTools/subset/__init__.py
@@ -1987,7 +1987,8 @@
 
 @_add_method(ttLib.getTableClass('MATH'))
 def closure_glyphs(self, s):
-	self.table.MathVariants.closure_glyphs(s)
+	if self.table.MathVariants:
+		self.table.MathVariants.closure_glyphs(s)
 
 @_add_method(otTables.MathItalicsCorrectionInfo)
 def subset_glyphs(self, s):
@@ -2039,8 +2040,10 @@
 @_add_method(ttLib.getTableClass('MATH'))
 def subset_glyphs(self, s):
 	s.glyphs = s.glyphs_mathed
-	self.table.MathGlyphInfo.subset_glyphs(s)
-	self.table.MathVariants.subset_glyphs(s)
+	if self.table.MathGlyphInfo:
+		self.table.MathGlyphInfo.subset_glyphs(s)
+	if self.table.MathVariants:
+		self.table.MathVariants.subset_glyphs(s)
 	return True
 
 @_add_method(ttLib.getTableModule('glyf').Glyph)
diff --git a/Lib/fontTools/ttLib/woff2.py b/Lib/fontTools/ttLib/woff2.py
index c0c0e70..56b119a 100644
--- a/Lib/fontTools/ttLib/woff2.py
+++ b/Lib/fontTools/ttLib/woff2.py
@@ -16,7 +16,7 @@
 import logging
 
 
-log = logging.getLogger(__name__)
+log = logging.getLogger("fontTools.ttLib.woff2")
 
 haveBrotli = False
 try:
@@ -82,7 +82,7 @@
 		"""Fetch the raw table data. Reconstruct transformed tables."""
 		entry = self.tables[Tag(tag)]
 		if not hasattr(entry, 'data'):
-			if tag in woff2TransformedTableTags:
+			if entry.transformed:
 				entry.data = self.reconstructTable(tag)
 			else:
 				entry.data = entry.loadData(self.transformBuffer)
@@ -90,8 +90,6 @@
 
 	def reconstructTable(self, tag):
 		"""Reconstruct table named 'tag' from transformed data."""
-		if tag not in woff2TransformedTableTags:
-			raise TTLibError("transform for table '%s' is unknown" % tag)
 		entry = self.tables[Tag(tag)]
 		rawData = entry.loadData(self.transformBuffer)
 		if tag == 'glyf':
@@ -100,8 +98,10 @@
 			data = self._reconstructGlyf(rawData, padding)
 		elif tag == 'loca':
 			data = self._reconstructLoca()
+		elif tag == 'hmtx':
+			data = self._reconstructHmtx(rawData)
 		else:
-			raise NotImplementedError
+			raise TTLibError("transform for table '%s' is unknown" % tag)
 		return data
 
 	def _reconstructGlyf(self, data, padding=None):
@@ -130,6 +130,34 @@
 				% (self.tables['loca'].origLength, len(data)))
 		return data
 
+	def _reconstructHmtx(self, data):
+		""" Return reconstructed hmtx table data. """
+		# Before reconstructing 'hmtx' table we need to parse other tables:
+		# 'glyf' is required for reconstructing the sidebearings from the glyphs'
+		# bounding box; 'hhea' is needed for the numberOfHMetrics field.
+		if "glyf" in self.flavorData.transformedTables:
+			# transformed 'glyf' table is self-contained, thus 'loca' not needed
+			tableDependencies = ("maxp", "hhea", "glyf")
+		else:
+			# decompiling untransformed 'glyf' requires 'loca', which requires 'head'
+			tableDependencies = ("maxp", "head", "hhea", "loca", "glyf")
+		for tag in tableDependencies:
+			self._decompileTable(tag)
+		hmtxTable = self.ttFont["hmtx"] = WOFF2HmtxTable()
+		hmtxTable.reconstruct(data, self.ttFont)
+		data = hmtxTable.compile(self.ttFont)
+		return data
+
+	def _decompileTable(self, tag):
+		"""Decompile table data and store it inside self.ttFont."""
+		data = self[tag]
+		if self.ttFont.isLoaded(tag):
+			return self.ttFont[tag]
+		tableClass = getTableClass(tag)
+		table = tableClass(tag)
+		self.ttFont.tables[tag] = table
+		table.decompile(data, self.ttFont)
+
 
 class WOFF2Writer(SFNTWriter):
 
@@ -146,7 +174,7 @@
 		self.file = file
 		self.numTables = numTables
 		self.sfntVersion = Tag(sfntVersion)
-		self.flavorData = flavorData or WOFF2FlavorData()
+		self.flavorData = WOFF2FlavorData(data=flavorData)
 
 		self.directoryFormat = woff2DirectoryFormat
 		self.directorySize = woff2DirectorySize
@@ -199,7 +227,7 @@
 		# See:
 		# https://github.com/khaledhosny/ots/issues/60
 		# https://github.com/google/woff2/issues/15
-		if isTrueType:
+		if isTrueType and "glyf" in self.flavorData.transformedTables:
 			self._normaliseGlyfAndLoca(padding=4)
 		self._setHeadTransformFlag()
 
@@ -234,13 +262,7 @@
 		if self.sfntVersion == "OTTO":
 			return
 
-		# make up glyph names required to decompile glyf table
-		self._decompileTable('maxp')
-		numGlyphs = self.ttFont['maxp'].numGlyphs
-		glyphOrder = ['.notdef'] + ["glyph%.5d" % i for i in range(1, numGlyphs)]
-		self.ttFont.setGlyphOrder(glyphOrder)
-
-		for tag in ('head', 'loca', 'glyf'):
+		for tag in ('maxp', 'head', 'loca', 'glyf'):
 			self._decompileTable(tag)
 		self.ttFont['glyf'].padding = padding
 		for tag in ('glyf', 'loca'):
@@ -265,6 +287,8 @@
 			tableClass = WOFF2LocaTable
 		elif tag == 'glyf':
 			tableClass = WOFF2GlyfTable
+		elif tag == 'hmtx':
+			tableClass = WOFF2HmtxTable
 		else:
 			tableClass = getTableClass(tag)
 		table = tableClass(tag)
@@ -293,11 +317,17 @@
 
 	def _transformTables(self):
 		"""Return transformed font data."""
+		transformedTables = self.flavorData.transformedTables
 		for tag, entry in self.tables.items():
-			if tag in woff2TransformedTableTags:
+			data = None
+			if tag in transformedTables:
 				data = self.transformTable(tag)
-			else:
+				if data is not None:
+					entry.transformed = True
+			if data is None:
+				# pass-through the table data without transformation
 				data = entry.data
+				entry.transformed = False
 			entry.offset = self.nextTableOffset
 			entry.saveData(self.transformBuffer, data)
 			self.nextTableOffset += entry.length
@@ -306,9 +336,9 @@
 		return fontData
 
 	def transformTable(self, tag):
-		"""Return transformed table data."""
-		if tag not in woff2TransformedTableTags:
-			raise TTLibError("Transform for table '%s' is unknown" % tag)
+		"""Return transformed table data, or None if some pre-conditions aren't
+		met -- in which case, the non-transformed table data will be used.
+		"""
 		if tag == "loca":
 			data = b""
 		elif tag == "glyf":
@@ -316,8 +346,15 @@
 				self._decompileTable(tag)
 			glyfTable = self.ttFont['glyf']
 			data = glyfTable.transform(self.ttFont)
+		elif tag == "hmtx":
+			if "glyf" not in self.tables:
+				return
+			for tag in ("maxp", "head", "hhea", "loca", "glyf", "hmtx"):
+				self._decompileTable(tag)
+			hmtxTable = self.ttFont["hmtx"]
+			data = hmtxTable.transform(self.ttFont)  # can be None
 		else:
-			raise NotImplementedError
+			raise TTLibError("Transform for table '%s' is unknown" % tag)
 		return data
 
 	def _calcMasterChecksum(self):
@@ -533,11 +570,9 @@
 			# otherwise, tag is derived from a fixed 'Known Tags' table
 			self.tag = woff2KnownTags[self.flags & 0x3F]
 		self.tag = Tag(self.tag)
-		if self.flags & 0xC0 != 0:
-			raise TTLibError('bits 6-7 are reserved and must be 0')
 		self.origLength, data = unpackBase128(data)
 		self.length = self.origLength
-		if self.tag in woff2TransformedTableTags:
+		if self.transformed:
 			self.length, data = unpackBase128(data)
 			if self.tag == 'loca' and self.length != 0:
 				raise TTLibError(
@@ -550,10 +585,44 @@
 		if (self.flags & 0x3F) == 0x3F:
 			data += struct.pack('>4s', self.tag.tobytes())
 		data += packBase128(self.origLength)
-		if self.tag in woff2TransformedTableTags:
+		if self.transformed:
 			data += packBase128(self.length)
 		return data
 
+	@property
+	def transformVersion(self):
+		"""Return bits 6-7 of table entry's flags, which indicate the preprocessing
+		transformation version number (between 0 and 3).
+		"""
+		return self.flags >> 6
+
+	@transformVersion.setter
+	def transformVersion(self, value):
+		assert 0 <= value <= 3
+		self.flags |= value << 6
+
+	@property
+	def transformed(self):
+		"""Return True if the table has any transformation, else return False."""
+		# For all tables in a font, except for 'glyf' and 'loca', the transformation
+		# version 0 indicates the null transform (where the original table data is
+		# passed directly to the Brotli compressor). For 'glyf' and 'loca' tables,
+		# transformation version 3 indicates the null transform
+		if self.tag in {"glyf", "loca"}:
+			return self.transformVersion != 3
+		else:
+			return self.transformVersion != 0
+
+	@transformed.setter
+	def transformed(self, booleanValue):
+		# here we assume that a non-null transform means version 0 for 'glyf' and
+		# 'loca' and 1 for every other table (e.g. hmtx); but that may change as
+		# new transformation formats are introduced in the future (if ever).
+		if self.tag in {"glyf", "loca"}:
+			self.transformVersion = 3 if not booleanValue else 0
+		else:
+			self.transformVersion = int(booleanValue)
+
 
 class WOFF2LocaTable(getTableClass('loca')):
 	"""Same as parent class. The only difference is that it attempts to preserve
@@ -652,19 +721,7 @@
 	def transform(self, ttFont):
 		""" Return transformed 'glyf' data """
 		self.numGlyphs = len(self.glyphs)
-		if not hasattr(self, "glyphOrder"):
-			try:
-				self.glyphOrder = ttFont.getGlyphOrder()
-			except:
-				self.glyphOrder = None
-			if self.glyphOrder is None:
-				self.glyphOrder = [".notdef"]
-				self.glyphOrder.extend(["glyph%.5d" % i for i in range(1, self.numGlyphs)])
-		if len(self.glyphOrder) != self.numGlyphs:
-			raise TTLibError(
-				"incorrect glyphOrder: expected %d glyphs, found %d" %
-				(len(self.glyphOrder), self.numGlyphs))
-
+		assert len(self.glyphOrder) == self.numGlyphs
 		if 'maxp' in ttFont:
 			ttFont['maxp'].numGlyphs = self.numGlyphs
 		self.indexFormat = ttFont['head'].indexToLocFormat
@@ -909,13 +966,206 @@
 		self.glyphStream += triplets.tostring()
 
 
+class WOFF2HmtxTable(getTableClass("hmtx")):
+
+	def __init__(self, tag=None):
+		self.tableTag = Tag(tag or 'hmtx')
+
+	def reconstruct(self, data, ttFont):
+		flags, = struct.unpack(">B", data[:1])
+		data = data[1:]
+		if flags & 0b11111100 != 0:
+			raise TTLibError("Bits 2-7 of '%s' flags are reserved" % self.tableTag)
+
+		# When bit 0 is _not_ set, the lsb[] array is present
+		hasLsbArray = flags & 1 == 0
+		# When bit 1 is _not_ set, the leftSideBearing[] array is present
+		hasLeftSideBearingArray = flags & 2 == 0
+		if hasLsbArray and hasLeftSideBearingArray:
+			raise TTLibError(
+				"either bits 0 or 1 (or both) must set in transformed '%s' flags"
+				% self.tableTag
+			)
+
+		glyfTable = ttFont["glyf"]
+		headerTable = ttFont["hhea"]
+		glyphOrder = glyfTable.glyphOrder
+		numGlyphs = len(glyphOrder)
+		numberOfHMetrics = min(int(headerTable.numberOfHMetrics), numGlyphs)
+
+		assert len(data) >= 2 * numberOfHMetrics
+		advanceWidthArray = array.array("H", data[:2 * numberOfHMetrics])
+		if sys.byteorder != "big":
+			advanceWidthArray.byteswap()
+		data = data[2 * numberOfHMetrics:]
+
+		if hasLsbArray:
+			assert len(data) >= 2 * numberOfHMetrics
+			lsbArray = array.array("h", data[:2 * numberOfHMetrics])
+			if sys.byteorder != "big":
+				lsbArray.byteswap()
+			data = data[2 * numberOfHMetrics:]
+		else:
+			# compute (proportional) glyphs' lsb from their xMin
+			lsbArray = array.array("h")
+			for i, glyphName in enumerate(glyphOrder):
+				if i >= numberOfHMetrics:
+					break
+				glyph = glyfTable[glyphName]
+				xMin = getattr(glyph, "xMin", 0)
+				lsbArray.append(xMin)
+
+		numberOfSideBearings = numGlyphs - numberOfHMetrics
+		if hasLeftSideBearingArray:
+			assert len(data) >= 2 * numberOfSideBearings
+			leftSideBearingArray = array.array("h", data[:2 * numberOfSideBearings])
+			if sys.byteorder != "big":
+				leftSideBearingArray.byteswap()
+			data = data[2 * numberOfSideBearings:]
+		else:
+			# compute (monospaced) glyphs' leftSideBearing from their xMin
+			leftSideBearingArray = array.array("h")
+			for i, glyphName in enumerate(glyphOrder):
+				if i < numberOfHMetrics:
+					continue
+				glyph = glyfTable[glyphName]
+				xMin = getattr(glyph, "xMin", 0)
+				leftSideBearingArray.append(xMin)
+
+		if data:
+			raise TTLibError("too much '%s' table data" % self.tableTag)
+
+		self.metrics = {}
+		for i in range(numberOfHMetrics):
+			glyphName = glyphOrder[i]
+			advanceWidth, lsb = advanceWidthArray[i], lsbArray[i]
+			self.metrics[glyphName] = (advanceWidth, lsb)
+		lastAdvance = advanceWidthArray[-1]
+		for i in range(numberOfSideBearings):
+			glyphName = glyphOrder[i + numberOfHMetrics]
+			self.metrics[glyphName] = (lastAdvance, leftSideBearingArray[i])
+
+	def transform(self, ttFont):
+		glyphOrder = ttFont.getGlyphOrder()
+		glyf = ttFont["glyf"]
+		hhea = ttFont["hhea"]
+		numberOfHMetrics = hhea.numberOfHMetrics
+
+		# check if any of the proportional glyphs has left sidebearings that
+		# differ from their xMin bounding box values.
+		hasLsbArray = False
+		for i in range(numberOfHMetrics):
+			glyphName = glyphOrder[i]
+			lsb = self.metrics[glyphName][1]
+			if lsb != getattr(glyf[glyphName], "xMin", 0):
+				hasLsbArray = True
+				break
+
+		# do the same for the monospaced glyphs (if any) at the end of hmtx table
+		hasLeftSideBearingArray = False
+		for i in range(numberOfHMetrics, len(glyphOrder)):
+			glyphName = glyphOrder[i]
+			lsb = self.metrics[glyphName][1]
+			if lsb != getattr(glyf[glyphName], "xMin", 0):
+				hasLeftSideBearingArray = True
+				break
+
+		# if we need to encode both sidebearings arrays, then no transformation is
+		# applicable, and we must use the untransformed hmtx data
+		if hasLsbArray and hasLeftSideBearingArray:
+			return
+
+		# set bit 0 and 1 when the respective arrays are _not_ present
+		flags = 0
+		if not hasLsbArray:
+			flags |= 1 << 0
+		if not hasLeftSideBearingArray:
+			flags |= 1 << 1
+
+		data = struct.pack(">B", flags)
+
+		advanceWidthArray = array.array(
+			"H",
+			[
+				self.metrics[glyphName][0]
+				for i, glyphName in enumerate(glyphOrder)
+				if i < numberOfHMetrics
+			]
+		)
+		if sys.byteorder != "big":
+			advanceWidthArray.byteswap()
+		data += advanceWidthArray.tostring()
+
+		if hasLsbArray:
+			lsbArray = array.array(
+				"h",
+				[
+					self.metrics[glyphName][1]
+					for i, glyphName in enumerate(glyphOrder)
+					if i < numberOfHMetrics
+				]
+			)
+			if sys.byteorder != "big":
+				lsbArray.byteswap()
+			data += lsbArray.tostring()
+
+		if hasLeftSideBearingArray:
+			leftSideBearingArray = array.array(
+				"h",
+				[
+					self.metrics[glyphOrder[i]][1]
+					for i in range(numberOfHMetrics, len(glyphOrder))
+				]
+			)
+			if sys.byteorder != "big":
+				leftSideBearingArray.byteswap()
+			data += leftSideBearingArray.tostring()
+
+		return data
+
+
 class WOFF2FlavorData(WOFFFlavorData):
 
 	Flavor = 'woff2'
 
-	def __init__(self, reader=None):
+	def __init__(self, reader=None, data=None, transformedTables=None):
+		"""Data class that holds the WOFF2 header major/minor version, any
+		metadata or private data (as bytes strings), and the set of
+		table tags that have transformations applied (if reader is not None),
+		or will have once the WOFF2 font is compiled.
+
+		Args:
+			reader: an SFNTReader (or subclass) object to read flavor data from.
+			data: another WOFFFlavorData object to initialise data from.
+			transformedTables: set of strings containing table tags to be transformed.
+
+		Raises:
+			ImportError if the brotli module is not installed.
+
+		NOTE: The 'reader' argument, on the one hand, and the 'data' and
+		'transformedTables' arguments, on the other hand, are mutually exclusive.
+		"""
 		if not haveBrotli:
 			raise ImportError("No module named brotli")
+
+		if reader is not None:
+			if data is not None:
+				raise TypeError(
+					"'reader' and 'data' arguments are mutually exclusive"
+				)
+			if transformedTables is not None:
+				raise TypeError(
+					"'reader' and 'transformedTables' arguments are mutually exclusive"
+				)
+
+		if transformedTables is not None and (
+				"glyf" in transformedTables and "loca" not in transformedTables
+				or "loca" in transformedTables and "glyf" not in transformedTables
+			):
+				raise ValueError(
+					"'glyf' and 'loca' must be transformed (or not) together"
+				)
+
 		self.majorVersion = None
 		self.minorVersion = None
 		self.metaData = None
@@ -927,14 +1177,31 @@
 				reader.file.seek(reader.metaOffset)
 				rawData = reader.file.read(reader.metaLength)
 				assert len(rawData) == reader.metaLength
-				data = brotli.decompress(rawData)
-				assert len(data) == reader.metaOrigLength
-				self.metaData = data
+				metaData = brotli.decompress(rawData)
+				assert len(metaData) == reader.metaOrigLength
+				self.metaData = metaData
 			if reader.privLength:
 				reader.file.seek(reader.privOffset)
-				data = reader.file.read(reader.privLength)
-				assert len(data) == reader.privLength
-				self.privData = data
+				privData = reader.file.read(reader.privLength)
+				assert len(privData) == reader.privLength
+				self.privData = privData
+			transformedTables = [
+				tag
+				for tag, entry in reader.tables.items()
+				if entry.transformed
+			]
+		elif data:
+			self.majorVersion = data.majorVersion
+			self.majorVersion = data.minorVersion
+			self.metaData = data.metaData
+			self.privData = data.privData
+			if transformedTables is None and hasattr(data, "transformedTables"):
+				 transformedTables = data.transformedTables
+
+		if transformedTables is None:
+			transformedTables = woff2TransformedTableTags
+
+		self.transformedTables = set(transformedTables)
 
 
 def unpackBase128(data):
@@ -1091,6 +1358,166 @@
 		return struct.pack(">BH", 253, value)
 
 
+def compress(input_file, output_file, transform_tables=None):
+	"""Compress OpenType font to WOFF2.
+
+	Args:
+		input_file: a file path, file or file-like object (open in binary mode)
+			containing an OpenType font (either CFF- or TrueType-flavored).
+		output_file: a file path, file or file-like object where to save the
+			compressed WOFF2 font.
+		transform_tables: Optional[Iterable[str]]: a set of table tags for which
+			to enable preprocessing transformations. By default, only 'glyf'
+			and 'loca' tables are transformed. An empty set means disable all
+			transformations.
+	"""
+	log.info("Processing %s => %s" % (input_file, output_file))
+
+	font = TTFont(input_file, recalcBBoxes=False, recalcTimestamp=False)
+	font.flavor = "woff2"
+
+	if transform_tables is not None:
+		font.flavorData = WOFF2FlavorData(
+			data=font.flavorData, transformedTables=transform_tables
+		)
+
+	font.save(output_file, reorderTables=False)
+
+
+def decompress(input_file, output_file):
+	"""Decompress WOFF2 font to OpenType font.
+
+	Args:
+		input_file: a file path, file or file-like object (open in binary mode)
+			containing a compressed WOFF2 font.
+		output_file: a file path, file or file-like object where to save the
+			decompressed OpenType font.
+	"""
+	log.info("Processing %s => %s" % (input_file, output_file))
+
+	font = TTFont(input_file, recalcBBoxes=False, recalcTimestamp=False)
+	font.flavor = None
+	font.flavorData = None
+	font.save(output_file, reorderTables=True)
+
+
+def main(args=None):
+	import argparse
+	from fontTools import configLogger
+	from fontTools.ttx import makeOutputFileName
+
+	class _NoGlyfTransformAction(argparse.Action):
+		def __call__(self, parser, namespace, values, option_string=None):
+			namespace.transform_tables.difference_update({"glyf", "loca"})
+
+	class _HmtxTransformAction(argparse.Action):
+		def __call__(self, parser, namespace, values, option_string=None):
+			namespace.transform_tables.add("hmtx")
+
+	parser = argparse.ArgumentParser(
+		prog="fonttools ttLib.woff2",
+		description="Compress and decompress WOFF2 fonts",
+	)
+
+	parser_group = parser.add_subparsers(title="sub-commands")
+	parser_compress = parser_group.add_parser("compress")
+	parser_decompress = parser_group.add_parser("decompress")
+
+	for subparser in (parser_compress, parser_decompress):
+		group = subparser.add_mutually_exclusive_group(required=False)
+		group.add_argument(
+			"-v",
+			"--verbose",
+			action="store_true",
+			help="print more messages to console",
+		)
+		group.add_argument(
+			"-q",
+			"--quiet",
+			action="store_true",
+			help="do not print messages to console",
+		)
+
+	parser_compress.add_argument(
+		"input_file",
+		metavar="INPUT",
+		help="the input OpenType font (.ttf or .otf)",
+	)
+	parser_decompress.add_argument(
+		"input_file",
+		metavar="INPUT",
+		help="the input WOFF2 font",
+	)
+
+	parser_compress.add_argument(
+		"-o",
+		"--output-file",
+		metavar="OUTPUT",
+		help="the output WOFF2 font",
+	)
+	parser_decompress.add_argument(
+		"-o",
+		"--output-file",
+		metavar="OUTPUT",
+		help="the output OpenType font",
+	)
+
+	transform_group = parser_compress.add_argument_group()
+	transform_group.add_argument(
+		"--no-glyf-transform",
+		dest="transform_tables",
+		nargs=0,
+		action=_NoGlyfTransformAction,
+		help="Do not transform glyf (and loca) tables",
+	)
+	transform_group.add_argument(
+		"--hmtx-transform",
+		dest="transform_tables",
+		nargs=0,
+		action=_HmtxTransformAction,
+		help="Enable optional transformation for 'hmtx' table",
+	)
+
+	parser_compress.set_defaults(
+		subcommand=compress,
+		transform_tables={"glyf", "loca"},
+	)
+	parser_decompress.set_defaults(subcommand=decompress)
+
+	options = vars(parser.parse_args(args))
+
+	subcommand = options.pop("subcommand", None)
+	if not subcommand:
+		parser.print_help()
+		return
+
+	quiet = options.pop("quiet")
+	verbose = options.pop("verbose")
+	configLogger(
+		level=("ERROR" if quiet else "DEBUG" if verbose else "INFO"),
+	)
+
+	if not options["output_file"]:
+		if subcommand is compress:
+			extension = ".woff2"
+		elif subcommand is decompress:
+			# choose .ttf/.otf file extension depending on sfntVersion
+			with open(options["input_file"], "rb") as f:
+				f.seek(4)  # skip 'wOF2' signature
+				sfntVersion = f.read(4)
+			assert len(sfntVersion) == 4, "not enough data"
+			extension = ".otf" if sfntVersion == b"OTTO" else ".ttf"
+		else:
+			raise AssertionError(subcommand)
+		options["output_file"] = makeOutputFileName(
+			options["input_file"], outputDir=None, extension=extension
+		)
+
+	try:
+		subcommand(**options)
+	except TTLibError as e:
+		parser.error(e)
+
+
 if __name__ == "__main__":
-	import doctest
-	sys.exit(doctest.testmod().failed)
+	sys.exit(main())
diff --git a/Lib/fontTools/unicodedata/Blocks.py b/Lib/fontTools/unicodedata/Blocks.py
index 692fca8..132b095 100644
--- a/Lib/fontTools/unicodedata/Blocks.py
+++ b/Lib/fontTools/unicodedata/Blocks.py
@@ -4,9 +4,9 @@
 # Source: https://unicode.org/Public/UNIDATA/Blocks.txt
 # License: http://unicode.org/copyright.html#License
 #
-# Blocks-11.0.0.txt
-# Date: 2017-10-16, 24:39:00 GMT [KW]
-# © 2017 Unicode®, Inc.
+# Blocks-12.1.0.txt
+# Date: 2019-03-08, 23:59:00 GMT [KW]
+# © 2019 Unicode®, Inc.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
 # Unicode Character Database
@@ -237,7 +237,8 @@
     0x10E80,  # .. 0x10EFF ; No_Block
     0x10F00,  # .. 0x10F2F ; Old Sogdian
     0x10F30,  # .. 0x10F6F ; Sogdian
-    0x10F70,  # .. 0x10FFF ; No_Block
+    0x10F70,  # .. 0x10FDF ; No_Block
+    0x10FE0,  # .. 0x10FFF ; Elymaic
     0x11000,  # .. 0x1107F ; Brahmi
     0x11080,  # .. 0x110CF ; Kaithi
     0x110D0,  # .. 0x110FF ; Sora Sompeng
@@ -264,7 +265,8 @@
     0x11800,  # .. 0x1184F ; Dogra
     0x11850,  # .. 0x1189F ; No_Block
     0x118A0,  # .. 0x118FF ; Warang Citi
-    0x11900,  # .. 0x119FF ; No_Block
+    0x11900,  # .. 0x1199F ; No_Block
+    0x119A0,  # .. 0x119FF ; Nandinagari
     0x11A00,  # .. 0x11A4F ; Zanabazar Square
     0x11A50,  # .. 0x11AAF ; Soyombo
     0x11AB0,  # .. 0x11ABF ; No_Block
@@ -277,13 +279,15 @@
     0x11D60,  # .. 0x11DAF ; Gunjala Gondi
     0x11DB0,  # .. 0x11EDF ; No_Block
     0x11EE0,  # .. 0x11EFF ; Makasar
-    0x11F00,  # .. 0x11FFF ; No_Block
+    0x11F00,  # .. 0x11FBF ; No_Block
+    0x11FC0,  # .. 0x11FFF ; Tamil Supplement
     0x12000,  # .. 0x123FF ; Cuneiform
     0x12400,  # .. 0x1247F ; Cuneiform Numbers and Punctuation
     0x12480,  # .. 0x1254F ; Early Dynastic Cuneiform
     0x12550,  # .. 0x12FFF ; No_Block
     0x13000,  # .. 0x1342F ; Egyptian Hieroglyphs
-    0x13430,  # .. 0x143FF ; No_Block
+    0x13430,  # .. 0x1343F ; Egyptian Hieroglyph Format Controls
+    0x13440,  # .. 0x143FF ; No_Block
     0x14400,  # .. 0x1467F ; Anatolian Hieroglyphs
     0x14680,  # .. 0x167FF ; No_Block
     0x16800,  # .. 0x16A3F ; Bamum Supplement
@@ -302,7 +306,7 @@
     0x18B00,  # .. 0x1AFFF ; No_Block
     0x1B000,  # .. 0x1B0FF ; Kana Supplement
     0x1B100,  # .. 0x1B12F ; Kana Extended-A
-    0x1B130,  # .. 0x1B16F ; No_Block
+    0x1B130,  # .. 0x1B16F ; Small Kana Extension
     0x1B170,  # .. 0x1B2FF ; Nushu
     0x1B300,  # .. 0x1BBFF ; No_Block
     0x1BC00,  # .. 0x1BC9F ; Duployan
@@ -320,13 +324,19 @@
     0x1D800,  # .. 0x1DAAF ; Sutton SignWriting
     0x1DAB0,  # .. 0x1DFFF ; No_Block
     0x1E000,  # .. 0x1E02F ; Glagolitic Supplement
-    0x1E030,  # .. 0x1E7FF ; No_Block
+    0x1E030,  # .. 0x1E0FF ; No_Block
+    0x1E100,  # .. 0x1E14F ; Nyiakeng Puachue Hmong
+    0x1E150,  # .. 0x1E2BF ; No_Block
+    0x1E2C0,  # .. 0x1E2FF ; Wancho
+    0x1E300,  # .. 0x1E7FF ; No_Block
     0x1E800,  # .. 0x1E8DF ; Mende Kikakui
     0x1E8E0,  # .. 0x1E8FF ; No_Block
     0x1E900,  # .. 0x1E95F ; Adlam
     0x1E960,  # .. 0x1EC6F ; No_Block
     0x1EC70,  # .. 0x1ECBF ; Indic Siyaq Numbers
-    0x1ECC0,  # .. 0x1EDFF ; No_Block
+    0x1ECC0,  # .. 0x1ECFF ; No_Block
+    0x1ED00,  # .. 0x1ED4F ; Ottoman Siyaq Numbers
+    0x1ED50,  # .. 0x1EDFF ; No_Block
     0x1EE00,  # .. 0x1EEFF ; Arabic Mathematical Alphabetic Symbols
     0x1EF00,  # .. 0x1EFFF ; No_Block
     0x1F000,  # .. 0x1F02F ; Mahjong Tiles
@@ -343,7 +353,8 @@
     0x1F800,  # .. 0x1F8FF ; Supplemental Arrows-C
     0x1F900,  # .. 0x1F9FF ; Supplemental Symbols and Pictographs
     0x1FA00,  # .. 0x1FA6F ; Chess Symbols
-    0x1FA70,  # .. 0x1FFFF ; No_Block
+    0x1FA70,  # .. 0x1FAFF ; Symbols and Pictographs Extended-A
+    0x1FB00,  # .. 0x1FFFF ; No_Block
     0x20000,  # .. 0x2A6DF ; CJK Unified Ideographs Extension B
     0x2A6E0,  # .. 0x2A6FF ; No_Block
     0x2A700,  # .. 0x2B73F ; CJK Unified Ideographs Extension C
@@ -582,7 +593,8 @@
     'No_Block',                                        # 10E80..10EFF
     'Old Sogdian',                                     # 10F00..10F2F
     'Sogdian',                                         # 10F30..10F6F
-    'No_Block',                                        # 10F70..10FFF
+    'No_Block',                                        # 10F70..10FDF
+    'Elymaic',                                         # 10FE0..10FFF
     'Brahmi',                                          # 11000..1107F
     'Kaithi',                                          # 11080..110CF
     'Sora Sompeng',                                    # 110D0..110FF
@@ -609,7 +621,8 @@
     'Dogra',                                           # 11800..1184F
     'No_Block',                                        # 11850..1189F
     'Warang Citi',                                     # 118A0..118FF
-    'No_Block',                                        # 11900..119FF
+    'No_Block',                                        # 11900..1199F
+    'Nandinagari',                                     # 119A0..119FF
     'Zanabazar Square',                                # 11A00..11A4F
     'Soyombo',                                         # 11A50..11AAF
     'No_Block',                                        # 11AB0..11ABF
@@ -622,13 +635,15 @@
     'Gunjala Gondi',                                   # 11D60..11DAF
     'No_Block',                                        # 11DB0..11EDF
     'Makasar',                                         # 11EE0..11EFF
-    'No_Block',                                        # 11F00..11FFF
+    'No_Block',                                        # 11F00..11FBF
+    'Tamil Supplement',                                # 11FC0..11FFF
     'Cuneiform',                                       # 12000..123FF
     'Cuneiform Numbers and Punctuation',               # 12400..1247F
     'Early Dynastic Cuneiform',                        # 12480..1254F
     'No_Block',                                        # 12550..12FFF
     'Egyptian Hieroglyphs',                            # 13000..1342F
-    'No_Block',                                        # 13430..143FF
+    'Egyptian Hieroglyph Format Controls',             # 13430..1343F
+    'No_Block',                                        # 13440..143FF
     'Anatolian Hieroglyphs',                           # 14400..1467F
     'No_Block',                                        # 14680..167FF
     'Bamum Supplement',                                # 16800..16A3F
@@ -647,7 +662,7 @@
     'No_Block',                                        # 18B00..1AFFF
     'Kana Supplement',                                 # 1B000..1B0FF
     'Kana Extended-A',                                 # 1B100..1B12F
-    'No_Block',                                        # 1B130..1B16F
+    'Small Kana Extension',                            # 1B130..1B16F
     'Nushu',                                           # 1B170..1B2FF
     'No_Block',                                        # 1B300..1BBFF
     'Duployan',                                        # 1BC00..1BC9F
@@ -665,13 +680,19 @@
     'Sutton SignWriting',                              # 1D800..1DAAF
     'No_Block',                                        # 1DAB0..1DFFF
     'Glagolitic Supplement',                           # 1E000..1E02F
-    'No_Block',                                        # 1E030..1E7FF
+    'No_Block',                                        # 1E030..1E0FF
+    'Nyiakeng Puachue Hmong',                          # 1E100..1E14F
+    'No_Block',                                        # 1E150..1E2BF
+    'Wancho',                                          # 1E2C0..1E2FF
+    'No_Block',                                        # 1E300..1E7FF
     'Mende Kikakui',                                   # 1E800..1E8DF
     'No_Block',                                        # 1E8E0..1E8FF
     'Adlam',                                           # 1E900..1E95F
     'No_Block',                                        # 1E960..1EC6F
     'Indic Siyaq Numbers',                             # 1EC70..1ECBF
-    'No_Block',                                        # 1ECC0..1EDFF
+    'No_Block',                                        # 1ECC0..1ECFF
+    'Ottoman Siyaq Numbers',                           # 1ED00..1ED4F
+    'No_Block',                                        # 1ED50..1EDFF
     'Arabic Mathematical Alphabetic Symbols',          # 1EE00..1EEFF
     'No_Block',                                        # 1EF00..1EFFF
     'Mahjong Tiles',                                   # 1F000..1F02F
@@ -688,7 +709,8 @@
     'Supplemental Arrows-C',                           # 1F800..1F8FF
     'Supplemental Symbols and Pictographs',            # 1F900..1F9FF
     'Chess Symbols',                                   # 1FA00..1FA6F
-    'No_Block',                                        # 1FA70..1FFFF
+    'Symbols and Pictographs Extended-A',              # 1FA70..1FAFF
+    'No_Block',                                        # 1FB00..1FFFF
     'CJK Unified Ideographs Extension B',              # 20000..2A6DF
     'No_Block',                                        # 2A6E0..2A6FF
     'CJK Unified Ideographs Extension C',              # 2A700..2B73F
diff --git a/Lib/fontTools/unicodedata/ScriptExtensions.py b/Lib/fontTools/unicodedata/ScriptExtensions.py
index bfcdbec..d7d2e3c 100644
--- a/Lib/fontTools/unicodedata/ScriptExtensions.py
+++ b/Lib/fontTools/unicodedata/ScriptExtensions.py
@@ -4,9 +4,9 @@
 # Source: https://unicode.org/Public/UNIDATA/ScriptExtensions.txt
 # License: http://unicode.org/copyright.html#License
 #
-# ScriptExtensions-11.0.0.txt
-# Date: 2018-02-04, 20:04:00 GMT
-# © 2018 Unicode®, Inc.
+# ScriptExtensions-12.1.0.txt
+# Date: 2019-04-01, 09:10:42 GMT
+# © 2019 Unicode®, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -75,8 +75,8 @@
     0x0951,  # .. 0x0951 ; {'Beng', 'Deva', 'Gran', 'Gujr', 'Guru', 'Knda', 'Latn', 'Mlym', 'Orya', 'Shrd', 'Taml', 'Telu', 'Tirh'}
     0x0952,  # .. 0x0952 ; {'Beng', 'Deva', 'Gran', 'Gujr', 'Guru', 'Knda', 'Latn', 'Mlym', 'Orya', 'Taml', 'Telu', 'Tirh'}
     0x0953,  # .. 0x0963 ; None
-    0x0964,  # .. 0x0964 ; {'Beng', 'Deva', 'Dogr', 'Gong', 'Gran', 'Gujr', 'Guru', 'Knda', 'Mahj', 'Mlym', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'}
-    0x0965,  # .. 0x0965 ; {'Beng', 'Deva', 'Dogr', 'Gong', 'Gran', 'Gujr', 'Guru', 'Knda', 'Limb', 'Mahj', 'Mlym', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'}
+    0x0964,  # .. 0x0964 ; {'Beng', 'Deva', 'Dogr', 'Gong', 'Gonm', 'Gran', 'Gujr', 'Guru', 'Knda', 'Mahj', 'Mlym', 'Nand', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'}
+    0x0965,  # .. 0x0965 ; {'Beng', 'Deva', 'Dogr', 'Gong', 'Gonm', 'Gran', 'Gujr', 'Guru', 'Knda', 'Limb', 'Mahj', 'Mlym', 'Nand', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'}
     0x0966,  # .. 0x096F ; {'Deva', 'Dogr', 'Kthi', 'Mahj'}
     0x0970,  # .. 0x09E5 ; None
     0x09E6,  # .. 0x09EF ; {'Beng', 'Cakm', 'Sylo'}
@@ -86,7 +86,9 @@
     0x0AE6,  # .. 0x0AEF ; {'Gujr', 'Khoj'}
     0x0AF0,  # .. 0x0BE5 ; None
     0x0BE6,  # .. 0x0BF3 ; {'Gran', 'Taml'}
-    0x0BF4,  # .. 0x103F ; None
+    0x0BF4,  # .. 0x0CE5 ; None
+    0x0CE6,  # .. 0x0CEF ; {'Knda', 'Nand'}
+    0x0CF0,  # .. 0x103F ; None
     0x1040,  # .. 0x1049 ; {'Cakm', 'Mymr', 'Tale'}
     0x104A,  # .. 0x10FA ; None
     0x10FB,  # .. 0x10FB ; {'Geor', 'Latn'}
@@ -112,19 +114,24 @@
     0x1CDE,  # .. 0x1CDF ; {'Deva'}
     0x1CE0,  # .. 0x1CE0 ; {'Deva', 'Shrd'}
     0x1CE1,  # .. 0x1CE1 ; {'Beng', 'Deva'}
-    0x1CE2,  # .. 0x1CE9 ; {'Deva'}
+    0x1CE2,  # .. 0x1CE8 ; {'Deva'}
+    0x1CE9,  # .. 0x1CE9 ; {'Deva', 'Nand'}
     0x1CEA,  # .. 0x1CEA ; {'Beng', 'Deva'}
     0x1CEB,  # .. 0x1CEC ; {'Deva'}
     0x1CED,  # .. 0x1CED ; {'Beng', 'Deva'}
     0x1CEE,  # .. 0x1CF1 ; {'Deva'}
-    0x1CF2,  # .. 0x1CF3 ; {'Deva', 'Gran'}
+    0x1CF2,  # .. 0x1CF2 ; {'Beng', 'Deva', 'Gran', 'Knda', 'Nand', 'Orya', 'Telu', 'Tirh'}
+    0x1CF3,  # .. 0x1CF3 ; {'Deva', 'Gran'}
     0x1CF4,  # .. 0x1CF4 ; {'Deva', 'Gran', 'Knda'}
     0x1CF5,  # .. 0x1CF6 ; {'Beng', 'Deva'}
     0x1CF7,  # .. 0x1CF7 ; {'Beng'}
     0x1CF8,  # .. 0x1CF9 ; {'Deva', 'Gran'}
-    0x1CFA,  # .. 0x1DBF ; None
+    0x1CFA,  # .. 0x1CFA ; {'Nand'}
+    0x1CFB,  # .. 0x1DBF ; None
     0x1DC0,  # .. 0x1DC1 ; {'Grek'}
-    0x1DC2,  # .. 0x20EF ; None
+    0x1DC2,  # .. 0x202E ; None
+    0x202F,  # .. 0x202F ; {'Latn', 'Mong'}
+    0x2030,  # .. 0x20EF ; None
     0x20F0,  # .. 0x20F0 ; {'Deva', 'Gran', 'Latn'}
     0x20F1,  # .. 0x2E42 ; None
     0x2E43,  # .. 0x2E43 ; {'Cyrl', 'Glag'}
@@ -166,7 +173,9 @@
     0x3280,  # .. 0x32B0 ; {'Hani'}
     0x32B1,  # .. 0x32BF ; None
     0x32C0,  # .. 0x32CB ; {'Hani'}
-    0x32CC,  # .. 0x3357 ; None
+    0x32CC,  # .. 0x32FE ; None
+    0x32FF,  # .. 0x32FF ; {'Hani'}
+    0x3300,  # .. 0x3357 ; None
     0x3358,  # .. 0x3370 ; {'Hani'}
     0x3371,  # .. 0x337A ; None
     0x337B,  # .. 0x337F ; {'Hani'}
@@ -175,8 +184,8 @@
     0x33FF,  # .. 0xA66E ; None
     0xA66F,  # .. 0xA66F ; {'Cyrl', 'Glag'}
     0xA670,  # .. 0xA82F ; None
-    0xA830,  # .. 0xA832 ; {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Mlym', 'Modi', 'Sind', 'Takr', 'Tirh'}
-    0xA833,  # .. 0xA835 ; {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Modi', 'Sind', 'Takr', 'Tirh'}
+    0xA830,  # .. 0xA832 ; {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Mlym', 'Modi', 'Nand', 'Sind', 'Takr', 'Tirh'}
+    0xA833,  # .. 0xA835 ; {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Modi', 'Nand', 'Sind', 'Takr', 'Tirh'}
     0xA836,  # .. 0xA839 ; {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Kthi', 'Mahj', 'Modi', 'Sind', 'Takr', 'Tirh'}
     0xA83A,  # .. 0xA8F0 ; None
     0xA8F1,  # .. 0xA8F1 ; {'Beng', 'Deva'}
@@ -212,7 +221,11 @@
     0x11303,  # .. 0x11303 ; {'Gran', 'Taml'}
     0x11304,  # .. 0x1133A ; None
     0x1133B,  # .. 0x1133C ; {'Gran', 'Taml'}
-    0x1133D,  # .. 0x1BC9F ; None
+    0x1133D,  # .. 0x11FCF ; None
+    0x11FD0,  # .. 0x11FD1 ; {'Gran', 'Taml'}
+    0x11FD2,  # .. 0x11FD2 ; None
+    0x11FD3,  # .. 0x11FD3 ; {'Gran', 'Taml'}
+    0x11FD4,  # .. 0x1BC9F ; None
     0x1BCA0,  # .. 0x1BCA3 ; {'Dupl'}
     0x1BCA4,  # .. 0x1D35F ; None
     0x1D360,  # .. 0x1D371 ; {'Hani'}
@@ -256,8 +269,8 @@
     {'Beng', 'Deva', 'Gran', 'Gujr', 'Guru', 'Knda', 'Latn', 'Mlym', 'Orya', 'Shrd', 'Taml', 'Telu', 'Tirh'},  # 0951..0951
     {'Beng', 'Deva', 'Gran', 'Gujr', 'Guru', 'Knda', 'Latn', 'Mlym', 'Orya', 'Taml', 'Telu', 'Tirh'},  # 0952..0952
     None,                                                      # 0953..0963
-    {'Beng', 'Deva', 'Dogr', 'Gong', 'Gran', 'Gujr', 'Guru', 'Knda', 'Mahj', 'Mlym', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'},  # 0964..0964
-    {'Beng', 'Deva', 'Dogr', 'Gong', 'Gran', 'Gujr', 'Guru', 'Knda', 'Limb', 'Mahj', 'Mlym', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'},  # 0965..0965
+    {'Beng', 'Deva', 'Dogr', 'Gong', 'Gonm', 'Gran', 'Gujr', 'Guru', 'Knda', 'Mahj', 'Mlym', 'Nand', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'},  # 0964..0964
+    {'Beng', 'Deva', 'Dogr', 'Gong', 'Gonm', 'Gran', 'Gujr', 'Guru', 'Knda', 'Limb', 'Mahj', 'Mlym', 'Nand', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml', 'Telu', 'Tirh'},  # 0965..0965
     {'Deva', 'Dogr', 'Kthi', 'Mahj'},                          # 0966..096F
     None,                                                      # 0970..09E5
     {'Beng', 'Cakm', 'Sylo'},                                  # 09E6..09EF
@@ -267,7 +280,9 @@
     {'Gujr', 'Khoj'},                                          # 0AE6..0AEF
     None,                                                      # 0AF0..0BE5
     {'Gran', 'Taml'},                                          # 0BE6..0BF3
-    None,                                                      # 0BF4..103F
+    None,                                                      # 0BF4..0CE5
+    {'Knda', 'Nand'},                                          # 0CE6..0CEF
+    None,                                                      # 0CF0..103F
     {'Cakm', 'Mymr', 'Tale'},                                  # 1040..1049
     None,                                                      # 104A..10FA
     {'Geor', 'Latn'},                                          # 10FB..10FB
@@ -293,19 +308,24 @@
     {'Deva'},                                                  # 1CDE..1CDF
     {'Deva', 'Shrd'},                                          # 1CE0..1CE0
     {'Beng', 'Deva'},                                          # 1CE1..1CE1
-    {'Deva'},                                                  # 1CE2..1CE9
+    {'Deva'},                                                  # 1CE2..1CE8
+    {'Deva', 'Nand'},                                          # 1CE9..1CE9
     {'Beng', 'Deva'},                                          # 1CEA..1CEA
     {'Deva'},                                                  # 1CEB..1CEC
     {'Beng', 'Deva'},                                          # 1CED..1CED
     {'Deva'},                                                  # 1CEE..1CF1
-    {'Deva', 'Gran'},                                          # 1CF2..1CF3
+    {'Beng', 'Deva', 'Gran', 'Knda', 'Nand', 'Orya', 'Telu', 'Tirh'},  # 1CF2..1CF2
+    {'Deva', 'Gran'},                                          # 1CF3..1CF3
     {'Deva', 'Gran', 'Knda'},                                  # 1CF4..1CF4
     {'Beng', 'Deva'},                                          # 1CF5..1CF6
     {'Beng'},                                                  # 1CF7..1CF7
     {'Deva', 'Gran'},                                          # 1CF8..1CF9
-    None,                                                      # 1CFA..1DBF
+    {'Nand'},                                                  # 1CFA..1CFA
+    None,                                                      # 1CFB..1DBF
     {'Grek'},                                                  # 1DC0..1DC1
-    None,                                                      # 1DC2..20EF
+    None,                                                      # 1DC2..202E
+    {'Latn', 'Mong'},                                          # 202F..202F
+    None,                                                      # 2030..20EF
     {'Deva', 'Gran', 'Latn'},                                  # 20F0..20F0
     None,                                                      # 20F1..2E42
     {'Cyrl', 'Glag'},                                          # 2E43..2E43
@@ -347,7 +367,9 @@
     {'Hani'},                                                  # 3280..32B0
     None,                                                      # 32B1..32BF
     {'Hani'},                                                  # 32C0..32CB
-    None,                                                      # 32CC..3357
+    None,                                                      # 32CC..32FE
+    {'Hani'},                                                  # 32FF..32FF
+    None,                                                      # 3300..3357
     {'Hani'},                                                  # 3358..3370
     None,                                                      # 3371..337A
     {'Hani'},                                                  # 337B..337F
@@ -356,8 +378,8 @@
     None,                                                      # 33FF..A66E
     {'Cyrl', 'Glag'},                                          # A66F..A66F
     None,                                                      # A670..A82F
-    {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Mlym', 'Modi', 'Sind', 'Takr', 'Tirh'},  # A830..A832
-    {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Modi', 'Sind', 'Takr', 'Tirh'},  # A833..A835
+    {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Mlym', 'Modi', 'Nand', 'Sind', 'Takr', 'Tirh'},  # A830..A832
+    {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Knda', 'Kthi', 'Mahj', 'Modi', 'Nand', 'Sind', 'Takr', 'Tirh'},  # A833..A835
     {'Deva', 'Dogr', 'Gujr', 'Guru', 'Khoj', 'Kthi', 'Mahj', 'Modi', 'Sind', 'Takr', 'Tirh'},  # A836..A839
     None,                                                      # A83A..A8F0
     {'Beng', 'Deva'},                                          # A8F1..A8F1
@@ -393,7 +415,11 @@
     {'Gran', 'Taml'},                                          # 11303..11303
     None,                                                      # 11304..1133A
     {'Gran', 'Taml'},                                          # 1133B..1133C
-    None,                                                      # 1133D..1BC9F
+    None,                                                      # 1133D..11FCF
+    {'Gran', 'Taml'},                                          # 11FD0..11FD1
+    None,                                                      # 11FD2..11FD2
+    {'Gran', 'Taml'},                                          # 11FD3..11FD3
+    None,                                                      # 11FD4..1BC9F
     {'Dupl'},                                                  # 1BCA0..1BCA3
     None,                                                      # 1BCA4..1D35F
     {'Hani'},                                                  # 1D360..1D371
diff --git a/Lib/fontTools/unicodedata/Scripts.py b/Lib/fontTools/unicodedata/Scripts.py
index 30cd8f5..dc8c1e2 100644
--- a/Lib/fontTools/unicodedata/Scripts.py
+++ b/Lib/fontTools/unicodedata/Scripts.py
@@ -4,9 +4,9 @@
 # Source: https://unicode.org/Public/UNIDATA/Scripts.txt
 # License: http://unicode.org/copyright.html#License
 #
-# Scripts-11.0.0.txt
-# Date: 2018-02-21, 05:34:31 GMT
-# © 2018 Unicode®, Inc.
+# Scripts-12.1.0.txt
+# Date: 2019-04-01, 09:10:42 GMT
+# © 2019 Unicode®, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -128,8 +128,8 @@
     0x08E2,  # .. 0x08E2 ; Common
     0x08E3,  # .. 0x08FF ; Arabic
     0x0900,  # .. 0x0950 ; Devanagari
-    0x0951,  # .. 0x0952 ; Inherited
-    0x0953,  # .. 0x0963 ; Devanagari
+    0x0951,  # .. 0x0954 ; Inherited
+    0x0955,  # .. 0x0963 ; Devanagari
     0x0964,  # .. 0x0965 ; Common
     0x0966,  # .. 0x097F ; Devanagari
     0x0980,  # .. 0x0983 ; Bengali
@@ -301,8 +301,8 @@
     0x0C60,  # .. 0x0C63 ; Telugu
     0x0C64,  # .. 0x0C65 ; Unknown
     0x0C66,  # .. 0x0C6F ; Telugu
-    0x0C70,  # .. 0x0C77 ; Unknown
-    0x0C78,  # .. 0x0C7F ; Telugu
+    0x0C70,  # .. 0x0C76 ; Unknown
+    0x0C77,  # .. 0x0C7F ; Telugu
     0x0C80,  # .. 0x0C8C ; Kannada
     0x0C8D,  # .. 0x0C8D ; Unknown
     0x0C8E,  # .. 0x0C90 ; Kannada
@@ -377,28 +377,14 @@
     0x0E81,  # .. 0x0E82 ; Lao
     0x0E83,  # .. 0x0E83 ; Unknown
     0x0E84,  # .. 0x0E84 ; Lao
-    0x0E85,  # .. 0x0E86 ; Unknown
-    0x0E87,  # .. 0x0E88 ; Lao
-    0x0E89,  # .. 0x0E89 ; Unknown
-    0x0E8A,  # .. 0x0E8A ; Lao
-    0x0E8B,  # .. 0x0E8C ; Unknown
-    0x0E8D,  # .. 0x0E8D ; Lao
-    0x0E8E,  # .. 0x0E93 ; Unknown
-    0x0E94,  # .. 0x0E97 ; Lao
-    0x0E98,  # .. 0x0E98 ; Unknown
-    0x0E99,  # .. 0x0E9F ; Lao
-    0x0EA0,  # .. 0x0EA0 ; Unknown
-    0x0EA1,  # .. 0x0EA3 ; Lao
+    0x0E85,  # .. 0x0E85 ; Unknown
+    0x0E86,  # .. 0x0E8A ; Lao
+    0x0E8B,  # .. 0x0E8B ; Unknown
+    0x0E8C,  # .. 0x0EA3 ; Lao
     0x0EA4,  # .. 0x0EA4 ; Unknown
     0x0EA5,  # .. 0x0EA5 ; Lao
     0x0EA6,  # .. 0x0EA6 ; Unknown
-    0x0EA7,  # .. 0x0EA7 ; Lao
-    0x0EA8,  # .. 0x0EA9 ; Unknown
-    0x0EAA,  # .. 0x0EAB ; Lao
-    0x0EAC,  # .. 0x0EAC ; Unknown
-    0x0EAD,  # .. 0x0EB9 ; Lao
-    0x0EBA,  # .. 0x0EBA ; Unknown
-    0x0EBB,  # .. 0x0EBD ; Lao
+    0x0EA7,  # .. 0x0EBD ; Lao
     0x0EBE,  # .. 0x0EBF ; Unknown
     0x0EC0,  # .. 0x0EC4 ; Lao
     0x0EC5,  # .. 0x0EC5 ; Unknown
@@ -585,7 +571,8 @@
     0x1CF4,  # .. 0x1CF4 ; Inherited
     0x1CF5,  # .. 0x1CF7 ; Common
     0x1CF8,  # .. 0x1CF9 ; Inherited
-    0x1CFA,  # .. 0x1CFF ; Unknown
+    0x1CFA,  # .. 0x1CFA ; Common
+    0x1CFB,  # .. 0x1CFF ; Unknown
     0x1D00,  # .. 0x1D25 ; Latin
     0x1D26,  # .. 0x1D2A ; Greek
     0x1D2B,  # .. 0x1D2B ; Cyrillic
@@ -672,10 +659,7 @@
     0x2B74,  # .. 0x2B75 ; Unknown
     0x2B76,  # .. 0x2B95 ; Common
     0x2B96,  # .. 0x2B97 ; Unknown
-    0x2B98,  # .. 0x2BC8 ; Common
-    0x2BC9,  # .. 0x2BC9 ; Unknown
-    0x2BCA,  # .. 0x2BFE ; Common
-    0x2BFF,  # .. 0x2BFF ; Unknown
+    0x2B98,  # .. 0x2BFF ; Common
     0x2C00,  # .. 0x2C2E ; Glagolitic
     0x2C2F,  # .. 0x2C2F ; Unknown
     0x2C30,  # .. 0x2C5E ; Glagolitic
@@ -714,8 +698,8 @@
     0x2DD8,  # .. 0x2DDE ; Ethiopic
     0x2DDF,  # .. 0x2DDF ; Unknown
     0x2DE0,  # .. 0x2DFF ; Cyrillic
-    0x2E00,  # .. 0x2E4E ; Common
-    0x2E4F,  # .. 0x2E7F ; Unknown
+    0x2E00,  # .. 0x2E4F ; Common
+    0x2E50,  # .. 0x2E7F ; Unknown
     0x2E80,  # .. 0x2E99 ; Han
     0x2E9A,  # .. 0x2E9A ; Unknown
     0x2E9B,  # .. 0x2EF3 ; Han
@@ -762,7 +746,7 @@
     0x3260,  # .. 0x327E ; Hangul
     0x327F,  # .. 0x32CF ; Common
     0x32D0,  # .. 0x32FE ; Katakana
-    0x32FF,  # .. 0x32FF ; Unknown
+    0x32FF,  # .. 0x32FF ; Common
     0x3300,  # .. 0x3357 ; Katakana
     0x3358,  # .. 0x33FF ; Common
     0x3400,  # .. 0x4DB5 ; Han
@@ -783,8 +767,10 @@
     0xA700,  # .. 0xA721 ; Common
     0xA722,  # .. 0xA787 ; Latin
     0xA788,  # .. 0xA78A ; Common
-    0xA78B,  # .. 0xA7B9 ; Latin
-    0xA7BA,  # .. 0xA7F6 ; Unknown
+    0xA78B,  # .. 0xA7BF ; Latin
+    0xA7C0,  # .. 0xA7C1 ; Unknown
+    0xA7C2,  # .. 0xA7C6 ; Latin
+    0xA7C7,  # .. 0xA7F6 ; Unknown
     0xA7F7,  # .. 0xA7FF ; Latin
     0xA800,  # .. 0xA82B ; Syloti_Nagri
     0xA82C,  # .. 0xA82F ; Unknown
@@ -840,7 +826,8 @@
     0xAB5B,  # .. 0xAB5B ; Common
     0xAB5C,  # .. 0xAB64 ; Latin
     0xAB65,  # .. 0xAB65 ; Greek
-    0xAB66,  # .. 0xAB6F ; Unknown
+    0xAB66,  # .. 0xAB67 ; Latin
+    0xAB68,  # .. 0xAB6F ; Unknown
     0xAB70,  # .. 0xABBF ; Cherokee
     0xABC0,  # .. 0xABED ; Meetei_Mayek
     0xABEE,  # .. 0xABEF ; Unknown
@@ -1086,7 +1073,9 @@
     0x10F00,  # .. 0x10F27 ; Old_Sogdian
     0x10F28,  # .. 0x10F2F ; Unknown
     0x10F30,  # .. 0x10F59 ; Sogdian
-    0x10F5A,  # .. 0x10FFF ; Unknown
+    0x10F5A,  # .. 0x10FDF ; Unknown
+    0x10FE0,  # .. 0x10FF6 ; Elymaic
+    0x10FF7,  # .. 0x10FFF ; Unknown
     0x11000,  # .. 0x1104D ; Brahmi
     0x1104E,  # .. 0x11051 ; Unknown
     0x11052,  # .. 0x1106F ; Brahmi
@@ -1165,8 +1154,8 @@
     0x1145A,  # .. 0x1145A ; Unknown
     0x1145B,  # .. 0x1145B ; Newa
     0x1145C,  # .. 0x1145C ; Unknown
-    0x1145D,  # .. 0x1145E ; Newa
-    0x1145F,  # .. 0x1147F ; Unknown
+    0x1145D,  # .. 0x1145F ; Newa
+    0x11460,  # .. 0x1147F ; Unknown
     0x11480,  # .. 0x114C7 ; Tirhuta
     0x114C8,  # .. 0x114CF ; Unknown
     0x114D0,  # .. 0x114D9 ; Tirhuta
@@ -1181,8 +1170,8 @@
     0x1165A,  # .. 0x1165F ; Unknown
     0x11660,  # .. 0x1166C ; Mongolian
     0x1166D,  # .. 0x1167F ; Unknown
-    0x11680,  # .. 0x116B7 ; Takri
-    0x116B8,  # .. 0x116BF ; Unknown
+    0x11680,  # .. 0x116B8 ; Takri
+    0x116B9,  # .. 0x116BF ; Unknown
     0x116C0,  # .. 0x116C9 ; Takri
     0x116CA,  # .. 0x116FF ; Unknown
     0x11700,  # .. 0x1171A ; Ahom
@@ -1196,12 +1185,16 @@
     0x118A0,  # .. 0x118F2 ; Warang_Citi
     0x118F3,  # .. 0x118FE ; Unknown
     0x118FF,  # .. 0x118FF ; Warang_Citi
-    0x11900,  # .. 0x119FF ; Unknown
+    0x11900,  # .. 0x1199F ; Unknown
+    0x119A0,  # .. 0x119A7 ; Nandinagari
+    0x119A8,  # .. 0x119A9 ; Unknown
+    0x119AA,  # .. 0x119D7 ; Nandinagari
+    0x119D8,  # .. 0x119D9 ; Unknown
+    0x119DA,  # .. 0x119E4 ; Nandinagari
+    0x119E5,  # .. 0x119FF ; Unknown
     0x11A00,  # .. 0x11A47 ; Zanabazar_Square
     0x11A48,  # .. 0x11A4F ; Unknown
-    0x11A50,  # .. 0x11A83 ; Soyombo
-    0x11A84,  # .. 0x11A85 ; Unknown
-    0x11A86,  # .. 0x11AA2 ; Soyombo
+    0x11A50,  # .. 0x11AA2 ; Soyombo
     0x11AA3,  # .. 0x11ABF ; Unknown
     0x11AC0,  # .. 0x11AF8 ; Pau_Cin_Hau
     0x11AF9,  # .. 0x11BFF ; Unknown
@@ -1246,7 +1239,10 @@
     0x11DA0,  # .. 0x11DA9 ; Gunjala_Gondi
     0x11DAA,  # .. 0x11EDF ; Unknown
     0x11EE0,  # .. 0x11EF8 ; Makasar
-    0x11EF9,  # .. 0x11FFF ; Unknown
+    0x11EF9,  # .. 0x11FBF ; Unknown
+    0x11FC0,  # .. 0x11FF1 ; Tamil
+    0x11FF2,  # .. 0x11FFE ; Unknown
+    0x11FFF,  # .. 0x11FFF ; Tamil
     0x12000,  # .. 0x12399 ; Cuneiform
     0x1239A,  # .. 0x123FF ; Unknown
     0x12400,  # .. 0x1246E ; Cuneiform
@@ -1256,7 +1252,9 @@
     0x12480,  # .. 0x12543 ; Cuneiform
     0x12544,  # .. 0x12FFF ; Unknown
     0x13000,  # .. 0x1342E ; Egyptian_Hieroglyphs
-    0x1342F,  # .. 0x143FF ; Unknown
+    0x1342F,  # .. 0x1342F ; Unknown
+    0x13430,  # .. 0x13438 ; Egyptian_Hieroglyphs
+    0x13439,  # .. 0x143FF ; Unknown
     0x14400,  # .. 0x14646 ; Anatolian_Hieroglyphs
     0x14647,  # .. 0x167FF ; Unknown
     0x16800,  # .. 0x16A38 ; Bamum
@@ -1283,22 +1281,27 @@
     0x16B90,  # .. 0x16E3F ; Unknown
     0x16E40,  # .. 0x16E9A ; Medefaidrin
     0x16E9B,  # .. 0x16EFF ; Unknown
-    0x16F00,  # .. 0x16F44 ; Miao
-    0x16F45,  # .. 0x16F4F ; Unknown
-    0x16F50,  # .. 0x16F7E ; Miao
-    0x16F7F,  # .. 0x16F8E ; Unknown
+    0x16F00,  # .. 0x16F4A ; Miao
+    0x16F4B,  # .. 0x16F4E ; Unknown
+    0x16F4F,  # .. 0x16F87 ; Miao
+    0x16F88,  # .. 0x16F8E ; Unknown
     0x16F8F,  # .. 0x16F9F ; Miao
     0x16FA0,  # .. 0x16FDF ; Unknown
     0x16FE0,  # .. 0x16FE0 ; Tangut
     0x16FE1,  # .. 0x16FE1 ; Nushu
-    0x16FE2,  # .. 0x16FFF ; Unknown
-    0x17000,  # .. 0x187F1 ; Tangut
-    0x187F2,  # .. 0x187FF ; Unknown
+    0x16FE2,  # .. 0x16FE3 ; Common
+    0x16FE4,  # .. 0x16FFF ; Unknown
+    0x17000,  # .. 0x187F7 ; Tangut
+    0x187F8,  # .. 0x187FF ; Unknown
     0x18800,  # .. 0x18AF2 ; Tangut
     0x18AF3,  # .. 0x1AFFF ; Unknown
     0x1B000,  # .. 0x1B000 ; Katakana
     0x1B001,  # .. 0x1B11E ; Hiragana
-    0x1B11F,  # .. 0x1B16F ; Unknown
+    0x1B11F,  # .. 0x1B14F ; Unknown
+    0x1B150,  # .. 0x1B152 ; Hiragana
+    0x1B153,  # .. 0x1B163 ; Unknown
+    0x1B164,  # .. 0x1B167 ; Katakana
+    0x1B168,  # .. 0x1B16F ; Unknown
     0x1B170,  # .. 0x1B2FB ; Nushu
     0x1B2FC,  # .. 0x1BBFF ; Unknown
     0x1BC00,  # .. 0x1BC6A ; Duployan
@@ -1390,19 +1393,33 @@
     0x1E023,  # .. 0x1E024 ; Glagolitic
     0x1E025,  # .. 0x1E025 ; Unknown
     0x1E026,  # .. 0x1E02A ; Glagolitic
-    0x1E02B,  # .. 0x1E7FF ; Unknown
+    0x1E02B,  # .. 0x1E0FF ; Unknown
+    0x1E100,  # .. 0x1E12C ; Nyiakeng_Puachue_Hmong
+    0x1E12D,  # .. 0x1E12F ; Unknown
+    0x1E130,  # .. 0x1E13D ; Nyiakeng_Puachue_Hmong
+    0x1E13E,  # .. 0x1E13F ; Unknown
+    0x1E140,  # .. 0x1E149 ; Nyiakeng_Puachue_Hmong
+    0x1E14A,  # .. 0x1E14D ; Unknown
+    0x1E14E,  # .. 0x1E14F ; Nyiakeng_Puachue_Hmong
+    0x1E150,  # .. 0x1E2BF ; Unknown
+    0x1E2C0,  # .. 0x1E2F9 ; Wancho
+    0x1E2FA,  # .. 0x1E2FE ; Unknown
+    0x1E2FF,  # .. 0x1E2FF ; Wancho
+    0x1E300,  # .. 0x1E7FF ; Unknown
     0x1E800,  # .. 0x1E8C4 ; Mende_Kikakui
     0x1E8C5,  # .. 0x1E8C6 ; Unknown
     0x1E8C7,  # .. 0x1E8D6 ; Mende_Kikakui
     0x1E8D7,  # .. 0x1E8FF ; Unknown
-    0x1E900,  # .. 0x1E94A ; Adlam
-    0x1E94B,  # .. 0x1E94F ; Unknown
+    0x1E900,  # .. 0x1E94B ; Adlam
+    0x1E94C,  # .. 0x1E94F ; Unknown
     0x1E950,  # .. 0x1E959 ; Adlam
     0x1E95A,  # .. 0x1E95D ; Unknown
     0x1E95E,  # .. 0x1E95F ; Adlam
     0x1E960,  # .. 0x1EC70 ; Unknown
     0x1EC71,  # .. 0x1ECB4 ; Common
-    0x1ECB5,  # .. 0x1EDFF ; Unknown
+    0x1ECB5,  # .. 0x1ED00 ; Unknown
+    0x1ED01,  # .. 0x1ED3D ; Common
+    0x1ED3E,  # .. 0x1EDFF ; Unknown
     0x1EE00,  # .. 0x1EE03 ; Arabic
     0x1EE04,  # .. 0x1EE04 ; Unknown
     0x1EE05,  # .. 0x1EE1F ; Arabic
@@ -1485,8 +1502,8 @@
     0x1F0F6,  # .. 0x1F0FF ; Unknown
     0x1F100,  # .. 0x1F10C ; Common
     0x1F10D,  # .. 0x1F10F ; Unknown
-    0x1F110,  # .. 0x1F16B ; Common
-    0x1F16C,  # .. 0x1F16F ; Unknown
+    0x1F110,  # .. 0x1F16C ; Common
+    0x1F16D,  # .. 0x1F16F ; Unknown
     0x1F170,  # .. 0x1F1AC ; Common
     0x1F1AD,  # .. 0x1F1E5 ; Unknown
     0x1F1E6,  # .. 0x1F1FF ; Common
@@ -1501,16 +1518,18 @@
     0x1F252,  # .. 0x1F25F ; Unknown
     0x1F260,  # .. 0x1F265 ; Common
     0x1F266,  # .. 0x1F2FF ; Unknown
-    0x1F300,  # .. 0x1F6D4 ; Common
-    0x1F6D5,  # .. 0x1F6DF ; Unknown
+    0x1F300,  # .. 0x1F6D5 ; Common
+    0x1F6D6,  # .. 0x1F6DF ; Unknown
     0x1F6E0,  # .. 0x1F6EC ; Common
     0x1F6ED,  # .. 0x1F6EF ; Unknown
-    0x1F6F0,  # .. 0x1F6F9 ; Common
-    0x1F6FA,  # .. 0x1F6FF ; Unknown
+    0x1F6F0,  # .. 0x1F6FA ; Common
+    0x1F6FB,  # .. 0x1F6FF ; Unknown
     0x1F700,  # .. 0x1F773 ; Common
     0x1F774,  # .. 0x1F77F ; Unknown
     0x1F780,  # .. 0x1F7D8 ; Common
-    0x1F7D9,  # .. 0x1F7FF ; Unknown
+    0x1F7D9,  # .. 0x1F7DF ; Unknown
+    0x1F7E0,  # .. 0x1F7EB ; Common
+    0x1F7EC,  # .. 0x1F7FF ; Unknown
     0x1F800,  # .. 0x1F80B ; Common
     0x1F80C,  # .. 0x1F80F ; Unknown
     0x1F810,  # .. 0x1F847 ; Common
@@ -1522,25 +1541,29 @@
     0x1F890,  # .. 0x1F8AD ; Common
     0x1F8AE,  # .. 0x1F8FF ; Unknown
     0x1F900,  # .. 0x1F90B ; Common
-    0x1F90C,  # .. 0x1F90F ; Unknown
-    0x1F910,  # .. 0x1F93E ; Common
-    0x1F93F,  # .. 0x1F93F ; Unknown
-    0x1F940,  # .. 0x1F970 ; Common
-    0x1F971,  # .. 0x1F972 ; Unknown
+    0x1F90C,  # .. 0x1F90C ; Unknown
+    0x1F90D,  # .. 0x1F971 ; Common
+    0x1F972,  # .. 0x1F972 ; Unknown
     0x1F973,  # .. 0x1F976 ; Common
     0x1F977,  # .. 0x1F979 ; Unknown
-    0x1F97A,  # .. 0x1F97A ; Common
-    0x1F97B,  # .. 0x1F97B ; Unknown
-    0x1F97C,  # .. 0x1F9A2 ; Common
-    0x1F9A3,  # .. 0x1F9AF ; Unknown
-    0x1F9B0,  # .. 0x1F9B9 ; Common
-    0x1F9BA,  # .. 0x1F9BF ; Unknown
-    0x1F9C0,  # .. 0x1F9C2 ; Common
-    0x1F9C3,  # .. 0x1F9CF ; Unknown
-    0x1F9D0,  # .. 0x1F9FF ; Common
-    0x1FA00,  # .. 0x1FA5F ; Unknown
+    0x1F97A,  # .. 0x1F9A2 ; Common
+    0x1F9A3,  # .. 0x1F9A4 ; Unknown
+    0x1F9A5,  # .. 0x1F9AA ; Common
+    0x1F9AB,  # .. 0x1F9AD ; Unknown
+    0x1F9AE,  # .. 0x1F9CA ; Common
+    0x1F9CB,  # .. 0x1F9CC ; Unknown
+    0x1F9CD,  # .. 0x1FA53 ; Common
+    0x1FA54,  # .. 0x1FA5F ; Unknown
     0x1FA60,  # .. 0x1FA6D ; Common
-    0x1FA6E,  # .. 0x1FFFF ; Unknown
+    0x1FA6E,  # .. 0x1FA6F ; Unknown
+    0x1FA70,  # .. 0x1FA73 ; Common
+    0x1FA74,  # .. 0x1FA77 ; Unknown
+    0x1FA78,  # .. 0x1FA7A ; Common
+    0x1FA7B,  # .. 0x1FA7F ; Unknown
+    0x1FA80,  # .. 0x1FA82 ; Common
+    0x1FA83,  # .. 0x1FA8F ; Unknown
+    0x1FA90,  # .. 0x1FA95 ; Common
+    0x1FA96,  # .. 0x1FFFF ; Unknown
     0x20000,  # .. 0x2A6D6 ; Han
     0x2A6D7,  # .. 0x2A6FF ; Unknown
     0x2A700,  # .. 0x2B734 ; Han
@@ -1669,8 +1692,8 @@
     'Zyyy',  # 08E2..08E2 ; Common
     'Arab',  # 08E3..08FF ; Arabic
     'Deva',  # 0900..0950 ; Devanagari
-    'Zinh',  # 0951..0952 ; Inherited
-    'Deva',  # 0953..0963 ; Devanagari
+    'Zinh',  # 0951..0954 ; Inherited
+    'Deva',  # 0955..0963 ; Devanagari
     'Zyyy',  # 0964..0965 ; Common
     'Deva',  # 0966..097F ; Devanagari
     'Beng',  # 0980..0983 ; Bengali
@@ -1842,8 +1865,8 @@
     'Telu',  # 0C60..0C63 ; Telugu
     'Zzzz',  # 0C64..0C65 ; Unknown
     'Telu',  # 0C66..0C6F ; Telugu
-    'Zzzz',  # 0C70..0C77 ; Unknown
-    'Telu',  # 0C78..0C7F ; Telugu
+    'Zzzz',  # 0C70..0C76 ; Unknown
+    'Telu',  # 0C77..0C7F ; Telugu
     'Knda',  # 0C80..0C8C ; Kannada
     'Zzzz',  # 0C8D..0C8D ; Unknown
     'Knda',  # 0C8E..0C90 ; Kannada
@@ -1918,28 +1941,14 @@
     'Laoo',  # 0E81..0E82 ; Lao
     'Zzzz',  # 0E83..0E83 ; Unknown
     'Laoo',  # 0E84..0E84 ; Lao
-    'Zzzz',  # 0E85..0E86 ; Unknown
-    'Laoo',  # 0E87..0E88 ; Lao
-    'Zzzz',  # 0E89..0E89 ; Unknown
-    'Laoo',  # 0E8A..0E8A ; Lao
-    'Zzzz',  # 0E8B..0E8C ; Unknown
-    'Laoo',  # 0E8D..0E8D ; Lao
-    'Zzzz',  # 0E8E..0E93 ; Unknown
-    'Laoo',  # 0E94..0E97 ; Lao
-    'Zzzz',  # 0E98..0E98 ; Unknown
-    'Laoo',  # 0E99..0E9F ; Lao
-    'Zzzz',  # 0EA0..0EA0 ; Unknown
-    'Laoo',  # 0EA1..0EA3 ; Lao
+    'Zzzz',  # 0E85..0E85 ; Unknown
+    'Laoo',  # 0E86..0E8A ; Lao
+    'Zzzz',  # 0E8B..0E8B ; Unknown
+    'Laoo',  # 0E8C..0EA3 ; Lao
     'Zzzz',  # 0EA4..0EA4 ; Unknown
     'Laoo',  # 0EA5..0EA5 ; Lao
     'Zzzz',  # 0EA6..0EA6 ; Unknown
-    'Laoo',  # 0EA7..0EA7 ; Lao
-    'Zzzz',  # 0EA8..0EA9 ; Unknown
-    'Laoo',  # 0EAA..0EAB ; Lao
-    'Zzzz',  # 0EAC..0EAC ; Unknown
-    'Laoo',  # 0EAD..0EB9 ; Lao
-    'Zzzz',  # 0EBA..0EBA ; Unknown
-    'Laoo',  # 0EBB..0EBD ; Lao
+    'Laoo',  # 0EA7..0EBD ; Lao
     'Zzzz',  # 0EBE..0EBF ; Unknown
     'Laoo',  # 0EC0..0EC4 ; Lao
     'Zzzz',  # 0EC5..0EC5 ; Unknown
@@ -2126,7 +2135,8 @@
     'Zinh',  # 1CF4..1CF4 ; Inherited
     'Zyyy',  # 1CF5..1CF7 ; Common
     'Zinh',  # 1CF8..1CF9 ; Inherited
-    'Zzzz',  # 1CFA..1CFF ; Unknown
+    'Zyyy',  # 1CFA..1CFA ; Common
+    'Zzzz',  # 1CFB..1CFF ; Unknown
     'Latn',  # 1D00..1D25 ; Latin
     'Grek',  # 1D26..1D2A ; Greek
     'Cyrl',  # 1D2B..1D2B ; Cyrillic
@@ -2213,10 +2223,7 @@
     'Zzzz',  # 2B74..2B75 ; Unknown
     'Zyyy',  # 2B76..2B95 ; Common
     'Zzzz',  # 2B96..2B97 ; Unknown
-    'Zyyy',  # 2B98..2BC8 ; Common
-    'Zzzz',  # 2BC9..2BC9 ; Unknown
-    'Zyyy',  # 2BCA..2BFE ; Common
-    'Zzzz',  # 2BFF..2BFF ; Unknown
+    'Zyyy',  # 2B98..2BFF ; Common
     'Glag',  # 2C00..2C2E ; Glagolitic
     'Zzzz',  # 2C2F..2C2F ; Unknown
     'Glag',  # 2C30..2C5E ; Glagolitic
@@ -2255,8 +2262,8 @@
     'Ethi',  # 2DD8..2DDE ; Ethiopic
     'Zzzz',  # 2DDF..2DDF ; Unknown
     'Cyrl',  # 2DE0..2DFF ; Cyrillic
-    'Zyyy',  # 2E00..2E4E ; Common
-    'Zzzz',  # 2E4F..2E7F ; Unknown
+    'Zyyy',  # 2E00..2E4F ; Common
+    'Zzzz',  # 2E50..2E7F ; Unknown
     'Hani',  # 2E80..2E99 ; Han
     'Zzzz',  # 2E9A..2E9A ; Unknown
     'Hani',  # 2E9B..2EF3 ; Han
@@ -2303,7 +2310,7 @@
     'Hang',  # 3260..327E ; Hangul
     'Zyyy',  # 327F..32CF ; Common
     'Kana',  # 32D0..32FE ; Katakana
-    'Zzzz',  # 32FF..32FF ; Unknown
+    'Zyyy',  # 32FF..32FF ; Common
     'Kana',  # 3300..3357 ; Katakana
     'Zyyy',  # 3358..33FF ; Common
     'Hani',  # 3400..4DB5 ; Han
@@ -2324,8 +2331,10 @@
     'Zyyy',  # A700..A721 ; Common
     'Latn',  # A722..A787 ; Latin
     'Zyyy',  # A788..A78A ; Common
-    'Latn',  # A78B..A7B9 ; Latin
-    'Zzzz',  # A7BA..A7F6 ; Unknown
+    'Latn',  # A78B..A7BF ; Latin
+    'Zzzz',  # A7C0..A7C1 ; Unknown
+    'Latn',  # A7C2..A7C6 ; Latin
+    'Zzzz',  # A7C7..A7F6 ; Unknown
     'Latn',  # A7F7..A7FF ; Latin
     'Sylo',  # A800..A82B ; Syloti_Nagri
     'Zzzz',  # A82C..A82F ; Unknown
@@ -2381,7 +2390,8 @@
     'Zyyy',  # AB5B..AB5B ; Common
     'Latn',  # AB5C..AB64 ; Latin
     'Grek',  # AB65..AB65 ; Greek
-    'Zzzz',  # AB66..AB6F ; Unknown
+    'Latn',  # AB66..AB67 ; Latin
+    'Zzzz',  # AB68..AB6F ; Unknown
     'Cher',  # AB70..ABBF ; Cherokee
     'Mtei',  # ABC0..ABED ; Meetei_Mayek
     'Zzzz',  # ABEE..ABEF ; Unknown
@@ -2627,7 +2637,9 @@
     'Sogo',  # 10F00..10F27 ; Old_Sogdian
     'Zzzz',  # 10F28..10F2F ; Unknown
     'Sogd',  # 10F30..10F59 ; Sogdian
-    'Zzzz',  # 10F5A..10FFF ; Unknown
+    'Zzzz',  # 10F5A..10FDF ; Unknown
+    'Elym',  # 10FE0..10FF6 ; Elymaic
+    'Zzzz',  # 10FF7..10FFF ; Unknown
     'Brah',  # 11000..1104D ; Brahmi
     'Zzzz',  # 1104E..11051 ; Unknown
     'Brah',  # 11052..1106F ; Brahmi
@@ -2706,8 +2718,8 @@
     'Zzzz',  # 1145A..1145A ; Unknown
     'Newa',  # 1145B..1145B ; Newa
     'Zzzz',  # 1145C..1145C ; Unknown
-    'Newa',  # 1145D..1145E ; Newa
-    'Zzzz',  # 1145F..1147F ; Unknown
+    'Newa',  # 1145D..1145F ; Newa
+    'Zzzz',  # 11460..1147F ; Unknown
     'Tirh',  # 11480..114C7 ; Tirhuta
     'Zzzz',  # 114C8..114CF ; Unknown
     'Tirh',  # 114D0..114D9 ; Tirhuta
@@ -2722,8 +2734,8 @@
     'Zzzz',  # 1165A..1165F ; Unknown
     'Mong',  # 11660..1166C ; Mongolian
     'Zzzz',  # 1166D..1167F ; Unknown
-    'Takr',  # 11680..116B7 ; Takri
-    'Zzzz',  # 116B8..116BF ; Unknown
+    'Takr',  # 11680..116B8 ; Takri
+    'Zzzz',  # 116B9..116BF ; Unknown
     'Takr',  # 116C0..116C9 ; Takri
     'Zzzz',  # 116CA..116FF ; Unknown
     'Ahom',  # 11700..1171A ; Ahom
@@ -2737,12 +2749,16 @@
     'Wara',  # 118A0..118F2 ; Warang_Citi
     'Zzzz',  # 118F3..118FE ; Unknown
     'Wara',  # 118FF..118FF ; Warang_Citi
-    'Zzzz',  # 11900..119FF ; Unknown
+    'Zzzz',  # 11900..1199F ; Unknown
+    'Nand',  # 119A0..119A7 ; Nandinagari
+    'Zzzz',  # 119A8..119A9 ; Unknown
+    'Nand',  # 119AA..119D7 ; Nandinagari
+    'Zzzz',  # 119D8..119D9 ; Unknown
+    'Nand',  # 119DA..119E4 ; Nandinagari
+    'Zzzz',  # 119E5..119FF ; Unknown
     'Zanb',  # 11A00..11A47 ; Zanabazar_Square
     'Zzzz',  # 11A48..11A4F ; Unknown
-    'Soyo',  # 11A50..11A83 ; Soyombo
-    'Zzzz',  # 11A84..11A85 ; Unknown
-    'Soyo',  # 11A86..11AA2 ; Soyombo
+    'Soyo',  # 11A50..11AA2 ; Soyombo
     'Zzzz',  # 11AA3..11ABF ; Unknown
     'Pauc',  # 11AC0..11AF8 ; Pau_Cin_Hau
     'Zzzz',  # 11AF9..11BFF ; Unknown
@@ -2787,7 +2803,10 @@
     'Gong',  # 11DA0..11DA9 ; Gunjala_Gondi
     'Zzzz',  # 11DAA..11EDF ; Unknown
     'Maka',  # 11EE0..11EF8 ; Makasar
-    'Zzzz',  # 11EF9..11FFF ; Unknown
+    'Zzzz',  # 11EF9..11FBF ; Unknown
+    'Taml',  # 11FC0..11FF1 ; Tamil
+    'Zzzz',  # 11FF2..11FFE ; Unknown
+    'Taml',  # 11FFF..11FFF ; Tamil
     'Xsux',  # 12000..12399 ; Cuneiform
     'Zzzz',  # 1239A..123FF ; Unknown
     'Xsux',  # 12400..1246E ; Cuneiform
@@ -2797,7 +2816,9 @@
     'Xsux',  # 12480..12543 ; Cuneiform
     'Zzzz',  # 12544..12FFF ; Unknown
     'Egyp',  # 13000..1342E ; Egyptian_Hieroglyphs
-    'Zzzz',  # 1342F..143FF ; Unknown
+    'Zzzz',  # 1342F..1342F ; Unknown
+    'Egyp',  # 13430..13438 ; Egyptian_Hieroglyphs
+    'Zzzz',  # 13439..143FF ; Unknown
     'Hluw',  # 14400..14646 ; Anatolian_Hieroglyphs
     'Zzzz',  # 14647..167FF ; Unknown
     'Bamu',  # 16800..16A38 ; Bamum
@@ -2824,22 +2845,27 @@
     'Zzzz',  # 16B90..16E3F ; Unknown
     'Medf',  # 16E40..16E9A ; Medefaidrin
     'Zzzz',  # 16E9B..16EFF ; Unknown
-    'Plrd',  # 16F00..16F44 ; Miao
-    'Zzzz',  # 16F45..16F4F ; Unknown
-    'Plrd',  # 16F50..16F7E ; Miao
-    'Zzzz',  # 16F7F..16F8E ; Unknown
+    'Plrd',  # 16F00..16F4A ; Miao
+    'Zzzz',  # 16F4B..16F4E ; Unknown
+    'Plrd',  # 16F4F..16F87 ; Miao
+    'Zzzz',  # 16F88..16F8E ; Unknown
     'Plrd',  # 16F8F..16F9F ; Miao
     'Zzzz',  # 16FA0..16FDF ; Unknown
     'Tang',  # 16FE0..16FE0 ; Tangut
     'Nshu',  # 16FE1..16FE1 ; Nushu
-    'Zzzz',  # 16FE2..16FFF ; Unknown
-    'Tang',  # 17000..187F1 ; Tangut
-    'Zzzz',  # 187F2..187FF ; Unknown
+    'Zyyy',  # 16FE2..16FE3 ; Common
+    'Zzzz',  # 16FE4..16FFF ; Unknown
+    'Tang',  # 17000..187F7 ; Tangut
+    'Zzzz',  # 187F8..187FF ; Unknown
     'Tang',  # 18800..18AF2 ; Tangut
     'Zzzz',  # 18AF3..1AFFF ; Unknown
     'Kana',  # 1B000..1B000 ; Katakana
     'Hira',  # 1B001..1B11E ; Hiragana
-    'Zzzz',  # 1B11F..1B16F ; Unknown
+    'Zzzz',  # 1B11F..1B14F ; Unknown
+    'Hira',  # 1B150..1B152 ; Hiragana
+    'Zzzz',  # 1B153..1B163 ; Unknown
+    'Kana',  # 1B164..1B167 ; Katakana
+    'Zzzz',  # 1B168..1B16F ; Unknown
     'Nshu',  # 1B170..1B2FB ; Nushu
     'Zzzz',  # 1B2FC..1BBFF ; Unknown
     'Dupl',  # 1BC00..1BC6A ; Duployan
@@ -2931,19 +2957,33 @@
     'Glag',  # 1E023..1E024 ; Glagolitic
     'Zzzz',  # 1E025..1E025 ; Unknown
     'Glag',  # 1E026..1E02A ; Glagolitic
-    'Zzzz',  # 1E02B..1E7FF ; Unknown
+    'Zzzz',  # 1E02B..1E0FF ; Unknown
+    'Hmnp',  # 1E100..1E12C ; Nyiakeng_Puachue_Hmong
+    'Zzzz',  # 1E12D..1E12F ; Unknown
+    'Hmnp',  # 1E130..1E13D ; Nyiakeng_Puachue_Hmong
+    'Zzzz',  # 1E13E..1E13F ; Unknown
+    'Hmnp',  # 1E140..1E149 ; Nyiakeng_Puachue_Hmong
+    'Zzzz',  # 1E14A..1E14D ; Unknown
+    'Hmnp',  # 1E14E..1E14F ; Nyiakeng_Puachue_Hmong
+    'Zzzz',  # 1E150..1E2BF ; Unknown
+    'Wcho',  # 1E2C0..1E2F9 ; Wancho
+    'Zzzz',  # 1E2FA..1E2FE ; Unknown
+    'Wcho',  # 1E2FF..1E2FF ; Wancho
+    'Zzzz',  # 1E300..1E7FF ; Unknown
     'Mend',  # 1E800..1E8C4 ; Mende_Kikakui
     'Zzzz',  # 1E8C5..1E8C6 ; Unknown
     'Mend',  # 1E8C7..1E8D6 ; Mende_Kikakui
     'Zzzz',  # 1E8D7..1E8FF ; Unknown
-    'Adlm',  # 1E900..1E94A ; Adlam
-    'Zzzz',  # 1E94B..1E94F ; Unknown
+    'Adlm',  # 1E900..1E94B ; Adlam
+    'Zzzz',  # 1E94C..1E94F ; Unknown
     'Adlm',  # 1E950..1E959 ; Adlam
     'Zzzz',  # 1E95A..1E95D ; Unknown
     'Adlm',  # 1E95E..1E95F ; Adlam
     'Zzzz',  # 1E960..1EC70 ; Unknown
     'Zyyy',  # 1EC71..1ECB4 ; Common
-    'Zzzz',  # 1ECB5..1EDFF ; Unknown
+    'Zzzz',  # 1ECB5..1ED00 ; Unknown
+    'Zyyy',  # 1ED01..1ED3D ; Common
+    'Zzzz',  # 1ED3E..1EDFF ; Unknown
     'Arab',  # 1EE00..1EE03 ; Arabic
     'Zzzz',  # 1EE04..1EE04 ; Unknown
     'Arab',  # 1EE05..1EE1F ; Arabic
@@ -3026,8 +3066,8 @@
     'Zzzz',  # 1F0F6..1F0FF ; Unknown
     'Zyyy',  # 1F100..1F10C ; Common
     'Zzzz',  # 1F10D..1F10F ; Unknown
-    'Zyyy',  # 1F110..1F16B ; Common
-    'Zzzz',  # 1F16C..1F16F ; Unknown
+    'Zyyy',  # 1F110..1F16C ; Common
+    'Zzzz',  # 1F16D..1F16F ; Unknown
     'Zyyy',  # 1F170..1F1AC ; Common
     'Zzzz',  # 1F1AD..1F1E5 ; Unknown
     'Zyyy',  # 1F1E6..1F1FF ; Common
@@ -3042,16 +3082,18 @@
     'Zzzz',  # 1F252..1F25F ; Unknown
     'Zyyy',  # 1F260..1F265 ; Common
     'Zzzz',  # 1F266..1F2FF ; Unknown
-    'Zyyy',  # 1F300..1F6D4 ; Common
-    'Zzzz',  # 1F6D5..1F6DF ; Unknown
+    'Zyyy',  # 1F300..1F6D5 ; Common
+    'Zzzz',  # 1F6D6..1F6DF ; Unknown
     'Zyyy',  # 1F6E0..1F6EC ; Common
     'Zzzz',  # 1F6ED..1F6EF ; Unknown
-    'Zyyy',  # 1F6F0..1F6F9 ; Common
-    'Zzzz',  # 1F6FA..1F6FF ; Unknown
+    'Zyyy',  # 1F6F0..1F6FA ; Common
+    'Zzzz',  # 1F6FB..1F6FF ; Unknown
     'Zyyy',  # 1F700..1F773 ; Common
     'Zzzz',  # 1F774..1F77F ; Unknown
     'Zyyy',  # 1F780..1F7D8 ; Common
-    'Zzzz',  # 1F7D9..1F7FF ; Unknown
+    'Zzzz',  # 1F7D9..1F7DF ; Unknown
+    'Zyyy',  # 1F7E0..1F7EB ; Common
+    'Zzzz',  # 1F7EC..1F7FF ; Unknown
     'Zyyy',  # 1F800..1F80B ; Common
     'Zzzz',  # 1F80C..1F80F ; Unknown
     'Zyyy',  # 1F810..1F847 ; Common
@@ -3063,25 +3105,29 @@
     'Zyyy',  # 1F890..1F8AD ; Common
     'Zzzz',  # 1F8AE..1F8FF ; Unknown
     'Zyyy',  # 1F900..1F90B ; Common
-    'Zzzz',  # 1F90C..1F90F ; Unknown
-    'Zyyy',  # 1F910..1F93E ; Common
-    'Zzzz',  # 1F93F..1F93F ; Unknown
-    'Zyyy',  # 1F940..1F970 ; Common
-    'Zzzz',  # 1F971..1F972 ; Unknown
+    'Zzzz',  # 1F90C..1F90C ; Unknown
+    'Zyyy',  # 1F90D..1F971 ; Common
+    'Zzzz',  # 1F972..1F972 ; Unknown
     'Zyyy',  # 1F973..1F976 ; Common
     'Zzzz',  # 1F977..1F979 ; Unknown
-    'Zyyy',  # 1F97A..1F97A ; Common
-    'Zzzz',  # 1F97B..1F97B ; Unknown
-    'Zyyy',  # 1F97C..1F9A2 ; Common
-    'Zzzz',  # 1F9A3..1F9AF ; Unknown
-    'Zyyy',  # 1F9B0..1F9B9 ; Common
-    'Zzzz',  # 1F9BA..1F9BF ; Unknown
-    'Zyyy',  # 1F9C0..1F9C2 ; Common
-    'Zzzz',  # 1F9C3..1F9CF ; Unknown
-    'Zyyy',  # 1F9D0..1F9FF ; Common
-    'Zzzz',  # 1FA00..1FA5F ; Unknown
+    'Zyyy',  # 1F97A..1F9A2 ; Common
+    'Zzzz',  # 1F9A3..1F9A4 ; Unknown
+    'Zyyy',  # 1F9A5..1F9AA ; Common
+    'Zzzz',  # 1F9AB..1F9AD ; Unknown
+    'Zyyy',  # 1F9AE..1F9CA ; Common
+    'Zzzz',  # 1F9CB..1F9CC ; Unknown
+    'Zyyy',  # 1F9CD..1FA53 ; Common
+    'Zzzz',  # 1FA54..1FA5F ; Unknown
     'Zyyy',  # 1FA60..1FA6D ; Common
-    'Zzzz',  # 1FA6E..1FFFF ; Unknown
+    'Zzzz',  # 1FA6E..1FA6F ; Unknown
+    'Zyyy',  # 1FA70..1FA73 ; Common
+    'Zzzz',  # 1FA74..1FA77 ; Unknown
+    'Zyyy',  # 1FA78..1FA7A ; Common
+    'Zzzz',  # 1FA7B..1FA7F ; Unknown
+    'Zyyy',  # 1FA80..1FA82 ; Common
+    'Zzzz',  # 1FA83..1FA8F ; Unknown
+    'Zyyy',  # 1FA90..1FA95 ; Common
+    'Zzzz',  # 1FA96..1FFFF ; Unknown
     'Hani',  # 20000..2A6D6 ; Han
     'Zzzz',  # 2A6D7..2A6FF ; Unknown
     'Hani',  # 2A700..2B734 ; Han
@@ -3135,6 +3181,7 @@
     'Dupl': 'Duployan',
     'Egyp': 'Egyptian_Hieroglyphs',
     'Elba': 'Elbasan',
+    'Elym': 'Elymaic',
     'Ethi': 'Ethiopic',
     'Geor': 'Georgian',
     'Glag': 'Glagolitic',
@@ -3153,6 +3200,7 @@
     'Hira': 'Hiragana',
     'Hluw': 'Anatolian_Hieroglyphs',
     'Hmng': 'Pahawh_Hmong',
+    'Hmnp': 'Nyiakeng_Puachue_Hmong',
     'Hrkt': 'Katakana_Or_Hiragana',
     'Hung': 'Old_Hungarian',
     'Ital': 'Old_Italic',
@@ -3190,6 +3238,7 @@
     'Mtei': 'Meetei_Mayek',
     'Mult': 'Multani',
     'Mymr': 'Myanmar',
+    'Nand': 'Nandinagari',
     'Narb': 'Old_North_Arabian',
     'Nbat': 'Nabataean',
     'Newa': 'Newa',
@@ -3246,6 +3295,7 @@
     'Ugar': 'Ugaritic',
     'Vaii': 'Vai',
     'Wara': 'Warang_Citi',
+    'Wcho': 'Wancho',
     'Xpeo': 'Old_Persian',
     'Xsux': 'Cuneiform',
     'Yiii': 'Yi',
diff --git a/Lib/fontTools/varLib/cff.py b/Lib/fontTools/varLib/cff.py
index a8da214..bcafdee 100755
--- a/Lib/fontTools/varLib/cff.py
+++ b/Lib/fontTools/varLib/cff.py
@@ -161,7 +161,7 @@
 		For each key, step through each relevant source font Private dict, and
 		build a list of values to blend.
 	The 'relevant' source fonts are selected by first getting the right
-	submodel using model_keys[vsindex]. The indices of the
+	submodel using vsindex_dict[vsindex]. The indices of the
 	subModel.locations are mapped to source font list indices by
 	assuming the latter order is the same as the order of the
 	var_model.locations. I can then get the index of each subModel
@@ -180,7 +180,7 @@
 		# At the moment, no PrivateDict has a vsindex key, but let's support
 		# how it should work. See comment at end of
 		# merge_charstrings() - still need to optimize use of vsindex.
-		sub_model, model_keys = vsindex_dict[vsindex]
+		sub_model, _ = vsindex_dict[vsindex]
 		master_indices = []
 		for loc in sub_model.locations[1:]:
 			i = var_model.locations.index(loc) - 1
@@ -270,7 +270,9 @@
 	num_regions = len(region_fonts)
 	topDict = default_font['CFF '].cff.topDictIndex[0]
 	if not hasattr(topDict, 'FDSelect'):
-		fd_map[0] = [0]*num_regions
+		# All glyphs reference only one FontDict. 
+		# Map the FD index for regions to index 0.
+		fd_map[0] = {ri:0 for ri in range(num_regions)}
 		return fd_map
 
 	gname_mapping = {}
@@ -317,6 +319,19 @@
 		return None
 	return charstrings[glyphName]
 
+def _add_new_vsindex(model, key, masterSupports, vsindex_dict,
+		vsindex_by_key, varDataList):
+	varTupleIndexes = []
+	for support in model.supports[1:]:
+		if support not in masterSupports:
+			masterSupports.append(support)
+		varTupleIndexes.append(masterSupports.index(support))
+	var_data = varLib.builder.buildVarData(varTupleIndexes, None, False)
+	vsindex = len(vsindex_dict)
+	vsindex_by_key[key] = vsindex
+	vsindex_dict[vsindex] = (model, [key])
+	varDataList.append(var_data)
+	return vsindex
 
 def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel):
 
@@ -365,24 +380,24 @@
 
 		# If the charstring required a new model, create
 		# a VarData table to go with, and set vsindex.
+		key = tuple(v is not None for v in all_cs)
 		try:
-			key = tuple(v is not None for v in all_cs)
 			vsindex = vsindex_by_key[key]
 		except KeyError:
-			varTupleIndexes = []
-			for support in model.supports[1:]:
-				if support not in masterSupports:
-					masterSupports.append(support)
-				varTupleIndexes.append(masterSupports.index(support))
-			var_data = varLib.builder.buildVarData(varTupleIndexes, None, False)
-			vsindex = len(vsindex_dict)
-			vsindex_by_key[key] = vsindex
-			vsindex_dict[vsindex] = (model, [key])
-			varDataList.append(var_data)
+			vsindex = _add_new_vsindex(model, key, masterSupports, vsindex_dict,
+				vsindex_by_key, varDataList)
 		# We do not need to check for an existing new_cs.private.vsindex,
 		# as we know it doesn't exist yet.
 		if vsindex != 0:
 			new_cs.program[:0] = [vsindex, 'vsindex']
+			
+	# If there is no variation in any of the charstrings, then vsindex_dict
+	# never gets built. This could still be needed if there is variation 
+	# in the PrivatDict, so we will build the default data for vsindex = 0.
+	if not vsindex_dict:
+		key = (True,) * num_masters
+		_add_new_vsindex(model, key, masterSupports, vsindex_dict,
+			vsindex_by_key, varDataList)
 	cvData = CVarData(varDataList=varDataList, masterSupports=masterSupports,
 						vsindex_dict=vsindex_dict)
 	# XXX To do: optimize use of vsindex between the PrivateDicts and
diff --git a/Lib/fontTools/varLib/featureVars.py b/Lib/fontTools/varLib/featureVars.py
index de2808d..4caf30a 100644
--- a/Lib/fontTools/varLib/featureVars.py
+++ b/Lib/fontTools/varLib/featureVars.py
@@ -342,7 +342,7 @@
     langrec = ot.LangSysRecord()
     langrec.LangSys = ot.LangSys()
     langrec.LangSys.ReqFeatureIndex = 0xFFFF
-    langrec.LangSys.FeatureIndex = [0]
+    langrec.LangSys.FeatureIndex = []
     srec.Script.DefaultLangSys = langrec.LangSys
 
     gsub.ScriptList.ScriptRecord.append(srec)
diff --git a/Lib/fontTools/varLib/merger.py b/Lib/fontTools/varLib/merger.py
index b4b1705..cd16ace 100644
--- a/Lib/fontTools/varLib/merger.py
+++ b/Lib/fontTools/varLib/merger.py
@@ -2,6 +2,8 @@
 Merge OpenType Layout tables (GDEF / GPOS / GSUB).
 """
 from __future__ import print_function, division, absolute_import
+import copy
+from operator import ior
 from fontTools.misc.py23 import *
 from fontTools.misc.fixedTools import otRound
 from fontTools.misc import classifyTools
@@ -12,6 +14,7 @@
 from fontTools.varLib.models import nonNone, allNone, allEqual, allEqualTo
 from fontTools.varLib.varStore import VarStoreInstancer
 from functools import reduce
+from fontTools.otlLib.builder import buildSinglePos
 
 
 class Merger(object):
@@ -455,7 +458,7 @@
 					exemplarGlyph = next(iter(classSet))
 					klass = classDef2.get(exemplarGlyph, 0)
 					rec2 = oldClass2Records[klass]
-				class2Records.append(rec2)
+				class2Records.append(copy.deepcopy(rec2))
 			class1Records.append(rec1new)
 		new_matrices.append(class1Records)
 	matrices = new_matrices
@@ -726,6 +729,30 @@
 
 	return lst
 
+def _Lookup_SinglePos_subtables_flatten(lst, font, min_inclusive_rec_format):
+	glyphs, _ = _merge_GlyphOrders(font,
+		[v.Coverage.glyphs for v in lst], None)
+	num_glyphs = len(glyphs)
+	new = ot.SinglePos()
+	new.Format = 2
+	new.ValueFormat = min_inclusive_rec_format
+	new.Coverage = ot.Coverage()
+	new.Coverage.glyphs = glyphs
+	new.ValueCount = num_glyphs
+	new.Value = [None] * num_glyphs
+	for singlePos in lst:
+		if singlePos.Format == 1:
+			val_rec = singlePos.Value
+			for gname in singlePos.Coverage.glyphs:
+				i = glyphs.index(gname)
+				new.Value[i] = copy.deepcopy(val_rec)
+		elif singlePos.Format == 2:
+			for j, gname in enumerate(singlePos.Coverage.glyphs):
+				val_rec = singlePos.Value[j]
+				i = glyphs.index(gname)
+				new.Value[i] = copy.deepcopy(val_rec)
+	return [new]
+
 @AligningMerger.merger(ot.Lookup)
 def merge(merger, self, lst):
 	subtables = merger.lookup_subtables = [l.SubTable for l in lst]
@@ -745,12 +772,28 @@
 	isPairPos = self.SubTable and isinstance(self.SubTable[0], ot.PairPos)
 
 	if isPairPos:
-
 		# AFDKO and feaLib sometimes generate two Format1 subtables instead of one.
 		# Merge those before continuing.
 		# https://github.com/fonttools/fonttools/issues/719
 		self.SubTable = _Lookup_PairPos_subtables_canonicalize(self.SubTable, merger.font)
 		subtables = merger.lookup_subtables = [_Lookup_PairPos_subtables_canonicalize(st, merger.font) for st in subtables]
+	else:
+		isSinglePos = self.SubTable and isinstance(self.SubTable[0], ot.SinglePos)
+		if isSinglePos:
+			numSubtables = [len(st) for st in subtables]
+			if not all([nums == numSubtables[0] for nums in numSubtables]):
+				# Flatten list of SinglePos subtables to single Format 2 subtable,
+				# with all value records set to the rec format type.
+				# We use buildSinglePos() to optimize the lookup after merging.
+				valueFormatList = [t.ValueFormat for st in subtables for t in st]
+				# Find the minimum value record that can accomodate all the singlePos subtables.
+				mirf = reduce(ior, valueFormatList)
+				self.SubTable = _Lookup_SinglePos_subtables_flatten(self.SubTable, merger.font, mirf)
+				subtables = merger.lookup_subtables = [
+					_Lookup_SinglePos_subtables_flatten(st, merger.font, mirf) for st in subtables]
+				flattened = True
+			else:
+				flattened = False
 
 	merger.mergeLists(self.SubTable, subtables)
 	self.SubTableCount = len(self.SubTable)
@@ -768,6 +811,16 @@
 			self.SubTable.pop(-1)
 			self.SubTableCount -= 1
 
+	elif isSinglePos and flattened:
+		singlePosTable = self.SubTable[0]
+		glyphs = singlePosTable.Coverage.glyphs
+		# We know that singlePosTable is Format 2, as this is set
+		# in _Lookup_SinglePos_subtables_flatten.
+		singlePosMapping = {
+			gname: valRecord
+			for gname, valRecord in zip(glyphs, singlePosTable.Value)
+		}
+		self.SubTable = buildSinglePos(singlePosMapping, merger.font.getReverseGlyphMap())
 	merger.mergeObjects(self, lst, exclude=['SubTable', 'SubTableCount'])
 
 	del merger.lookup_subtables
diff --git a/Lib/fonttools.egg-info/PKG-INFO b/Lib/fonttools.egg-info/PKG-INFO
index b302ec9..74bb40d 100644
--- a/Lib/fonttools.egg-info/PKG-INFO
+++ b/Lib/fonttools.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: fonttools
-Version: 3.42.0
+Version: 3.43.1
 Summary: Tools to manipulate font files
 Home-page: http://github.com/fonttools/fonttools
 Author: Just van Rossum
@@ -415,6 +415,37 @@
         Changelog
         ~~~~~~~~~
         
+        3.43.1 (released 2019-06-19)
+        ----------------------------
+        
+        - [subset] Fixed regression when passing ``--flavor=woff2`` option with an input font
+          that was already compressed as WOFF 1.0 (#1650).
+        
+        3.43.0 (released 2019-06-18)
+        ----------------------------
+        
+        - [woff2] Added support for compressing/decompressing WOFF2 fonts with non-transformed
+          ``glyf`` and ``loca`` tables, as well as with transformed ``hmtx`` table.
+          Removed ``Snippets/woff2_compress.py`` and ``Snippets/woff2_decompress.py`` scripts,
+          and replaced them with a new console entry point ``fonttools ttLib.woff2``
+          that provides two sub-commands ``compress`` and ``decompress``.
+        - [varLib.cff] Fixed bug when merging CFF2 ``PrivateDicts``. The ``PrivateDict``
+          data from the first region font was incorrecty used for all subsequent fonts.
+          The bug would only affect variable CFF2 fonts with hinting (#1643, #1644).
+          Also, fixed a merging bug when VF masters have no blends or marking glyphs (#1632,
+          #1642).
+        - [loggingTools] Removed unused backport of ``LastResortLogger`` class.
+        - [subset] Gracefully handle partial MATH table (#1635).
+        - [featureVars] Avoid duplicate references to ``rvrn`` feature record in
+          ``DefaultLangSys`` tables when calling ``addFeatureVariations`` on a font that
+          does not already have a ``GSUB`` table (aa8a5bc6).
+        - [varLib] Fixed merging of class-based kerning. Before, the process could introduce
+          rogue kerning values and variations for random classes against class zero (everything
+          not otherwise classed).
+        - [varLib] Fixed merging GPOS tables from master fonts with different number of
+          ``SinglePos`` subtables (#1621, #1641).
+        - [unicodedata] Updated Blocks, Scripts and ScriptExtensions to Unicode 12.1.
+        
         3.42.0 (released 2019-05-28)
         ----------------------------
         
@@ -1756,13 +1787,13 @@
 Classifier: Topic :: Text Processing :: Fonts
 Classifier: Topic :: Multimedia :: Graphics
 Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
-Provides-Extra: all
-Provides-Extra: symfont
-Provides-Extra: graphite
-Provides-Extra: unicode
-Provides-Extra: interpolatable
 Provides-Extra: lxml
+Provides-Extra: interpolatable
+Provides-Extra: unicode
+Provides-Extra: type1
+Provides-Extra: all
 Provides-Extra: ufo
+Provides-Extra: graphite
 Provides-Extra: woff
 Provides-Extra: plot
-Provides-Extra: type1
+Provides-Extra: symfont
diff --git a/Lib/fonttools.egg-info/SOURCES.txt b/Lib/fonttools.egg-info/SOURCES.txt
index 4ff321a..063c93c 100644
--- a/Lib/fonttools.egg-info/SOURCES.txt
+++ b/Lib/fonttools.egg-info/SOURCES.txt
@@ -328,8 +328,6 @@
 Snippets/rename-fonts.py
 Snippets/subset-fpgm.py
 Snippets/svg2glif.py
-Snippets/woff2_compress.py
-Snippets/woff2_decompress.py
 Tests/agl_test.py
 Tests/merge_test.py
 Tests/unicodedata_test.py
@@ -648,6 +646,7 @@
 Tests/pens/t2CharStringPen_test.py
 Tests/pens/ttGlyphPen_test.py
 Tests/subset/subset_test.py
+Tests/subset/data/Lobster.subset.otf
 Tests/subset/data/Lobster.subset.ttx
 Tests/subset/data/NotdefWidthCID-Regular.ttx
 Tests/subset/data/TestANKR.ttx
@@ -682,6 +681,7 @@
 Tests/subset/data/expect_keep_math.ttx
 Tests/subset/data/expect_lcar_0.ttx
 Tests/subset/data/expect_lcar_1.ttx
+Tests/subset/data/expect_math_partial.ttx
 Tests/subset/data/expect_no_hinting_CFF.ttx
 Tests/subset/data/expect_no_hinting_TTF.ttx
 Tests/subset/data/expect_no_hinting_desubroutinize_CFF.ttx
@@ -698,6 +698,7 @@
 Tests/subset/data/test_cntrmask_CFF.ttx
 Tests/subset/data/test_hinted_subrs_CFF.desub.ttx
 Tests/subset/data/test_hinted_subrs_CFF.ttx
+Tests/subset/data/test_math_partial.ttx
 Tests/svgLib/path/__init__.py
 Tests/svgLib/path/parser_test.py
 Tests/svgLib/path/path_test.py
@@ -1442,13 +1443,21 @@
 Tests/varLib/data/InterpolateLayout.designspace
 Tests/varLib/data/InterpolateLayout2.designspace
 Tests/varLib/data/InterpolateLayout3.designspace
+Tests/varLib/data/KerningMerging.designspace
 Tests/varLib/data/SparseMasters.designspace
 Tests/varLib/data/TestCFF2.designspace
+Tests/varLib/data/TestNonMarkingCFF2.designspace
 Tests/varLib/data/TestSparseCFF2VF.designspace
 Tests/varLib/data/TestVVAR.designspace
+Tests/varLib/data/test_vpal.designspace
 Tests/varLib/data/master_cff2/TestCFF2_Black.ttx
 Tests/varLib/data/master_cff2/TestCFF2_ExtraLight.ttx
 Tests/varLib/data/master_cff2/TestCFF2_Regular.ttx
+Tests/varLib/data/master_kerning_merging/0.ttx
+Tests/varLib/data/master_kerning_merging/1.ttx
+Tests/varLib/data/master_kerning_merging/2.ttx
+Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx
+Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx
 Tests/varLib/data/master_sparse_cff2/MasterSet_Kanji-w0.00.ttx
 Tests/varLib/data/master_sparse_cff2/MasterSet_Kanji-w1000.00.ttx
 Tests/varLib/data/master_sparse_cff2/MasterSet_Kanji-w439.00.ttx
@@ -1747,6 +1756,8 @@
 Tests/varLib/data/master_ufo/TestFamily4-Regular.ufo/glyphs.public.background/dieresiscomb.glif
 Tests/varLib/data/master_ufo/TestFamily4-Regular.ufo/glyphs.public.background/n.glif
 Tests/varLib/data/master_ufo/TestFamily4-Regular.ufo/glyphs.public.background/o.glif
+Tests/varLib/data/master_vpal_test/master_vpal_test_0.ttx
+Tests/varLib/data/master_vpal_test/master_vpal_test_1.ttx
 Tests/varLib/data/master_vvar_cff2/TestVVAR.0.ttx
 Tests/varLib/data/master_vvar_cff2/TestVVAR.1.ttx
 Tests/varLib/data/test_results/Build.ttx
@@ -1785,7 +1796,9 @@
 Tests/varLib/data/test_results/Mutator_Getvar-instance.ttx
 Tests/varLib/data/test_results/Mutator_IUP-instance.ttx
 Tests/varLib/data/test_results/SparseMasters.ttx
+Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx
 Tests/varLib/data/test_results/TestSparseCFF2VF.ttx
 Tests/varLib/data/test_results/TestVVAR.ttx
+Tests/varLib/data/test_results/test_vpal.ttx
 Tests/voltLib/lexer_test.py
 Tests/voltLib/parser_test.py
\ No newline at end of file
diff --git a/METADATA b/METADATA
index f9e8a0e..ef73891 100644
--- a/METADATA
+++ b/METADATA
@@ -7,12 +7,12 @@
   }
   url {
     type: ARCHIVE
-    value: "https://github.com/fonttools/fonttools/releases/download/3.42.0/fonttools-3.42.0.zip"
+    value: "https://github.com/fonttools/fonttools/releases/download/3.43.1/fonttools-3.43.1.zip"
   }
-  version: "3.42.0"
+  version: "3.43.1"
   last_upgrade_date {
     year: 2019
-    month: 5
-    day: 31
+    month: 6
+    day: 19
   }
 }
diff --git a/NEWS.rst b/NEWS.rst
index c862424..b7b1b50 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -1,3 +1,34 @@
+3.43.1 (released 2019-06-19)
+----------------------------
+
+- [subset] Fixed regression when passing ``--flavor=woff2`` option with an input font
+  that was already compressed as WOFF 1.0 (#1650).
+
+3.43.0 (released 2019-06-18)
+----------------------------
+
+- [woff2] Added support for compressing/decompressing WOFF2 fonts with non-transformed
+  ``glyf`` and ``loca`` tables, as well as with transformed ``hmtx`` table.
+  Removed ``Snippets/woff2_compress.py`` and ``Snippets/woff2_decompress.py`` scripts,
+  and replaced them with a new console entry point ``fonttools ttLib.woff2``
+  that provides two sub-commands ``compress`` and ``decompress``.
+- [varLib.cff] Fixed bug when merging CFF2 ``PrivateDicts``. The ``PrivateDict``
+  data from the first region font was incorrecty used for all subsequent fonts.
+  The bug would only affect variable CFF2 fonts with hinting (#1643, #1644).
+  Also, fixed a merging bug when VF masters have no blends or marking glyphs (#1632,
+  #1642).
+- [loggingTools] Removed unused backport of ``LastResortLogger`` class.
+- [subset] Gracefully handle partial MATH table (#1635).
+- [featureVars] Avoid duplicate references to ``rvrn`` feature record in
+  ``DefaultLangSys`` tables when calling ``addFeatureVariations`` on a font that
+  does not already have a ``GSUB`` table (aa8a5bc6).
+- [varLib] Fixed merging of class-based kerning. Before, the process could introduce
+  rogue kerning values and variations for random classes against class zero (everything
+  not otherwise classed).
+- [varLib] Fixed merging GPOS tables from master fonts with different number of
+  ``SinglePos`` subtables (#1621, #1641).
+- [unicodedata] Updated Blocks, Scripts and ScriptExtensions to Unicode 12.1.
+
 3.42.0 (released 2019-05-28)
 ----------------------------
 
diff --git a/PKG-INFO b/PKG-INFO
index b302ec9..74bb40d 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: fonttools
-Version: 3.42.0
+Version: 3.43.1
 Summary: Tools to manipulate font files
 Home-page: http://github.com/fonttools/fonttools
 Author: Just van Rossum
@@ -415,6 +415,37 @@
         Changelog
         ~~~~~~~~~
         
+        3.43.1 (released 2019-06-19)
+        ----------------------------
+        
+        - [subset] Fixed regression when passing ``--flavor=woff2`` option with an input font
+          that was already compressed as WOFF 1.0 (#1650).
+        
+        3.43.0 (released 2019-06-18)
+        ----------------------------
+        
+        - [woff2] Added support for compressing/decompressing WOFF2 fonts with non-transformed
+          ``glyf`` and ``loca`` tables, as well as with transformed ``hmtx`` table.
+          Removed ``Snippets/woff2_compress.py`` and ``Snippets/woff2_decompress.py`` scripts,
+          and replaced them with a new console entry point ``fonttools ttLib.woff2``
+          that provides two sub-commands ``compress`` and ``decompress``.
+        - [varLib.cff] Fixed bug when merging CFF2 ``PrivateDicts``. The ``PrivateDict``
+          data from the first region font was incorrecty used for all subsequent fonts.
+          The bug would only affect variable CFF2 fonts with hinting (#1643, #1644).
+          Also, fixed a merging bug when VF masters have no blends or marking glyphs (#1632,
+          #1642).
+        - [loggingTools] Removed unused backport of ``LastResortLogger`` class.
+        - [subset] Gracefully handle partial MATH table (#1635).
+        - [featureVars] Avoid duplicate references to ``rvrn`` feature record in
+          ``DefaultLangSys`` tables when calling ``addFeatureVariations`` on a font that
+          does not already have a ``GSUB`` table (aa8a5bc6).
+        - [varLib] Fixed merging of class-based kerning. Before, the process could introduce
+          rogue kerning values and variations for random classes against class zero (everything
+          not otherwise classed).
+        - [varLib] Fixed merging GPOS tables from master fonts with different number of
+          ``SinglePos`` subtables (#1621, #1641).
+        - [unicodedata] Updated Blocks, Scripts and ScriptExtensions to Unicode 12.1.
+        
         3.42.0 (released 2019-05-28)
         ----------------------------
         
@@ -1756,13 +1787,13 @@
 Classifier: Topic :: Text Processing :: Fonts
 Classifier: Topic :: Multimedia :: Graphics
 Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
-Provides-Extra: all
-Provides-Extra: symfont
-Provides-Extra: graphite
-Provides-Extra: unicode
-Provides-Extra: interpolatable
 Provides-Extra: lxml
+Provides-Extra: interpolatable
+Provides-Extra: unicode
+Provides-Extra: type1
+Provides-Extra: all
 Provides-Extra: ufo
+Provides-Extra: graphite
 Provides-Extra: woff
 Provides-Extra: plot
-Provides-Extra: type1
+Provides-Extra: symfont
diff --git a/Snippets/woff2_compress.py b/Snippets/woff2_compress.py
deleted file mode 100755
index 689ebdc..0000000
--- a/Snippets/woff2_compress.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function, division, absolute_import
-from fontTools.misc.py23 import *
-from fontTools.ttLib import TTFont
-from fontTools.ttx import makeOutputFileName
-import sys
-import os
-
-
-def main(args=None):
-    if args is None:
-        args = sys.argv[1:]
-    if len(args) < 1:
-        print("One argument, the input filename, must be provided.", file=sys.stderr)
-        return 1
-
-    filename = args[0]
-    outfilename = makeOutputFileName(filename, outputDir=None, extension='.woff2')
-
-    print("Processing %s => %s" % (filename, outfilename))
-
-    font = TTFont(filename, recalcBBoxes=False, recalcTimestamp=False)
-    font.flavor = "woff2"
-    font.save(outfilename, reorderTables=False)
-
-
-if __name__ == '__main__':
-    sys.exit(main())
diff --git a/Snippets/woff2_decompress.py b/Snippets/woff2_decompress.py
deleted file mode 100755
index e7c1bea..0000000
--- a/Snippets/woff2_decompress.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function, division, absolute_import
-from fontTools.misc.py23 import *
-from fontTools.ttLib import TTFont
-from fontTools.ttx import makeOutputFileName
-import sys
-import os
-
-
-def make_output_name(filename):
-    with open(filename, "rb") as f:
-        f.seek(4)
-        sfntVersion = f.read(4)
-    assert len(sfntVersion) == 4, "not enough data"
-    ext = '.ttf' if sfntVersion == b"\x00\x01\x00\x00" else ".otf"
-    outfilename = makeOutputFileName(filename, outputDir=None, extension=ext)
-    return outfilename
-
-
-def main(args=None):
-    if args is None:
-        args = sys.argv[1:]
-    if len(args) < 1:
-        print("One argument, the input filename, must be provided.", file=sys.stderr)
-        return 1
-
-    filename = args[0]
-    outfilename = make_output_name(filename)
-
-    print("Processing %s => %s" % (filename, outfilename))
-
-    font = TTFont(filename, recalcBBoxes=False, recalcTimestamp=False)
-    font.flavor = None
-    font.save(outfilename, reorderTables=True)
-
-
-if __name__ == '__main__':
-    sys.exit(main())
diff --git a/Tests/feaLib/builder_test.py b/Tests/feaLib/builder_test.py
index eb80078..3d852af 100644
--- a/Tests/feaLib/builder_test.py
+++ b/Tests/feaLib/builder_test.py
@@ -513,10 +513,9 @@
         addOpenTypeFeatures(font, tree)
         assert "GSUB" in font
 
-    @unittest.skipIf(sys.version_info[0:2] < (3, 4),
-                     "assertLogs() was introduced in 3.4")
     def test_unsupported_subtable_break(self):
-        with self.assertLogs(level='WARNING') as logs:
+        logger = logging.getLogger("fontTools.feaLib.builder")
+        with CapturingLogHandler(logger, level='WARNING') as captor:
             self.build(
                 "feature test {"
                 "    pos a 10;"
@@ -524,9 +523,10 @@
                 "    pos b 10;"
                 "} test;"
             )
-        self.assertEqual(logs.output,
-                ['WARNING:fontTools.feaLib.builder:<features>:1:32: '
-                 'unsupported "subtable" statement for lookup type'])
+
+        captor.assertRegex(
+            '<features>:1:32: unsupported "subtable" statement for lookup type'
+        )
 
     def test_skip_featureNames_if_no_name_table(self):
         features = (
diff --git a/Tests/misc/loggingTools_test.py b/Tests/misc/loggingTools_test.py
index 18b71b1..fd64b8b 100644
--- a/Tests/misc/loggingTools_test.py
+++ b/Tests/misc/loggingTools_test.py
@@ -6,15 +6,11 @@
     configLogger,
     ChannelsFilter,
     LogMixin,
-    StderrHandler,
-    LastResortLogger,
-    _resetExistingLoggers,
 )
 import logging
 import textwrap
 import time
 import re
-import sys
 import pytest
 
 
@@ -179,32 +175,3 @@
     assert isinstance(b.log, logging.Logger)
     assert a.log.name == "loggingTools_test.A"
     assert b.log.name == "loggingTools_test.B"
-
-
-@pytest.mark.skipif(sys.version_info[:2] > (2, 7), reason="only for python2.7")
-@pytest.mark.parametrize(
-    "reset", [True, False], ids=["reset", "no-reset"]
-)
-def test_LastResortLogger(reset, capsys, caplog):
-    current = logging.getLoggerClass()
-    msg = "The quick brown fox jumps over the lazy dog"
-    try:
-        if reset:
-            _resetExistingLoggers()
-        else:
-            caplog.set_level(logging.ERROR, logger="myCustomLogger")
-        logging.lastResort = StderrHandler(logging.WARNING)
-        logging.setLoggerClass(LastResortLogger)
-        logger = logging.getLogger("myCustomLogger")
-        logger.error(msg)
-    finally:
-        del logging.lastResort
-        logging.setLoggerClass(current)
-
-    captured = capsys.readouterr()
-    if reset:
-        assert msg in captured.err
-        msg not in caplog.text
-    else:
-        msg in caplog.text
-        msg not in captured.err
diff --git a/Tests/subset/data/Lobster.subset.otf b/Tests/subset/data/Lobster.subset.otf
new file mode 100644
index 0000000..8147542
--- /dev/null
+++ b/Tests/subset/data/Lobster.subset.otf
Binary files differ
diff --git a/Tests/subset/data/expect_math_partial.ttx b/Tests/subset/data/expect_math_partial.ttx
new file mode 100644
index 0000000..34136e9
--- /dev/null
+++ b/Tests/subset/data/expect_math_partial.ttx
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.41">
+
+  <MATH>
+    <Version value="0x00010000"/>
+    <MathConstants>
+      <ScriptPercentScaleDown value="75"/>
+      <ScriptScriptPercentScaleDown value="60"/>
+      <DelimitedSubFormulaMinHeight value="1500"/>
+      <DisplayOperatorMinHeight value="1450"/>
+      <MathLeading>
+        <Value value="150"/>
+      </MathLeading>
+      <AxisHeight>
+        <Value value="250"/>
+      </AxisHeight>
+      <AccentBaseHeight>
+        <Value value="450"/>
+      </AccentBaseHeight>
+      <FlattenedAccentBaseHeight>
+        <Value value="662"/>
+      </FlattenedAccentBaseHeight>
+      <SubscriptShiftDown>
+        <Value value="250"/>
+      </SubscriptShiftDown>
+      <SubscriptTopMax>
+        <Value value="400"/>
+      </SubscriptTopMax>
+      <SubscriptBaselineDropMin>
+        <Value value="50"/>
+      </SubscriptBaselineDropMin>
+      <SuperscriptShiftUp>
+        <Value value="400"/>
+      </SuperscriptShiftUp>
+      <SuperscriptShiftUpCramped>
+        <Value value="275"/>
+      </SuperscriptShiftUpCramped>
+      <SuperscriptBottomMin>
+        <Value value="125"/>
+      </SuperscriptBottomMin>
+      <SuperscriptBaselineDropMax>
+        <Value value="375"/>
+      </SuperscriptBaselineDropMax>
+      <SubSuperscriptGapMin>
+        <Value value="264"/>
+      </SubSuperscriptGapMin>
+      <SuperscriptBottomMaxWithSubscript>
+        <Value value="400"/>
+      </SuperscriptBottomMaxWithSubscript>
+      <SpaceAfterScript>
+        <Value value="41"/>
+      </SpaceAfterScript>
+      <UpperLimitGapMin>
+        <Value value="150"/>
+      </UpperLimitGapMin>
+      <UpperLimitBaselineRiseMin>
+        <Value value="300"/>
+      </UpperLimitBaselineRiseMin>
+      <LowerLimitGapMin>
+        <Value value="150"/>
+      </LowerLimitGapMin>
+      <LowerLimitBaselineDropMin>
+        <Value value="600"/>
+      </LowerLimitBaselineDropMin>
+      <StackTopShiftUp>
+        <Value value="480"/>
+      </StackTopShiftUp>
+      <StackTopDisplayStyleShiftUp>
+        <Value value="580"/>
+      </StackTopDisplayStyleShiftUp>
+      <StackBottomShiftDown>
+        <Value value="800"/>
+      </StackBottomShiftDown>
+      <StackBottomDisplayStyleShiftDown>
+        <Value value="900"/>
+      </StackBottomDisplayStyleShiftDown>
+      <StackGapMin>
+        <Value value="198"/>
+      </StackGapMin>
+      <StackDisplayStyleGapMin>
+        <Value value="462"/>
+      </StackDisplayStyleGapMin>
+      <StretchStackTopShiftUp>
+        <Value value="300"/>
+      </StretchStackTopShiftUp>
+      <StretchStackBottomShiftDown>
+        <Value value="600"/>
+      </StretchStackBottomShiftDown>
+      <StretchStackGapAboveMin>
+        <Value value="150"/>
+      </StretchStackGapAboveMin>
+      <StretchStackGapBelowMin>
+        <Value value="150"/>
+      </StretchStackGapBelowMin>
+      <FractionNumeratorShiftUp>
+        <Value value="480"/>
+      </FractionNumeratorShiftUp>
+      <FractionNumeratorDisplayStyleShiftUp>
+        <Value value="580"/>
+      </FractionNumeratorDisplayStyleShiftUp>
+      <FractionDenominatorShiftDown>
+        <Value value="480"/>
+      </FractionDenominatorShiftDown>
+      <FractionDenominatorDisplayStyleShiftDown>
+        <Value value="700"/>
+      </FractionDenominatorDisplayStyleShiftDown>
+      <FractionNumeratorGapMin>
+        <Value value="66"/>
+      </FractionNumeratorGapMin>
+      <FractionNumDisplayStyleGapMin>
+        <Value value="198"/>
+      </FractionNumDisplayStyleGapMin>
+      <FractionRuleThickness>
+        <Value value="66"/>
+      </FractionRuleThickness>
+      <FractionDenominatorGapMin>
+        <Value value="66"/>
+      </FractionDenominatorGapMin>
+      <FractionDenomDisplayStyleGapMin>
+        <Value value="198"/>
+      </FractionDenomDisplayStyleGapMin>
+      <SkewedFractionHorizontalGap>
+        <Value value="300"/>
+      </SkewedFractionHorizontalGap>
+      <SkewedFractionVerticalGap>
+        <Value value="66"/>
+      </SkewedFractionVerticalGap>
+      <OverbarVerticalGap>
+        <Value value="198"/>
+      </OverbarVerticalGap>
+      <OverbarRuleThickness>
+        <Value value="66"/>
+      </OverbarRuleThickness>
+      <OverbarExtraAscender>
+        <Value value="66"/>
+      </OverbarExtraAscender>
+      <UnderbarVerticalGap>
+        <Value value="198"/>
+      </UnderbarVerticalGap>
+      <UnderbarRuleThickness>
+        <Value value="66"/>
+      </UnderbarRuleThickness>
+      <UnderbarExtraDescender>
+        <Value value="66"/>
+      </UnderbarExtraDescender>
+      <RadicalVerticalGap>
+        <Value value="82"/>
+      </RadicalVerticalGap>
+      <RadicalDisplayStyleVerticalGap>
+        <Value value="186"/>
+      </RadicalDisplayStyleVerticalGap>
+      <RadicalRuleThickness>
+        <Value value="66"/>
+      </RadicalRuleThickness>
+      <RadicalExtraAscender>
+        <Value value="66"/>
+      </RadicalExtraAscender>
+      <RadicalKernBeforeDegree>
+        <Value value="277"/>
+      </RadicalKernBeforeDegree>
+      <RadicalKernAfterDegree>
+        <Value value="-555"/>
+      </RadicalKernAfterDegree>
+      <RadicalDegreeBottomRaisePercent value="70"/>
+    </MathConstants>
+  </MATH>
+
+</ttFont>
diff --git a/Tests/subset/data/test_math_partial.ttx b/Tests/subset/data/test_math_partial.ttx
new file mode 100644
index 0000000..c0a70da
--- /dev/null
+++ b/Tests/subset/data/test_math_partial.ttx
@@ -0,0 +1,391 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.41">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="A"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.10799"/>
+    <checkSumAdjustment value="0x266835f6"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00001011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Sun Jan 10 17:35:12 2016"/>
+    <modified value="Sat Jun  8 23:59:34 2019"/>
+    <xMin value="-761"/>
+    <yMin value="-509"/>
+    <xMax value="3000"/>
+    <yMax value="2566"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="8"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="750"/>
+    <descent value="-250"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="3000"/>
+    <minLeftSideBearing value="-761"/>
+    <minRightSideBearing value="-365"/>
+    <xMaxExtent value="3000"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="2"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x5000"/>
+    <numGlyphs value="2"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="4"/>
+    <xAvgCharWidth value="666"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000000"/>
+    <ySubscriptXSize value="500"/>
+    <ySubscriptYSize value="500"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="250"/>
+    <ySuperscriptXSize value="500"/>
+    <ySuperscriptYSize value="500"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="500"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="306"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="2"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="5"/>
+      <bProportion value="3"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="STIX"/>
+    <fsSelection value="00000000 11000000"/>
+    <usFirstCharIndex value="65"/>
+    <usLastCharIndex value="65"/>
+    <sTypoAscender value="750"/>
+    <sTypoDescender value="-250"/>
+    <sTypoLineGap value="0"/>
+    <usWinAscent value="2598"/>
+    <usWinDescent value="918"/>
+    <ulCodePageRange1 value="01100000 00000000 00000000 10011111"/>
+    <ulCodePageRange2 value="11011111 11010111 00000000 00000000"/>
+    <sxHeight value="450"/>
+    <sCapHeight value="662"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="2"/>
+  </OS_2>
+
+  <name>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      XITS Math
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+  </name>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_4>
+    <cmap_format_12 platformID="0" platEncID="4" format="12" reserved="0" length="28" language="0" nGroups="1">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_12>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_4>
+    <cmap_format_12 platformID="3" platEncID="10" format="12" reserved="0" length="28" language="0" nGroups="1">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_12>
+  </cmap>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+  <CFF>
+    <major value="1"/>
+    <minor value="0"/>
+    <CFFFont name="XITSMath">
+      <version value="1.108"/>
+      <Notice value="Copyright (c) 2001-2011 by the STI Pub Companies, consisting of the American Chemical Society, the American Institute of Physics, the American Mathematical Society, the American Physical Society, Elsevier, Inc., and The Institute of Electrical and Electronic Engineers, Inc.  Portions copyright (c) 1998-2003 by MicroPress, Inc.  Portions copyright (c) 1990 by Elsevier, Inc.  Portions copyright (c) 2009-2012 by Khaled Hosny.  All rights reserved. "/>
+      <FullName value="XITS Math"/>
+      <FamilyName value="XITS Math"/>
+      <Weight value="Regular"/>
+      <isFixedPitch value="0"/>
+      <ItalicAngle value="0"/>
+      <UnderlinePosition value="-50"/>
+      <UnderlineThickness value="50"/>
+      <PaintType value="0"/>
+      <CharstringType value="2"/>
+      <FontMatrix value="0.001 0 0 0.001 0 0"/>
+      <FontBBox value="-761 -509 3000 2566"/>
+      <StrokeWidth value="0"/>
+      <!-- charset is dumped separately as the 'GlyphOrder' element -->
+      <Encoding name="StandardEncoding"/>
+      <Private>
+        <BlueValues value="-14 0 450 460 662 676"/>
+        <BlueScale value="0.039625"/>
+        <BlueShift value="6"/>
+        <BlueFuzz value="1"/>
+        <StdHW value="66"/>
+        <StdVW value="66"/>
+        <StemSnapH value="23 28 31 34 38 43 50 54 63 66"/>
+        <StemSnapV value="39 43 48 52 56 59 66 73 79 83"/>
+        <ForceBold value="0"/>
+        <LanguageGroup value="0"/>
+        <ExpansionFactor value="0.06"/>
+        <initialRandomSeed value="0"/>
+        <defaultWidthX value="685"/>
+        <nominalWidthX value="601"/>
+        <Subrs>
+          <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+          <CharString index="0">
+            19 vlineto
+            -52 6 -14 21 -28 65 rrcurveto
+            -246 563 -20 0 -206 -488 rlineto
+            -59 -140 -9 -21 -58 -6 rrcurveto
+            -19 199 19 vlineto
+            -48 -22 10 31 hvcurveto
+            0 12 4 17 5 13 rrcurveto
+            46 114 262 0 41 -94 rlineto
+            12 -28 7 -27 0 -15 0 -9 -6 -11 -8 -4 -12 -7 -7 -2 -36 0 rrcurveto
+            -19 vlineto
+            return
+          </CharString>
+          <CharString index="1">
+            -231 0 115 275 rlineto
+            return
+          </CharString>
+        </Subrs>
+      </Private>
+      <CharStrings>
+        <CharString name=".notdef">
+          -351 endchar
+        </CharString>
+        <CharString name="A">
+          121 0 20 196 41 397 20 hstem
+          707 hmoveto
+          -107 callsubr
+          -5 257 rmoveto
+          -106 callsubr
+          endchar
+        </CharString>
+      </CharStrings>
+    </CFFFont>
+
+    <GlobalSubrs>
+      <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+    </GlobalSubrs>
+  </CFF>
+
+  <MATH>
+    <Version value="0x00010000"/>
+    <MathConstants>
+      <ScriptPercentScaleDown value="75"/>
+      <ScriptScriptPercentScaleDown value="60"/>
+      <DelimitedSubFormulaMinHeight value="1500"/>
+      <DisplayOperatorMinHeight value="1450"/>
+      <MathLeading>
+        <Value value="150"/>
+      </MathLeading>
+      <AxisHeight>
+        <Value value="250"/>
+      </AxisHeight>
+      <AccentBaseHeight>
+        <Value value="450"/>
+      </AccentBaseHeight>
+      <FlattenedAccentBaseHeight>
+        <Value value="662"/>
+      </FlattenedAccentBaseHeight>
+      <SubscriptShiftDown>
+        <Value value="250"/>
+      </SubscriptShiftDown>
+      <SubscriptTopMax>
+        <Value value="400"/>
+      </SubscriptTopMax>
+      <SubscriptBaselineDropMin>
+        <Value value="50"/>
+      </SubscriptBaselineDropMin>
+      <SuperscriptShiftUp>
+        <Value value="400"/>
+      </SuperscriptShiftUp>
+      <SuperscriptShiftUpCramped>
+        <Value value="275"/>
+      </SuperscriptShiftUpCramped>
+      <SuperscriptBottomMin>
+        <Value value="125"/>
+      </SuperscriptBottomMin>
+      <SuperscriptBaselineDropMax>
+        <Value value="375"/>
+      </SuperscriptBaselineDropMax>
+      <SubSuperscriptGapMin>
+        <Value value="264"/>
+      </SubSuperscriptGapMin>
+      <SuperscriptBottomMaxWithSubscript>
+        <Value value="400"/>
+      </SuperscriptBottomMaxWithSubscript>
+      <SpaceAfterScript>
+        <Value value="41"/>
+      </SpaceAfterScript>
+      <UpperLimitGapMin>
+        <Value value="150"/>
+      </UpperLimitGapMin>
+      <UpperLimitBaselineRiseMin>
+        <Value value="300"/>
+      </UpperLimitBaselineRiseMin>
+      <LowerLimitGapMin>
+        <Value value="150"/>
+      </LowerLimitGapMin>
+      <LowerLimitBaselineDropMin>
+        <Value value="600"/>
+      </LowerLimitBaselineDropMin>
+      <StackTopShiftUp>
+        <Value value="480"/>
+      </StackTopShiftUp>
+      <StackTopDisplayStyleShiftUp>
+        <Value value="580"/>
+      </StackTopDisplayStyleShiftUp>
+      <StackBottomShiftDown>
+        <Value value="800"/>
+      </StackBottomShiftDown>
+      <StackBottomDisplayStyleShiftDown>
+        <Value value="900"/>
+      </StackBottomDisplayStyleShiftDown>
+      <StackGapMin>
+        <Value value="198"/>
+      </StackGapMin>
+      <StackDisplayStyleGapMin>
+        <Value value="462"/>
+      </StackDisplayStyleGapMin>
+      <StretchStackTopShiftUp>
+        <Value value="300"/>
+      </StretchStackTopShiftUp>
+      <StretchStackBottomShiftDown>
+        <Value value="600"/>
+      </StretchStackBottomShiftDown>
+      <StretchStackGapAboveMin>
+        <Value value="150"/>
+      </StretchStackGapAboveMin>
+      <StretchStackGapBelowMin>
+        <Value value="150"/>
+      </StretchStackGapBelowMin>
+      <FractionNumeratorShiftUp>
+        <Value value="480"/>
+      </FractionNumeratorShiftUp>
+      <FractionNumeratorDisplayStyleShiftUp>
+        <Value value="580"/>
+      </FractionNumeratorDisplayStyleShiftUp>
+      <FractionDenominatorShiftDown>
+        <Value value="480"/>
+      </FractionDenominatorShiftDown>
+      <FractionDenominatorDisplayStyleShiftDown>
+        <Value value="700"/>
+      </FractionDenominatorDisplayStyleShiftDown>
+      <FractionNumeratorGapMin>
+        <Value value="66"/>
+      </FractionNumeratorGapMin>
+      <FractionNumDisplayStyleGapMin>
+        <Value value="198"/>
+      </FractionNumDisplayStyleGapMin>
+      <FractionRuleThickness>
+        <Value value="66"/>
+      </FractionRuleThickness>
+      <FractionDenominatorGapMin>
+        <Value value="66"/>
+      </FractionDenominatorGapMin>
+      <FractionDenomDisplayStyleGapMin>
+        <Value value="198"/>
+      </FractionDenomDisplayStyleGapMin>
+      <SkewedFractionHorizontalGap>
+        <Value value="300"/>
+      </SkewedFractionHorizontalGap>
+      <SkewedFractionVerticalGap>
+        <Value value="66"/>
+      </SkewedFractionVerticalGap>
+      <OverbarVerticalGap>
+        <Value value="198"/>
+      </OverbarVerticalGap>
+      <OverbarRuleThickness>
+        <Value value="66"/>
+      </OverbarRuleThickness>
+      <OverbarExtraAscender>
+        <Value value="66"/>
+      </OverbarExtraAscender>
+      <UnderbarVerticalGap>
+        <Value value="198"/>
+      </UnderbarVerticalGap>
+      <UnderbarRuleThickness>
+        <Value value="66"/>
+      </UnderbarRuleThickness>
+      <UnderbarExtraDescender>
+        <Value value="66"/>
+      </UnderbarExtraDescender>
+      <RadicalVerticalGap>
+        <Value value="82"/>
+      </RadicalVerticalGap>
+      <RadicalDisplayStyleVerticalGap>
+        <Value value="186"/>
+      </RadicalDisplayStyleVerticalGap>
+      <RadicalRuleThickness>
+        <Value value="66"/>
+      </RadicalRuleThickness>
+      <RadicalExtraAscender>
+        <Value value="66"/>
+      </RadicalExtraAscender>
+      <RadicalKernBeforeDegree>
+        <Value value="277"/>
+      </RadicalKernBeforeDegree>
+      <RadicalKernAfterDegree>
+        <Value value="-555"/>
+      </RadicalKernAfterDegree>
+      <RadicalDegreeBottomRaisePercent value="70"/>
+    </MathConstants>
+  </MATH>
+
+  <hmtx>
+    <mtx name=".notdef" width="250" lsb="0"/>
+    <mtx name="A" width="722" lsb="15"/>
+  </hmtx>
+
+</ttFont>
diff --git a/Tests/subset/subset_test.py b/Tests/subset/subset_test.py
index 956197a..2bdfd9b 100644
--- a/Tests/subset/subset_test.py
+++ b/Tests/subset/subset_test.py
@@ -237,6 +237,13 @@
         subsetfont = TTFont(subsetpath)
         self.expect_ttx(subsetfont, self.getpath("expect_keep_math.ttx"), ["GlyphOrder", "CFF ", "MATH", "hmtx"])
 
+    def test_subset_math_partial(self):
+        _, fontpath = self.compile_font(self.getpath("test_math_partial.ttx"), ".ttf")
+        subsetpath = self.temp_path(".ttf")
+        subset.main([fontpath, "--text=A", "--output-file=%s" % subsetpath])
+        subsetfont = TTFont(subsetpath)
+        self.expect_ttx(subsetfont, self.getpath("expect_math_partial.ttx"), ["MATH"])
+
     def test_subset_opbd_remove(self):
         # In the test font, only the glyphs 'A' and 'zero' have an entry in
         # the Optical Bounds table. When subsetting, we do not request any
@@ -671,6 +678,48 @@
         subsetfont = TTFont(subsetpath)
         self.expect_ttx(subsetfont, self.getpath("expect_HVVAR_retain_gids.ttx"), ["GlyphOrder", "HVAR", "VVAR", "avar", "fvar"])
 
+    def test_subset_flavor(self):
+        _, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
+        font = TTFont(fontpath)
+
+        woff_path = self.temp_path(".woff")
+        subset.main(
+            [
+                fontpath,
+                "*",
+                "--flavor=woff",
+                "--output-file=%s" % woff_path,
+            ]
+        )
+        woff = TTFont(woff_path)
+
+        self.assertEqual(woff.flavor, "woff")
+
+        woff2_path = self.temp_path(".woff2")
+        subset.main(
+            [
+                woff_path,
+                "*",
+                "--flavor=woff2",
+                "--output-file=%s" % woff2_path,
+            ]
+        )
+        woff2 = TTFont(woff2_path)
+
+        self.assertEqual(woff2.flavor, "woff2")
+
+        ttf_path = self.temp_path(".ttf")
+        subset.main(
+            [
+                woff2_path,
+                "*",
+                "--output-file=%s" % ttf_path,
+            ]
+        )
+        ttf = TTFont(ttf_path)
+
+        self.assertEqual(ttf.flavor, None)
+
 
 if __name__ == "__main__":
     sys.exit(unittest.main())
diff --git a/Tests/ttLib/woff2_test.py b/Tests/ttLib/woff2_test.py
index 55c4b77..4a474ae 100644
--- a/Tests/ttLib/woff2_test.py
+++ b/Tests/ttLib/woff2_test.py
@@ -1,19 +1,24 @@
 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,
-	WOFF2Writer, unpackBase128, unpack255UShort, pack255UShort)
+	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:
@@ -122,7 +127,7 @@
 	def test_reconstruct_unknown(self):
 		reader = WOFF2Reader(self.file)
 		with self.assertRaisesRegex(ttLib.TTLibError, 'transform for table .* unknown'):
-			reader.reconstructTable('ZZZZ')
+			reader.reconstructTable('head')
 
 
 class WOFF2ReaderTTFTest(WOFF2ReaderTest):
@@ -145,6 +150,7 @@
 	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'))
 
@@ -242,10 +248,6 @@
 		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
@@ -291,6 +293,35 @@
 		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):
 
@@ -299,6 +330,7 @@
 		for attr in ('majorVersion', 'minorVersion', 'metaOffset', 'metaLength',
 				'metaOrigLength', 'privLength', 'privOffset'):
 			setattr(self, attr, 0)
+		self.tables = {}
 
 
 class WOFF2FlavorDataTest(unittest.TestCase):
@@ -353,6 +385,27 @@
 		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):
 
@@ -360,7 +413,7 @@
 	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.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)
@@ -511,6 +564,30 @@
 		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):
 
@@ -518,7 +595,7 @@
 	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.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)
@@ -539,6 +616,35 @@
 		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):
 
@@ -708,28 +814,6 @@
 		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)
@@ -747,6 +831,489 @@
 		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):
diff --git a/Tests/unicodedata_test.py b/Tests/unicodedata_test.py
index 190576f..fde3338 100644
--- a/Tests/unicodedata_test.py
+++ b/Tests/unicodedata_test.py
@@ -165,8 +165,8 @@
 
     assert unicodedata.script_extension("\u0660") == {'Arab', 'Thaa'}
     assert unicodedata.script_extension("\u0964") == {
-        'Beng', 'Deva', 'Dogr', 'Gong', 'Gran', 'Gujr', 'Guru', 'Knda',
-        'Mahj', 'Mlym', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml',
+        'Beng', 'Deva', 'Dogr', 'Gong', 'Gonm', 'Gran', 'Gujr', 'Guru', 'Knda',
+        'Mahj', 'Mlym', 'Nand', 'Orya', 'Sind', 'Sinh', 'Sylo', 'Takr', 'Taml',
         'Telu', 'Tirh'}
 
 
diff --git a/Tests/varLib/data/KerningMerging.designspace b/Tests/varLib/data/KerningMerging.designspace
new file mode 100644
index 0000000..f7ce7ef
--- /dev/null
+++ b/Tests/varLib/data/KerningMerging.designspace
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<designspace format="4.0">
+  <axes>
+    <axis tag="wght" name="Weight" minimum="100" maximum="900" default="400"/>
+  </axes>
+  <sources>
+    <source filename="master_kerning_merging/0.ttf">
+      <location>
+        <dimension name="Weight" xvalue="100"/>
+      </location>
+    </source>
+    <source filename="master_kerning_merging/1.ttf">
+      <location>
+        <dimension name="Weight" xvalue="400"/>
+      </location>
+    </source>
+    <source filename="master_kerning_merging/2.ttf">
+      <location>
+        <dimension name="Weight" xvalue="900"/>
+      </location>
+    </source>
+  </sources>
+</designspace>
diff --git a/Tests/varLib/data/TestNonMarkingCFF2.designspace b/Tests/varLib/data/TestNonMarkingCFF2.designspace
new file mode 100644
index 0000000..23c7797
--- /dev/null
+++ b/Tests/varLib/data/TestNonMarkingCFF2.designspace
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<designspace format="3">
+    <axes>
+        <axis default="0.0" maximum="1000.0" minimum="0.0" name="weight" tag="wght" />
+    </axes>
+    <sources>
+        <source filename="master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ufo" name="master_0">
+            <lib copy="1" />
+            <location>
+                <dimension name="weight" xvalue="0" />
+            </location>
+        </source>
+        <source filename="master_non_marking_cff2/TestNonMarkingCFF2_Regular.ufo" name="master_1">
+            <location>
+                <dimension name="weight" xvalue="1000" />
+            </location>
+        </source>
+    </sources>
+    <instances>
+        <instance familyname="Test Non Marking CFF2 Roman" postscriptfontname="TestNonMarkingCFF2-ExtraLight" stylename="ExtraLight">
+            <location>
+                <dimension name="weight" xvalue="0" />
+            </location>
+            <kerning />
+            <info />
+        </instance>
+        <instance familyname="Test Non Marking CFF2 Roman" postscriptfontname="TestNonMarkingCFF2-Regular" stylename="Regular">
+            <location>
+                <dimension name="weight" xvalue="1000" />
+            </location>
+            <kerning />
+            <info />
+        </instance>
+    </instances>
+</designspace>
diff --git a/Tests/varLib/data/master_kerning_merging/0.ttx b/Tests/varLib/data/master_kerning_merging/0.ttx
new file mode 100644
index 0000000..858f927
--- /dev/null
+++ b/Tests/varLib/data/master_kerning_merging/0.ttx
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.41">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="A"/>
+    <GlyphID id="2" name="B"/>
+    <GlyphID id="3" name="C"/>
+    <GlyphID id="4" name="D"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="0.0"/>
+    <checkSumAdjustment value="0x341296b2"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Wed Jun 12 15:33:01 2019"/>
+    <modified value="Wed Jun 12 15:33:01 2019"/>
+    <xMin value="50"/>
+    <yMin value="-200"/>
+    <xMax value="450"/>
+    <yMax value="800"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="6"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="1000"/>
+    <descent value="-200"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="500"/>
+    <minLeftSideBearing value="50"/>
+    <minRightSideBearing value="50"/>
+    <xMaxExtent value="450"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="1"/>
+  </hhea>
+
+  <maxp>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="0x10000"/>
+    <numGlyphs value="5"/>
+    <maxPoints value="8"/>
+    <maxContours value="2"/>
+    <maxCompositePoints value="0"/>
+    <maxCompositeContours value="0"/>
+    <maxZones value="1"/>
+    <maxTwilightPoints value="0"/>
+    <maxStorage value="0"/>
+    <maxFunctionDefs value="0"/>
+    <maxInstructionDefs value="0"/>
+    <maxStackElements value="0"/>
+    <maxSizeOfInstructions value="0"/>
+    <maxComponentElements value="0"/>
+    <maxComponentDepth value="0"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="4"/>
+    <xAvgCharWidth value="500"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000100"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="300"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="0"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="NONE"/>
+    <fsSelection value="00000000 01000000"/>
+    <usFirstCharIndex value="65"/>
+    <usLastCharIndex value="68"/>
+    <sTypoAscender value="800"/>
+    <sTypoDescender value="-200"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1000"/>
+    <usWinDescent value="200"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="500"/>
+    <sCapHeight value="700"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="2"/>
+  </OS_2>
+
+  <hmtx>
+    <mtx name=".notdef" width="500" lsb="50"/>
+    <mtx name="A" width="500" lsb="0"/>
+    <mtx name="B" width="500" lsb="0"/>
+    <mtx name="C" width="500" lsb="0"/>
+    <mtx name="D" width="500" lsb="0"/>
+  </hmtx>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+      <map code="0x42" name="B"/><!-- LATIN CAPITAL LETTER B -->
+      <map code="0x43" name="C"/><!-- LATIN CAPITAL LETTER C -->
+      <map code="0x44" name="D"/><!-- LATIN CAPITAL LETTER D -->
+    </cmap_format_4>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+      <map code="0x42" name="B"/><!-- LATIN CAPITAL LETTER B -->
+      <map code="0x43" name="C"/><!-- LATIN CAPITAL LETTER C -->
+      <map code="0x44" name="D"/><!-- LATIN CAPITAL LETTER D -->
+    </cmap_format_4>
+  </cmap>
+
+  <loca>
+    <!-- The 'loca' table will be calculated by the compiler -->
+  </loca>
+
+  <glyf>
+
+    <!-- The xMin, yMin, xMax and yMax values
+         will be recalculated by the compiler. -->
+
+    <TTGlyph name=".notdef" xMin="50" yMin="-200" xMax="450" yMax="800">
+      <contour>
+        <pt x="50" y="-200" on="1"/>
+        <pt x="450" y="-200" on="1"/>
+        <pt x="450" y="800" on="1"/>
+        <pt x="50" y="800" on="1"/>
+      </contour>
+      <contour>
+        <pt x="100" y="-150" on="1"/>
+        <pt x="100" y="750" on="1"/>
+        <pt x="400" y="750" on="1"/>
+        <pt x="400" y="-150" on="1"/>
+      </contour>
+      <instructions/>
+    </TTGlyph>
+
+    <TTGlyph name="A"/><!-- contains no outline data -->
+
+    <TTGlyph name="B"/><!-- contains no outline data -->
+
+    <TTGlyph name="C"/><!-- contains no outline data -->
+
+    <TTGlyph name="D"/><!-- contains no outline data -->
+
+  </glyf>
+
+  <name>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Test Thin
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+      0.000;NONE;Test-Thin
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Test Thin
+    </namerecord>
+    <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+      Version 0.000
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      Test-Thin
+    </namerecord>
+    <namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
+      Test
+    </namerecord>
+    <namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
+      Thin
+    </namerecord>
+  </name>
+
+  <post>
+    <formatType value="2.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-150"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+    <psNames>
+      <!-- This file uses unique glyph names based on the information
+           found in the 'post' table. Since these names might not be unique,
+           we have to invent artificial names in case of clashes. In order to
+           be able to retain the original information, we need a name to
+           ps name mapping for those cases where they differ. That's what
+           you see below.
+            -->
+    </psNames>
+    <extraNames>
+      <!-- following are the name that are not taken from the standard Mac glyph order -->
+    </extraNames>
+  </post>
+
+  <GPOS>
+    <Version value="0x00010000"/>
+    <ScriptList>
+      <!-- ScriptCount=1 -->
+      <ScriptRecord index="0">
+        <ScriptTag value="DFLT"/>
+        <Script>
+          <DefaultLangSys>
+            <ReqFeatureIndex value="65535"/>
+            <!-- FeatureCount=1 -->
+            <FeatureIndex index="0" value="0"/>
+          </DefaultLangSys>
+          <!-- LangSysCount=0 -->
+        </Script>
+      </ScriptRecord>
+    </ScriptList>
+    <FeatureList>
+      <!-- FeatureCount=1 -->
+      <FeatureRecord index="0">
+        <FeatureTag value="kern"/>
+        <Feature>
+          <!-- LookupCount=1 -->
+          <LookupListIndex index="0" value="0"/>
+        </Feature>
+      </FeatureRecord>
+    </FeatureList>
+    <LookupList>
+      <!-- LookupCount=1 -->
+      <Lookup index="0">
+        <LookupType value="2"/>
+        <LookupFlag value="8"/>
+        <!-- SubTableCount=1 -->
+        <PairPos index="0" Format="2">
+          <Coverage Format="1">
+            <Glyph value="A"/>
+            <Glyph value="B"/>
+          </Coverage>
+          <ValueFormat1 value="4"/>
+          <ValueFormat2 value="0"/>
+          <ClassDef1 Format="1">
+            <ClassDef glyph="A" class="1"/>
+          </ClassDef1>
+          <ClassDef2 Format="1">
+            <ClassDef glyph="C" class="1"/>
+          </ClassDef2>
+          <!-- Class1Count=2 -->
+          <!-- Class2Count=2 -->
+          <Class1Record index="0">
+            <Class2Record index="0">
+              <Value1 XAdvance="0"/>
+            </Class2Record>
+            <Class2Record index="1">
+              <Value1 XAdvance="10"/>
+            </Class2Record>
+          </Class1Record>
+          <Class1Record index="1">
+            <Class2Record index="0">
+              <Value1 XAdvance="0"/>
+            </Class2Record>
+            <Class2Record index="1">
+              <Value1 XAdvance="10"/>
+            </Class2Record>
+          </Class1Record>
+        </PairPos>
+      </Lookup>
+    </LookupList>
+  </GPOS>
+
+</ttFont>
diff --git a/Tests/varLib/data/master_kerning_merging/1.ttx b/Tests/varLib/data/master_kerning_merging/1.ttx
new file mode 100644
index 0000000..d60a708
--- /dev/null
+++ b/Tests/varLib/data/master_kerning_merging/1.ttx
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.41">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="A"/>
+    <GlyphID id="2" name="B"/>
+    <GlyphID id="3" name="C"/>
+    <GlyphID id="4" name="D"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="0.0"/>
+    <checkSumAdjustment value="0x340ca516"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Wed Jun 12 15:33:01 2019"/>
+    <modified value="Wed Jun 12 15:33:01 2019"/>
+    <xMin value="50"/>
+    <yMin value="-200"/>
+    <xMax value="450"/>
+    <yMax value="800"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="6"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="1000"/>
+    <descent value="-200"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="500"/>
+    <minLeftSideBearing value="50"/>
+    <minRightSideBearing value="50"/>
+    <xMaxExtent value="450"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="1"/>
+  </hhea>
+
+  <maxp>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="0x10000"/>
+    <numGlyphs value="5"/>
+    <maxPoints value="8"/>
+    <maxContours value="2"/>
+    <maxCompositePoints value="0"/>
+    <maxCompositeContours value="0"/>
+    <maxZones value="1"/>
+    <maxTwilightPoints value="0"/>
+    <maxStorage value="0"/>
+    <maxFunctionDefs value="0"/>
+    <maxInstructionDefs value="0"/>
+    <maxStackElements value="0"/>
+    <maxSizeOfInstructions value="0"/>
+    <maxComponentElements value="0"/>
+    <maxComponentDepth value="0"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="4"/>
+    <xAvgCharWidth value="500"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000100"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="300"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="0"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="NONE"/>
+    <fsSelection value="00000000 01000000"/>
+    <usFirstCharIndex value="65"/>
+    <usLastCharIndex value="68"/>
+    <sTypoAscender value="800"/>
+    <sTypoDescender value="-200"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1000"/>
+    <usWinDescent value="200"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="500"/>
+    <sCapHeight value="700"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="2"/>
+  </OS_2>
+
+  <hmtx>
+    <mtx name=".notdef" width="500" lsb="50"/>
+    <mtx name="A" width="500" lsb="0"/>
+    <mtx name="B" width="500" lsb="0"/>
+    <mtx name="C" width="500" lsb="0"/>
+    <mtx name="D" width="500" lsb="0"/>
+  </hmtx>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+      <map code="0x42" name="B"/><!-- LATIN CAPITAL LETTER B -->
+      <map code="0x43" name="C"/><!-- LATIN CAPITAL LETTER C -->
+      <map code="0x44" name="D"/><!-- LATIN CAPITAL LETTER D -->
+    </cmap_format_4>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+      <map code="0x42" name="B"/><!-- LATIN CAPITAL LETTER B -->
+      <map code="0x43" name="C"/><!-- LATIN CAPITAL LETTER C -->
+      <map code="0x44" name="D"/><!-- LATIN CAPITAL LETTER D -->
+    </cmap_format_4>
+  </cmap>
+
+  <loca>
+    <!-- The 'loca' table will be calculated by the compiler -->
+  </loca>
+
+  <glyf>
+
+    <!-- The xMin, yMin, xMax and yMax values
+         will be recalculated by the compiler. -->
+
+    <TTGlyph name=".notdef" xMin="50" yMin="-200" xMax="450" yMax="800">
+      <contour>
+        <pt x="50" y="-200" on="1"/>
+        <pt x="450" y="-200" on="1"/>
+        <pt x="450" y="800" on="1"/>
+        <pt x="50" y="800" on="1"/>
+      </contour>
+      <contour>
+        <pt x="100" y="-150" on="1"/>
+        <pt x="100" y="750" on="1"/>
+        <pt x="400" y="750" on="1"/>
+        <pt x="400" y="-150" on="1"/>
+      </contour>
+      <instructions/>
+    </TTGlyph>
+
+    <TTGlyph name="A"/><!-- contains no outline data -->
+
+    <TTGlyph name="B"/><!-- contains no outline data -->
+
+    <TTGlyph name="C"/><!-- contains no outline data -->
+
+    <TTGlyph name="D"/><!-- contains no outline data -->
+
+  </glyf>
+
+  <name>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Test
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+      0.000;NONE;Test-Regular
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Test Regular
+    </namerecord>
+    <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+      Version 0.000
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      Test-Regular
+    </namerecord>
+  </name>
+
+  <post>
+    <formatType value="2.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-150"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+    <psNames>
+      <!-- This file uses unique glyph names based on the information
+           found in the 'post' table. Since these names might not be unique,
+           we have to invent artificial names in case of clashes. In order to
+           be able to retain the original information, we need a name to
+           ps name mapping for those cases where they differ. That's what
+           you see below.
+            -->
+    </psNames>
+    <extraNames>
+      <!-- following are the name that are not taken from the standard Mac glyph order -->
+    </extraNames>
+  </post>
+
+  <GPOS>
+    <Version value="0x00010000"/>
+    <ScriptList>
+      <!-- ScriptCount=1 -->
+      <ScriptRecord index="0">
+        <ScriptTag value="DFLT"/>
+        <Script>
+          <DefaultLangSys>
+            <ReqFeatureIndex value="65535"/>
+            <!-- FeatureCount=1 -->
+            <FeatureIndex index="0" value="0"/>
+          </DefaultLangSys>
+          <!-- LangSysCount=0 -->
+        </Script>
+      </ScriptRecord>
+    </ScriptList>
+    <FeatureList>
+      <!-- FeatureCount=1 -->
+      <FeatureRecord index="0">
+        <FeatureTag value="kern"/>
+        <Feature>
+          <!-- LookupCount=1 -->
+          <LookupListIndex index="0" value="0"/>
+        </Feature>
+      </FeatureRecord>
+    </FeatureList>
+    <LookupList>
+      <!-- LookupCount=1 -->
+      <Lookup index="0">
+        <LookupType value="2"/>
+        <LookupFlag value="8"/>
+        <!-- SubTableCount=1 -->
+        <PairPos index="0" Format="2">
+          <Coverage Format="1">
+            <Glyph value="A"/>
+          </Coverage>
+          <ValueFormat1 value="4"/>
+          <ValueFormat2 value="0"/>
+          <ClassDef1 Format="2">
+          </ClassDef1>
+          <ClassDef2 Format="1">
+            <ClassDef glyph="B" class="2"/>
+            <ClassDef glyph="D" class="1"/>
+          </ClassDef2>
+          <!-- Class1Count=1 -->
+          <!-- Class2Count=3 -->
+          <Class1Record index="0">
+            <Class2Record index="0">
+              <Value1 XAdvance="0"/>
+            </Class2Record>
+            <Class2Record index="1">
+              <Value1 XAdvance="-20"/>
+            </Class2Record>
+            <Class2Record index="2">
+              <Value1 XAdvance="-20"/>
+            </Class2Record>
+          </Class1Record>
+        </PairPos>
+      </Lookup>
+    </LookupList>
+  </GPOS>
+
+</ttFont>
diff --git a/Tests/varLib/data/master_kerning_merging/2.ttx b/Tests/varLib/data/master_kerning_merging/2.ttx
new file mode 100644
index 0000000..e01a7b1
--- /dev/null
+++ b/Tests/varLib/data/master_kerning_merging/2.ttx
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.41">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="A"/>
+    <GlyphID id="2" name="B"/>
+    <GlyphID id="3" name="C"/>
+    <GlyphID id="4" name="D"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="0.0"/>
+    <checkSumAdjustment value="0x330c9492"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Wed Jun 12 15:33:01 2019"/>
+    <modified value="Wed Jun 12 15:33:01 2019"/>
+    <xMin value="50"/>
+    <yMin value="-200"/>
+    <xMax value="450"/>
+    <yMax value="800"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="6"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="1000"/>
+    <descent value="-200"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="500"/>
+    <minLeftSideBearing value="50"/>
+    <minRightSideBearing value="50"/>
+    <xMaxExtent value="450"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="1"/>
+  </hhea>
+
+  <maxp>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="0x10000"/>
+    <numGlyphs value="5"/>
+    <maxPoints value="8"/>
+    <maxContours value="2"/>
+    <maxCompositePoints value="0"/>
+    <maxCompositeContours value="0"/>
+    <maxZones value="1"/>
+    <maxTwilightPoints value="0"/>
+    <maxStorage value="0"/>
+    <maxFunctionDefs value="0"/>
+    <maxInstructionDefs value="0"/>
+    <maxStackElements value="0"/>
+    <maxSizeOfInstructions value="0"/>
+    <maxComponentElements value="0"/>
+    <maxComponentDepth value="0"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="4"/>
+    <xAvgCharWidth value="500"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000100"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="300"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="0"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="NONE"/>
+    <fsSelection value="00000000 01000000"/>
+    <usFirstCharIndex value="65"/>
+    <usLastCharIndex value="68"/>
+    <sTypoAscender value="800"/>
+    <sTypoDescender value="-200"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1000"/>
+    <usWinDescent value="200"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="500"/>
+    <sCapHeight value="700"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="2"/>
+  </OS_2>
+
+  <hmtx>
+    <mtx name=".notdef" width="500" lsb="50"/>
+    <mtx name="A" width="500" lsb="0"/>
+    <mtx name="B" width="500" lsb="0"/>
+    <mtx name="C" width="500" lsb="0"/>
+    <mtx name="D" width="500" lsb="0"/>
+  </hmtx>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+      <map code="0x42" name="B"/><!-- LATIN CAPITAL LETTER B -->
+      <map code="0x43" name="C"/><!-- LATIN CAPITAL LETTER C -->
+      <map code="0x44" name="D"/><!-- LATIN CAPITAL LETTER D -->
+    </cmap_format_4>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+      <map code="0x42" name="B"/><!-- LATIN CAPITAL LETTER B -->
+      <map code="0x43" name="C"/><!-- LATIN CAPITAL LETTER C -->
+      <map code="0x44" name="D"/><!-- LATIN CAPITAL LETTER D -->
+    </cmap_format_4>
+  </cmap>
+
+  <loca>
+    <!-- The 'loca' table will be calculated by the compiler -->
+  </loca>
+
+  <glyf>
+
+    <!-- The xMin, yMin, xMax and yMax values
+         will be recalculated by the compiler. -->
+
+    <TTGlyph name=".notdef" xMin="50" yMin="-200" xMax="450" yMax="800">
+      <contour>
+        <pt x="50" y="-200" on="1"/>
+        <pt x="450" y="-200" on="1"/>
+        <pt x="450" y="800" on="1"/>
+        <pt x="50" y="800" on="1"/>
+      </contour>
+      <contour>
+        <pt x="100" y="-150" on="1"/>
+        <pt x="100" y="750" on="1"/>
+        <pt x="400" y="750" on="1"/>
+        <pt x="400" y="-150" on="1"/>
+      </contour>
+      <instructions/>
+    </TTGlyph>
+
+    <TTGlyph name="A"/><!-- contains no outline data -->
+
+    <TTGlyph name="B"/><!-- contains no outline data -->
+
+    <TTGlyph name="C"/><!-- contains no outline data -->
+
+    <TTGlyph name="D"/><!-- contains no outline data -->
+
+  </glyf>
+
+  <name>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Test Black
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+      0.000;NONE;Test-Black
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Test Black
+    </namerecord>
+    <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+      Version 0.000
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      Test-Black
+    </namerecord>
+    <namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
+      Test
+    </namerecord>
+    <namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
+      Black
+    </namerecord>
+  </name>
+
+  <post>
+    <formatType value="2.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-150"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+    <psNames>
+      <!-- This file uses unique glyph names based on the information
+           found in the 'post' table. Since these names might not be unique,
+           we have to invent artificial names in case of clashes. In order to
+           be able to retain the original information, we need a name to
+           ps name mapping for those cases where they differ. That's what
+           you see below.
+            -->
+    </psNames>
+    <extraNames>
+      <!-- following are the name that are not taken from the standard Mac glyph order -->
+    </extraNames>
+  </post>
+
+  <GPOS>
+    <Version value="0x00010000"/>
+    <ScriptList>
+      <!-- ScriptCount=1 -->
+      <ScriptRecord index="0">
+        <ScriptTag value="DFLT"/>
+        <Script>
+          <DefaultLangSys>
+            <ReqFeatureIndex value="65535"/>
+            <!-- FeatureCount=1 -->
+            <FeatureIndex index="0" value="0"/>
+          </DefaultLangSys>
+          <!-- LangSysCount=0 -->
+        </Script>
+      </ScriptRecord>
+    </ScriptList>
+    <FeatureList>
+      <!-- FeatureCount=1 -->
+      <FeatureRecord index="0">
+        <FeatureTag value="kern"/>
+        <Feature>
+          <!-- LookupCount=1 -->
+          <LookupListIndex index="0" value="0"/>
+        </Feature>
+      </FeatureRecord>
+    </FeatureList>
+    <LookupList>
+      <!-- LookupCount=1 -->
+      <Lookup index="0">
+        <LookupType value="2"/>
+        <LookupFlag value="8"/>
+        <!-- SubTableCount=1 -->
+        <PairPos index="0" Format="2">
+          <Coverage Format="1">
+            <Glyph value="A"/>
+            <Glyph value="B"/>
+          </Coverage>
+          <ValueFormat1 value="4"/>
+          <ValueFormat2 value="0"/>
+          <ClassDef1 Format="1">
+            <ClassDef glyph="A" class="1"/>
+          </ClassDef1>
+          <ClassDef2 Format="1">
+            <ClassDef glyph="D" class="1"/>
+          </ClassDef2>
+          <!-- Class1Count=2 -->
+          <!-- Class2Count=2 -->
+          <Class1Record index="0">
+            <Class2Record index="0">
+              <Value1 XAdvance="0"/>
+            </Class2Record>
+            <Class2Record index="1">
+              <Value1 XAdvance="40"/>
+            </Class2Record>
+          </Class1Record>
+          <Class1Record index="1">
+            <Class2Record index="0">
+              <Value1 XAdvance="0"/>
+            </Class2Record>
+            <Class2Record index="1">
+              <Value1 XAdvance="40"/>
+            </Class2Record>
+          </Class1Record>
+        </PairPos>
+      </Lookup>
+    </LookupList>
+  </GPOS>
+
+</ttFont>
diff --git a/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx
new file mode 100644
index 0000000..9d3b267
--- /dev/null
+++ b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.41">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="A"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.01"/>
+    <checkSumAdjustment value="0xeb345d38"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Thu Nov 29 14:52:09 2018"/>
+    <modified value="Thu Nov 29 14:52:09 2018"/>
+    <xMin value="50"/>
+    <yMin value="-115"/>
+    <xMax value="550"/>
+    <yMax value="762"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="3"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="984"/>
+    <descent value="-273"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="600"/>
+    <minLeftSideBearing value="50"/>
+    <minRightSideBearing value="50"/>
+    <xMaxExtent value="550"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="5"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x5000"/>
+    <numGlyphs value="5"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="3"/>
+    <xAvgCharWidth value="578"/>
+    <usWeightClass value="200"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000000"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="286"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="2"/>
+      <bSerifStyle value="11"/>
+      <bWeight value="3"/>
+      <bProportion value="9"/>
+      <bContrast value="3"/>
+      <bStrokeVariation value="4"/>
+      <bArmStyle value="3"/>
+      <bLetterForm value="2"/>
+      <bMidline value="2"/>
+      <bXHeight value="4"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="ADBO"/>
+    <fsSelection value="00000000 00000000"/>
+    <usFirstCharIndex value="36"/>
+    <usLastCharIndex value="84"/>
+    <sTypoAscender value="750"/>
+    <sTypoDescender value="-250"/>
+    <sTypoLineGap value="0"/>
+    <usWinAscent value="984"/>
+    <usWinDescent value="273"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="478"/>
+    <sCapHeight value="660"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="1"/>
+  </OS_2>
+
+  <name>
+    <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      1.010;ADBO;SourceCode_ExtraLight
+    </namerecord>
+    <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="5" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596
+    </namerecord>
+    <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      SourceCode_ExtraLight
+    </namerecord>
+    <namerecord nameID="17" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Roman Master 0
+    </namerecord>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+      1.010;ADBO;SourceCode_ExtraLight
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+      Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      SourceCode_ExtraLight
+    </namerecord>
+    <namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
+      Roman Master 0
+    </namerecord>
+  </name>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_4>
+    <cmap_format_6 platformID="1" platEncID="0" language="0">
+      <map code="0x41" name="A"/>
+    </cmap_format_6>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_4>
+  </cmap>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="1"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+  <CFF>
+    <major value="1"/>
+    <minor value="0"/>
+    <CFFFont name="SourceCode_ExtraLight">
+      <version value="1.0"/>
+      <Notice value="Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries."/>
+      <Copyright value="Copyright 2010 - 2012 Adobe Systems Incorporated. All Rights Reserved."/>
+      <FamilyName value="Source Code"/>
+      <isFixedPitch value="1"/>
+      <ItalicAngle value="0"/>
+      <UnderlinePosition value="-100"/>
+      <UnderlineThickness value="50"/>
+      <PaintType value="0"/>
+      <CharstringType value="2"/>
+      <FontMatrix value="0.001 0 0 0.001 0 0"/>
+      <FontBBox value="50 -115 550 762"/>
+      <StrokeWidth value="0"/>
+      <!-- charset is dumped separately as the 'GlyphOrder' element -->
+      <Encoding name="StandardEncoding"/>
+      <Private>
+        <BlueValues value="-12 0 478 490 570 582 640 652 660 672 722 734"/>
+        <OtherBlues value="-234 -222"/>
+        <BlueScale value="0.0625"/>
+        <BlueShift value="7"/>
+        <BlueFuzz value="0"/>
+        <StdHW value="28"/>
+        <StdVW value="34"/>
+        <ForceBold value="0"/>
+        <LanguageGroup value="0"/>
+        <ExpansionFactor value="0.06"/>
+        <initialRandomSeed value="0"/>
+        <defaultWidthX value="600"/>
+        <nominalWidthX value="597"/>
+      </Private>
+      <CharStrings>
+        <CharString name=".notdef">
+          endchar
+        </CharString>
+        <CharString name="A">
+          endchar
+        </CharString>
+=      </CharStrings>
+    </CFFFont>
+
+    <GlobalSubrs>
+      <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+    </GlobalSubrs>
+  </CFF>
+
+  <hmtx>
+    <mtx name=".notdef" width="600" lsb="84"/>
+    <mtx name="A" width="600" lsb="50"/>
+  </hmtx>
+
+</ttFont>
diff --git a/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx
new file mode 100644
index 0000000..4e6775d
--- /dev/null
+++ b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.41">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="A"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.01"/>
+    <checkSumAdjustment value="0x60d07155"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Thu Nov 29 14:52:09 2018"/>
+    <modified value="Thu Nov 29 14:52:09 2018"/>
+    <xMin value="31"/>
+    <yMin value="-115"/>
+    <xMax value="569"/>
+    <yMax value="751"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="3"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="984"/>
+    <descent value="-273"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="600"/>
+    <minLeftSideBearing value="31"/>
+    <minRightSideBearing value="31"/>
+    <xMaxExtent value="569"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="5"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x5000"/>
+    <numGlyphs value="5"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="3"/>
+    <xAvgCharWidth value="579"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000000"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="291"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="2"/>
+      <bSerifStyle value="11"/>
+      <bWeight value="5"/>
+      <bProportion value="9"/>
+      <bContrast value="3"/>
+      <bStrokeVariation value="4"/>
+      <bArmStyle value="3"/>
+      <bLetterForm value="2"/>
+      <bMidline value="2"/>
+      <bXHeight value="4"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="ADBO"/>
+    <fsSelection value="00000000 01000000"/>
+    <usFirstCharIndex value="36"/>
+    <usLastCharIndex value="84"/>
+    <sTypoAscender value="750"/>
+    <sTypoDescender value="-250"/>
+    <sTypoLineGap value="0"/>
+    <usWinAscent value="984"/>
+    <usWinDescent value="273"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="486"/>
+    <sCapHeight value="660"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="1"/>
+  </OS_2>
+
+  <name>
+    <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      1.010;ADBO;SourceCodeVariable-Roman
+    </namerecord>
+    <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="5" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596
+    </namerecord>
+    <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      SourceCodeVariable-Roman
+    </namerecord>
+    <namerecord nameID="17" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Roman
+    </namerecord>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+      1.010;ADBO;SourceCodeVariable-Roman
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Source Code Variable
+    </namerecord>
+    <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+      Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      SourceCodeVariable-Roman
+    </namerecord>
+    <namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
+      Roman
+    </namerecord>
+  </name>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_4>
+    <cmap_format_6 platformID="1" platEncID="0" language="0">
+      <map code="0x41" name="A"/>
+    </cmap_format_6>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
+    </cmap_format_4>
+  </cmap>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="1"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+  <CFF>
+    <major value="1"/>
+    <minor value="0"/>
+    <CFFFont name="SourceCodeVariable-Roman">
+      <version value="1.0"/>
+      <Notice value="Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries."/>
+      <Copyright value="Copyright 2010 - 2012 Adobe Systems Incorporated. All Rights Reserved."/>
+      <FamilyName value="Source Code"/>
+      <isFixedPitch value="1"/>
+      <ItalicAngle value="0"/>
+      <UnderlinePosition value="-100"/>
+      <UnderlineThickness value="50"/>
+      <PaintType value="0"/>
+      <CharstringType value="2"/>
+      <FontMatrix value="0.001 0 0 0.001 0 0"/>
+      <FontBBox value="31 -115 569 751"/>
+      <StrokeWidth value="0"/>
+      <!-- charset is dumped separately as the 'GlyphOrder' element -->
+      <Encoding name="StandardEncoding"/>
+      <Private>
+        <BlueValues value="-12 0 486 498 574 586 638 650 656 668 712 724"/>
+        <OtherBlues value="-217 -205"/>
+        <BlueScale value="0.0625"/>
+        <BlueShift value="7"/>
+        <BlueFuzz value="0"/>
+        <StdHW value="67"/>
+        <StdVW value="85"/>
+        <ForceBold value="0"/>
+        <LanguageGroup value="0"/>
+        <ExpansionFactor value="0.06"/>
+        <initialRandomSeed value="0"/>
+        <defaultWidthX value="600"/>
+        <nominalWidthX value="604"/>
+      </Private>
+      <CharStrings>
+        <CharString name=".notdef">
+          endchar
+        </CharString>
+        <CharString name="A">
+          endchar
+        </CharString>
+      </CharStrings>
+    </CFFFont>
+
+    <GlobalSubrs>
+      <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+    </GlobalSubrs>
+  </CFF>
+
+  <hmtx>
+    <mtx name=".notdef" width="600" lsb="62"/>
+    <mtx name="A" width="600" lsb="31"/>
+  </hmtx>
+
+</ttFont>
diff --git a/Tests/varLib/data/master_vpal_test/master_vpal_test_0.ttx b/Tests/varLib/data/master_vpal_test/master_vpal_test_0.ttx
new file mode 100644
index 0000000..1fbb45d
--- /dev/null
+++ b/Tests/varLib/data/master_vpal_test/master_vpal_test_0.ttx
@@ -0,0 +1,485 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="uni3001"/>
+    <GlyphID id="2" name="uni30FB"/>
+    <GlyphID id="3" name="uniFF1A"/>
+    <GlyphID id="4" name="uniFF2D"/>
+    <GlyphID id="5" name="uni3073"/>
+    <GlyphID id="6" name="uni3074"/>
+    <GlyphID id="7" name="uni307B"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.004"/>
+    <checkSumAdjustment value="0x90c6f91d"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Wed Jun  5 14:40:00 2019"/>
+    <modified value="Tue Jun 11 21:27:36 2019"/>
+    <xMin value="64"/>
+    <yMin value="-52"/>
+    <xMax value="974"/>
+    <yMax value="798"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="3"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="1160"/>
+    <descent value="-317"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="1000"/>
+    <minLeftSideBearing value="64"/>
+    <minRightSideBearing value="26"/>
+    <xMaxExtent value="974"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="2"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x5000"/>
+    <numGlyphs value="8"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="3"/>
+    <xAvgCharWidth value="962"/>
+    <usWeightClass value="250"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000100"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="228"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="3"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange2 value="00000000 00000111 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00010000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="UKWN"/>
+    <fsSelection value="00000000 00000000"/>
+    <usFirstCharIndex value="12289"/>
+    <usLastCharIndex value="65325"/>
+    <sTypoAscender value="880"/>
+    <sTypoDescender value="-120"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1160"/>
+    <usWinDescent value="317"/>
+    <ulCodePageRange1 value="00100000 00000010 00000000 10011111"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="380"/>
+    <sCapHeight value="760"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="1"/>
+  </OS_2>
+
+  <name>
+    <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
+      Copyright © 2018 Adobe systems Co., Ltd. All Rights Reserved.
+    </namerecord>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      MasterSet_KanjiFullEX
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+      1.004;UKWN;MasterSet_KanjiFullEX-w0.00
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      MasterSet_KanjiFullEX
+    </namerecord>
+    <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+      Version 1.004;hotconv 1.0.109;makeotfexe 2.5.65596
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      MasterSet_KanjiFullEX-w0.00
+    </namerecord>
+  </name>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_4>
+    <cmap_format_12 platformID="0" platEncID="4" format="12" reserved="0" length="88" language="0" nGroups="6">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_12>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_4>
+    <cmap_format_12 platformID="3" platEncID="10" format="12" reserved="0" length="88" language="0" nGroups="6">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_12>
+  </cmap>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+  <CFF>
+    <major value="1"/>
+    <minor value="0"/>
+    <CFFFont name="MasterSet_KanjiFullEX-w0.00">
+      <FamilyName value="MasterSet_KanjiFullEX"/>
+      <isFixedPitch value="0"/>
+      <ItalicAngle value="0"/>
+      <UnderlinePosition value="-100"/>
+      <UnderlineThickness value="50"/>
+      <PaintType value="0"/>
+      <CharstringType value="2"/>
+      <FontMatrix value="0.001 0 0 0.001 0 0"/>
+      <FontBBox value="64 -52 974 798"/>
+      <StrokeWidth value="0"/>
+      <!-- charset is dumped separately as the 'GlyphOrder' element -->
+      <Encoding name="StandardEncoding"/>
+      <Private>
+        <BlueValues value="0 0"/>
+        <BlueScale value="0.039625"/>
+        <BlueShift value="7"/>
+        <BlueFuzz value="1"/>
+        <ForceBold value="0"/>
+        <LanguageGroup value="0"/>
+        <ExpansionFactor value="0.06"/>
+        <initialRandomSeed value="0"/>
+        <defaultWidthX value="1000"/>
+        <nominalWidthX value="532"/>
+      </Private>
+      <CharStrings>
+        <CharString name=".notdef">
+          -282 endchar
+        </CharString>
+        <CharString name="uni3001">
+          291 -43 rmoveto
+          29 24 rlineto
+          -74 84 -84 83 -73 58 rrcurveto
+          -25 -24 rlineto
+          72 -56 87 -85 68 -84 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni3073">
+          706 699 rmoveto
+          -32 -10 rlineto
+          50 -192 56 -132 112 -115 rrcurveto
+          24 26 rlineto
+          -143 124 -45 182 -22 117 rrcurveto
+          -592 -57 rmoveto
+          3 -38 rlineto
+          18 2 18 3 17 2 rrcurveto
+          43 6 101 12 63 13 rrcurveto
+          -83 -80 -128 -166 0 -210 rrcurveto
+          0 -150 92 -88 154 0 rrcurveto
+          294 0 65 313 -48 302 rrcurveto
+          -29 79 rlineto
+          64 -402 -96 -263 -249 0 rrcurveto
+          -109 0 -110 48 0 166 rrcurveto
+          0 219 171 196 58 42 rrcurveto
+          14 5 30 6 12 3 rrcurveto
+          -9 30 rlineto
+          -52 -21 -170 -26 -83 -3 rrcurveto
+          -18 -1 -21 0 -12 1 rrcurveto
+          677 114 rmoveto
+          -26 -11 rlineto
+          22 -34 33 -63 20 -42 rrcurveto
+          30 14 rlineto
+          -21 41 -37 62 -21 33 rrcurveto
+          97 40 rmoveto
+          -26 -13 rlineto
+          24 -33 31 -59 21 -44 rrcurveto
+          30 14 rlineto
+          -23 43 -36 60 -21 32 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni3074">
+          706 699 rmoveto
+          -32 -10 rlineto
+          50 -192 56 -132 112 -115 rrcurveto
+          24 26 rlineto
+          -143 124 -45 182 -22 117 rrcurveto
+          -592 -57 rmoveto
+          3 -38 rlineto
+          18 2 18 3 17 2 rrcurveto
+          43 6 101 12 63 13 rrcurveto
+          -83 -80 -128 -166 0 -210 rrcurveto
+          0 -150 92 -88 154 0 rrcurveto
+          294 0 65 313 -48 302 rrcurveto
+          -29 79 rlineto
+          64 -402 -96 -263 -249 0 rrcurveto
+          -109 0 -110 48 0 166 rrcurveto
+          0 219 171 196 58 42 rrcurveto
+          14 5 30 6 12 3 rrcurveto
+          -9 30 rlineto
+          -52 -21 -170 -26 -83 -3 rrcurveto
+          -18 -1 -21 0 -12 1 rrcurveto
+          681 51 rmoveto
+          0 42 33 33 41 0 rrcurveto
+          41 0 33 -33 0 -42 rrcurveto
+          0 -41 -33 -33 -41 0 rrcurveto
+          -42 0 -32 33 0 41 rrcurveto
+          -30 0 rmoveto
+          0 -57 46 -47 58 0 rrcurveto
+          57 0 48 47 0 57 rrcurveto
+          0 58 -48 47 -57 0 rrcurveto
+          -58 0 -46 -47 0 -58 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni307B">
+          703 676 rmoveto
+          -28 0 rlineto
+          0 -63 0 -106 0 -61 rrcurveto
+          0 -103 14 -162 0 -52 rrcurveto
+          0 -59 -17 -50 -97 0 rrcurveto
+          -91 0 -58 31 0 63 rrcurveto
+          0 53 62 37 87 0 rrcurveto
+          125 0 119 -56 94 -98 rrcurveto
+          19 31 rlineto
+          -90 81 -113 69 -154 0 rrcurveto
+          -130 0 -47 -64 0 -53 rrcurveto
+          0 -80 70 -42 105 0 rrcurveto
+          85 0 58 36 0 74 rrcurveto
+          0 68 -13 166 0 113 rrcurveto
+          0 61 0 96 0 70 rrcurveto
+          -284 -213 rmoveto
+          0 -31 rlineto
+          168 -10 194 12 125 13 rrcurveto
+          0 31 rlineto
+          -129 -15 -187 -13 -171 13 rrcurveto
+          16 230 rmoveto
+          0 -30 rlineto
+          139 -7 200 11 108 11 rrcurveto
+          0 30 rlineto
+          -111 -15 -197 -11 -139 11 rrcurveto
+          -207 51 rmoveto
+          -37 4 rlineto
+          0 -11 -1 -14 -3 -19 rrcurveto
+          -13 -88 -37 -183 0 -143 rrcurveto
+          0 -135 16 -105 20 -74 rrcurveto
+          28 3 rlineto
+          -1 7 -2 12 -1 9 rrcurveto
+          -1 13 2 16 3 14 rrcurveto
+          9 43 39 105 22 55 rrcurveto
+          -20 17 rlineto
+          -20 -48 -32 -89 -18 -56 rrcurveto
+          -10 78 -5 58 0 78 rrcurveto
+          0 124 26 166 25 119 rrcurveto
+          3 18 4 13 4 13 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni30FB">
+          500 465 rmoveto
+          -47 0 -38 -38 0 -47 rrcurveto
+          0 -47 38 -38 47 0 rrcurveto
+          47 0 38 38 0 47 rrcurveto
+          0 47 -38 38 -47 0 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uniFF1A">
+          500 572 rmoveto
+          28 0 28 19 0 37 rrcurveto
+          0 37 -28 19 -28 0 rrcurveto
+          -28 0 -28 -19 0 -37 rrcurveto
+          0 -37 28 -19 28 0 rrcurveto
+          0 -502 rmoveto
+          28 0 28 19 0 37 rrcurveto
+          0 37 -28 19 -28 0 rrcurveto
+          -28 0 -28 -19 0 -37 rrcurveto
+          0 -37 28 -19 28 0 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uniFF2D">
+          180 0 rmoveto
+          35 0 rlineto
+          0 502 rlineto
+          0 57 -1 74 -2 59 rrcurveto
+          5 0 rlineto
+          67 -160 rlineto
+          196 -451 rlineto
+          39 0 rlineto
+          195 451 rlineto
+          69 160 rlineto
+          5 0 rlineto
+          -2 -59 -3 -74 0 -57 rrcurveto
+          0 -502 rlineto
+          37 0 rlineto
+          0 726 rlineto
+          -59 0 rlineto
+          -191 -438 rlineto
+          -23 -54 -20 -55 -24 -55 rrcurveto
+          -4 0 rlineto
+          -24 55 -23 55 -23 54 rrcurveto
+          -190 438 rlineto
+          -59 0 rlineto
+          0 -726 rlineto
+          endchar
+        </CharString>
+      </CharStrings>
+    </CFFFont>
+
+    <GlobalSubrs>
+      <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+    </GlobalSubrs>
+  </CFF>
+
+  <GPOS>
+    <Version value="0x00010000"/>
+    <ScriptList>
+      <!-- ScriptCount=1 -->
+      <ScriptRecord index="0">
+        <ScriptTag value="DFLT"/>
+        <Script>
+          <DefaultLangSys>
+            <ReqFeatureIndex value="65535"/>
+            <!-- FeatureCount=1 -->
+            <FeatureIndex index="0" value="0"/>
+          </DefaultLangSys>
+          <!-- LangSysCount=0 -->
+        </Script>
+      </ScriptRecord>
+    </ScriptList>
+    <FeatureList>
+      <!-- FeatureCount=1 -->
+      <FeatureRecord index="0">
+        <FeatureTag value="vpal"/>
+        <Feature>
+          <!-- LookupCount=1 -->
+          <LookupListIndex index="0" value="0"/>
+        </Feature>
+      </FeatureRecord>
+    </FeatureList>
+    <LookupList>
+      <!-- LookupCount=1 -->
+      <Lookup index="0">
+        <LookupType value="1"/>
+        <LookupFlag value="0"/>
+        <!-- SubTableCount=5 -->
+        <SinglePos index="0" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uni3001"/>
+            <Glyph value="uniFF1A"/>
+          </Coverage>
+          <ValueFormat value="5"/>
+          <!-- ValueCount=2 -->
+          <Value index="0" XPlacement="-9" XAdvance="-500"/>
+          <Value index="1" XPlacement="-250" XAdvance="-500"/>
+        </SinglePos>
+        <SinglePos index="1" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uni30FB"/>
+          </Coverage>
+          <ValueFormat value="7"/>
+          <!-- ValueCount=1 -->
+          <Value index="0" XPlacement="-250" YPlacement="1" XAdvance="-500"/>
+        </SinglePos>
+        <SinglePos index="2" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uni3073"/>
+            <Glyph value="uni3074"/>
+          </Coverage>
+          <ValueFormat value="4"/>
+          <!-- ValueCount=2 -->
+          <Value index="0" XAdvance="-36"/>
+          <Value index="1" XAdvance="-30"/>
+        </SinglePos>
+        <SinglePos index="3" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uni307B"/>
+          </Coverage>
+          <ValueFormat value="1"/>
+          <!-- ValueCount=1 -->
+          <Value index="0" XPlacement="11"/>
+        </SinglePos>
+        <SinglePos index="4" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uniFF2D"/>
+          </Coverage>
+          <ValueFormat value="5"/>
+          <!-- ValueCount=1 -->
+          <Value index="0" XPlacement="12" XAdvance="23"/>
+        </SinglePos>
+      </Lookup>
+    </LookupList>
+  </GPOS>
+
+  <hmtx>
+    <mtx name=".notdef" width="250" lsb="0"/>
+    <mtx name="uni3001" width="1000" lsb="64"/>
+    <mtx name="uni3073" width="1000" lsb="114"/>
+    <mtx name="uni3074" width="1000" lsb="114"/>
+    <mtx name="uni307B" width="1000" lsb="137"/>
+    <mtx name="uni30FB" width="1000" lsb="415"/>
+    <mtx name="uniFF1A" width="1000" lsb="444"/>
+    <mtx name="uniFF2D" width="1000" lsb="180"/>
+  </hmtx>
+
+</ttFont>
diff --git a/Tests/varLib/data/master_vpal_test/master_vpal_test_1.ttx b/Tests/varLib/data/master_vpal_test/master_vpal_test_1.ttx
new file mode 100644
index 0000000..bb43958
--- /dev/null
+++ b/Tests/varLib/data/master_vpal_test/master_vpal_test_1.ttx
@@ -0,0 +1,473 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
+
+  <GlyphOrder>
+    <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="uni3001"/>
+    <GlyphID id="2" name="uni30FB"/>
+    <GlyphID id="3" name="uniFF1A"/>
+    <GlyphID id="4" name="uniFF2D"/>
+    <GlyphID id="5" name="uni3073"/>
+    <GlyphID id="6" name="uni3074"/>
+    <GlyphID id="7" name="uni307B"/>
+  </GlyphOrder>
+
+  <head>
+    <!-- Most of this table will be recalculated by the compiler -->
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.004"/>
+    <checkSumAdjustment value="0xfa2dc49e"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Wed Jun  5 14:40:08 2019"/>
+    <modified value="Tue Jun 11 21:27:55 2019"/>
+    <xMin value="33"/>
+    <yMin value="-87"/>
+    <xMax value="992"/>
+    <yMax value="855"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="3"/>
+    <fontDirectionHint value="2"/>
+    <indexToLocFormat value="0"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x00010000"/>
+    <ascent value="1160"/>
+    <descent value="-317"/>
+    <lineGap value="0"/>
+    <advanceWidthMax value="1000"/>
+    <minLeftSideBearing value="33"/>
+    <minRightSideBearing value="8"/>
+    <xMaxExtent value="992"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+    <numberOfHMetrics value="2"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x5000"/>
+    <numGlyphs value="8"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="3"/>
+    <xAvgCharWidth value="971"/>
+    <usWeightClass value="900"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00000100"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="228"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="10"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange2 value="00000000 00000111 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00010000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="UKWN"/>
+    <fsSelection value="00000000 00000000"/>
+    <usFirstCharIndex value="12289"/>
+    <usLastCharIndex value="65325"/>
+    <sTypoAscender value="880"/>
+    <sTypoDescender value="-120"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1160"/>
+    <usWinDescent value="317"/>
+    <ulCodePageRange1 value="00100000 00000010 00000000 10011111"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="380"/>
+    <sCapHeight value="760"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="1"/>
+  </OS_2>
+
+  <name>
+    <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
+      Copyright © 2018 Adobe systems Co., Ltd. All Rights Reserved.
+    </namerecord>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      MasterSet_KanjiFullEX
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+      1.004;UKWN;MasterSet_KanjiFullEX-w1000.00
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      MasterSet_KanjiFullEX
+    </namerecord>
+    <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+      Version 1.004;hotconv 1.0.109;makeotfexe 2.5.65596
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      MasterSet_KanjiFullEX-w1000.00
+    </namerecord>
+  </name>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="0" platEncID="3" language="0">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_4>
+    <cmap_format_12 platformID="0" platEncID="4" format="12" reserved="0" length="88" language="0" nGroups="6">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_12>
+    <cmap_format_4 platformID="3" platEncID="1" language="0">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_4>
+    <cmap_format_12 platformID="3" platEncID="10" format="12" reserved="0" length="88" language="0" nGroups="6">
+      <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+      <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+      <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+      <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+      <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+      <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+      <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+    </cmap_format_12>
+  </cmap>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+  <CFF>
+    <major value="1"/>
+    <minor value="0"/>
+    <CFFFont name="MasterSet_KanjiFullEX-w1000.00">
+      <FamilyName value="MasterSet_KanjiFullEX"/>
+      <isFixedPitch value="0"/>
+      <ItalicAngle value="0"/>
+      <UnderlinePosition value="-100"/>
+      <UnderlineThickness value="50"/>
+      <PaintType value="0"/>
+      <CharstringType value="2"/>
+      <FontMatrix value="0.001 0 0 0.001 0 0"/>
+      <FontBBox value="33 -87 992 855"/>
+      <StrokeWidth value="0"/>
+      <!-- charset is dumped separately as the 'GlyphOrder' element -->
+      <Encoding name="StandardEncoding"/>
+      <Private>
+        <BlueValues value="0 0"/>
+        <BlueScale value="0.039625"/>
+        <BlueShift value="7"/>
+        <BlueFuzz value="1"/>
+        <ForceBold value="0"/>
+        <LanguageGroup value="0"/>
+        <ExpansionFactor value="0.06"/>
+        <initialRandomSeed value="0"/>
+        <defaultWidthX value="1000"/>
+        <nominalWidthX value="705"/>
+      </Private>
+      <CharStrings>
+        <CharString name=".notdef">
+          -455 endchar
+        </CharString>
+        <CharString name="uni3001">
+          245 -76 rmoveto
+          129 111 rlineto
+          -44 56 -100 103 -70 58 rrcurveto
+          -127 -109 rlineto
+          69 -61 84 -86 59 -72 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni3073">
+          729 763 rmoveto
+          -152 -42 rlineto
+          75 -225 86 -176 109 -123 rrcurveto
+          97 140 rlineto
+          -155 146 -41 152 -19 128 rrcurveto
+          -677 -48 rmoveto
+          11 -156 rlineto
+          24 5 15 2 22 3 rrcurveto
+          26 3 53 6 31 1 rrcurveto
+          -96 -130 -50 -109 0 -149 rrcurveto
+          0 -190 149 -88 163 0 rrcurveto
+          344 0 43 303 -58 260 rrcurveto
+          -142 223 rlineto
+          96 -376 -59 -246 -221 0 rrcurveto
+          -92 0 -67 46 0 103 rrcurveto
+          0 184 125 143 71 54 rrcurveto
+          16 10 18 8 15 6 rrcurveto
+          -46 134 rlineto
+          -69 -25 -166 -20 -98 -5 rrcurveto
+          -19 -1 -20 0 -19 1 rrcurveto
+          768 103 rmoveto
+          -88 -27 rlineto
+          22 -45 16 -54 15 -49 rrcurveto
+          87 28 rlineto
+          -11 41 -23 62 -18 44 rrcurveto
+          110 37 rmoveto
+          -85 -28 rlineto
+          21 -44 19 -57 14 -46 rrcurveto
+          88 28 rlineto
+          -13 40 -22 63 -22 44 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni3074">
+          729 763 rmoveto
+          -152 -42 rlineto
+          75 -225 86 -176 109 -123 rrcurveto
+          97 140 rlineto
+          -155 146 -41 152 -19 128 rrcurveto
+          -677 -48 rmoveto
+          11 -156 rlineto
+          24 5 15 2 22 3 rrcurveto
+          26 3 53 6 31 1 rrcurveto
+          -96 -130 -50 -109 0 -149 rrcurveto
+          0 -190 149 -88 163 0 rrcurveto
+          344 0 43 303 -58 260 rrcurveto
+          -142 223 rlineto
+          96 -376 -59 -246 -221 0 rrcurveto
+          -92 0 -67 46 0 103 rrcurveto
+          0 184 125 143 71 54 rrcurveto
+          16 10 18 8 15 6 rrcurveto
+          -46 134 rlineto
+          -69 -25 -166 -20 -98 -5 rrcurveto
+          -19 -1 -20 0 -19 1 rrcurveto
+          772 16 rmoveto
+          0 27 22 22 27 0 rrcurveto
+          27 0 22 -22 0 -27 rrcurveto
+          0 -27 -22 -22 -27 0 rrcurveto
+          -27 0 -22 22 0 27 rrcurveto
+          -70 0 rmoveto
+          0 -66 53 -53 66 0 rrcurveto
+          66 0 53 53 0 66 rrcurveto
+          0 66 -53 53 -66 0 rrcurveto
+          -66 0 -53 -53 0 -66 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni307B">
+          758 687 rmoveto
+          -141 0 rlineto
+          0 -42 0 -111 0 -88 rrcurveto
+          0 -104 8 -126 0 -63 rrcurveto
+          0 -45 -23 -24 -49 0 rrcurveto
+          -37 0 -24 16 0 29 rrcurveto
+          0 28 23 18 48 0 rrcurveto
+          107 0 121 -81 97 -98 rrcurveto
+          79 131 rlineto
+          -51 45 -135 115 -213 0 rrcurveto
+          -137 0 -76 -72 0 -97 rrcurveto
+          0 -116 100 -52 119 0 rrcurveto
+          142 0 55 65 0 93 rrcurveto
+          0 97 -13 99 0 147 rrcurveto
+          0 64 0 96 0 76 rrcurveto
+          -360 -167 rmoveto
+          1 -139 rlineto
+          195 -9 191 7 133 16 rrcurveto
+          0 139 rlineto
+          -148 -18 -178 -11 -194 15 rrcurveto
+          15 235 rmoveto
+          0 -134 rlineto
+          197 -9 162 8 126 14 rrcurveto
+          0 134 rlineto
+          -127 -19 -163 -9 -195 15 rrcurveto
+          -117 26 rmoveto
+          -168 14 rlineto
+          -1 -37 -6 -47 -4 -29 rrcurveto
+          -11 -74 -26 -192 0 -153 rrcurveto
+          0 -136 20 -117 21 -68 rrcurveto
+          139 10 rlineto
+          -1 16 0 18 0 11 rrcurveto
+          0 10 3 23 3 14 rrcurveto
+          12 58 30 101 30 90 rrcurveto
+          -73 59 rlineto
+          -13 -30 -14 -23 -12 -29 rrcurveto
+          -1 4 0 20 0 3 rrcurveto
+          0 93 33 237 12 52 rrcurveto
+          4 18 14 62 9 22 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uni30FB">
+          500 520 rmoveto
+          -77 0 -63 -63 0 -77 rrcurveto
+          0 -77 63 -63 77 0 rrcurveto
+          77 0 63 63 0 77 rrcurveto
+          0 77 -63 63 -77 0 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uniFF1A">
+          500 500 rmoveto
+          60 0 46 46 0 58 rrcurveto
+          0 60 -46 46 -60 0 rrcurveto
+          -60 0 -46 -46 0 -60 rrcurveto
+          0 -58 46 -46 60 0 rrcurveto
+          0 -470 rmoveto
+          60 0 46 46 0 58 rrcurveto
+          0 60 -46 46 -60 0 rrcurveto
+          -60 0 -46 -46 0 -60 rrcurveto
+          0 -58 46 -46 60 0 rrcurveto
+          endchar
+        </CharString>
+        <CharString name="uniFF2D">
+          113 0 rmoveto
+          160 0 rlineto
+          0 255 rlineto
+          0 75 -12 113 -9 74 rrcurveto
+          4 0 rlineto
+          72 -182 rlineto
+          121 -272 rlineto
+          98 0 rlineto
+          120 272 rlineto
+          73 182 rlineto
+          5 0 rlineto
+          -10 -74 -12 -113 0 -75 rrcurveto
+          0 -255 rlineto
+          163 0 rlineto
+          0 748 rlineto
+          -194 0 rlineto
+          -135 -325 rlineto
+          -17 -43 -18 -47 -18 -46 rrcurveto
+          -5 0 rlineto
+          -16 46 -19 47 -16 43 rrcurveto
+          -142 325 rlineto
+          -193 0 rlineto
+          0 -748 rlineto
+          endchar
+        </CharString>
+      </CharStrings>
+    </CFFFont>
+
+    <GlobalSubrs>
+      <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+    </GlobalSubrs>
+  </CFF>
+
+  <GPOS>
+    <Version value="0x00010000"/>
+    <ScriptList>
+      <!-- ScriptCount=1 -->
+      <ScriptRecord index="0">
+        <ScriptTag value="DFLT"/>
+        <Script>
+          <DefaultLangSys>
+            <ReqFeatureIndex value="65535"/>
+            <!-- FeatureCount=1 -->
+            <FeatureIndex index="0" value="0"/>
+          </DefaultLangSys>
+          <!-- LangSysCount=0 -->
+        </Script>
+      </ScriptRecord>
+    </ScriptList>
+    <FeatureList>
+      <!-- FeatureCount=1 -->
+      <FeatureRecord index="0">
+        <FeatureTag value="vpal"/>
+        <Feature>
+          <!-- LookupCount=1 -->
+          <LookupListIndex index="0" value="0"/>
+        </Feature>
+      </FeatureRecord>
+    </FeatureList>
+    <LookupList>
+      <!-- LookupCount=1 -->
+      <Lookup index="0">
+        <LookupType value="1"/>
+        <LookupFlag value="0"/>
+        <!-- SubTableCount=3 -->
+        <SinglePos index="0" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uni3001"/>
+            <Glyph value="uni30FB"/>
+            <Glyph value="uniFF1A"/>
+          </Coverage>
+          <ValueFormat value="5"/>
+          <!-- ValueCount=3 -->
+          <Value index="0" XPlacement="-3" XAdvance="-500"/>
+          <Value index="1" XPlacement="-250" XAdvance="-500"/>
+          <Value index="2" XPlacement="-250" XAdvance="-500"/>
+        </SinglePos>
+        <SinglePos index="1" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uni3073"/>
+            <Glyph value="uni3074"/>
+          </Coverage>
+          <ValueFormat value="4"/>
+          <!-- ValueCount=2 -->
+          <Value index="0" XAdvance="-35"/>
+          <Value index="1" XAdvance="-30"/>
+        </SinglePos>
+        <SinglePos index="2" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uniFF2D"/>
+            <Glyph value="uni307B"/>
+          </Coverage>
+          <ValueFormat value="1"/>
+          <!-- ValueCount=2 -->
+          <Value index="0" XPlacement="1"/>
+          <Value index="1" XPlacement="10"/>
+        </SinglePos>
+      </Lookup>
+    </LookupList>
+  </GPOS>
+
+  <hmtx>
+    <mtx name=".notdef" width="250" lsb="0"/>
+    <mtx name="uni3001" width="1000" lsb="33"/>
+    <mtx name="uni3073" width="1000" lsb="52"/>
+    <mtx name="uni3074" width="1000" lsb="52"/>
+    <mtx name="uni307B" width="1000" lsb="80"/>
+    <mtx name="uni30FB" width="1000" lsb="360"/>
+    <mtx name="uniFF1A" width="1000" lsb="394"/>
+    <mtx name="uniFF2D" width="1000" lsb="113"/>
+  </hmtx>
+
+</ttFont>
diff --git a/Tests/varLib/data/test_results/BuildTestCFF2.ttx b/Tests/varLib/data/test_results/BuildTestCFF2.ttx
index 37ed3aa..91b83fc 100644
--- a/Tests/varLib/data/test_results/BuildTestCFF2.ttx
+++ b/Tests/varLib/data/test_results/BuildTestCFF2.ttx
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ttFont sfntVersion="OTTO" ttLibVersion="3.38">
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
 
   <fvar>
 
@@ -67,29 +67,29 @@
             <BlueValues>
                 <blend value="-12 0 0"/>
                 <blend value="0 0 0"/>
-                <blend value="486 -8 -8"/>
+                <blend value="486 -8 14"/>
                 <blend value="498 0 0"/>
-                <blend value="574 4 4"/>
+                <blend value="574 4 -8"/>
                 <blend value="586 0 0"/>
-                <blend value="638 6 6"/>
+                <blend value="638 6 -10"/>
                 <blend value="650 0 0"/>
-                <blend value="656 2 2"/>
+                <blend value="656 2 -2"/>
                 <blend value="668 0 0"/>
-                <blend value="712 6 6"/>
+                <blend value="712 6 -10"/>
                 <blend value="724 0 0"/>
             </BlueValues>
             <OtherBlues>
-                <blend value="-217 -17 -17"/>
+                <blend value="-217 -17 29"/>
                 <blend value="-205 0 0"/>
             </OtherBlues>
             <BlueScale value="0.0625"/>
             <BlueShift value="7"/>
             <BlueFuzz value="0"/>
             <StdHW>
-                <blend value="67 -39.0 -39.0"/>
+                <blend value="67 -39.0 67.0"/>
             </StdHW>
             <StdVW>
-                <blend value="85 -51.0 -51.0"/>
+                <blend value="85 -51.0 87.0"/>
             </StdVW>
           </Private>
         </FontDict>
diff --git a/Tests/varLib/data/test_results/FeatureVars.ttx b/Tests/varLib/data/test_results/FeatureVars.ttx
index f2f6b05..93ad795 100644
--- a/Tests/varLib/data/test_results/FeatureVars.ttx
+++ b/Tests/varLib/data/test_results/FeatureVars.ttx
@@ -33,9 +33,8 @@
         <Script>
           <DefaultLangSys>
             <ReqFeatureIndex value="65535"/>
-            <!-- FeatureCount=2 -->
+            <!-- FeatureCount=1 -->
             <FeatureIndex index="0" value="0"/>
-            <FeatureIndex index="1" value="0"/>
           </DefaultLangSys>
           <!-- LangSysCount=0 -->
         </Script>
diff --git a/Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx b/Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx
new file mode 100644
index 0000000..5ded5b9
--- /dev/null
+++ b/Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
+
+  <CFF2>
+    <major value="2"/>
+    <minor value="0"/>
+    <CFFFont name="CFF2Font">
+      <FontMatrix value="0.001 0 0 0.001 0 0"/>
+      <FDArray>
+        <FontDict index="0">
+          <Private>
+            <BlueValues>
+                <blend value="-12 0"/>
+                <blend value="0 0"/>
+                <blend value="478 8"/>
+                <blend value="490 0"/>
+                <blend value="570 -4"/>
+                <blend value="582 0"/>
+                <blend value="640 -6"/>
+                <blend value="652 0"/>
+                <blend value="660 -2"/>
+                <blend value="672 0"/>
+                <blend value="722 -6"/>
+                <blend value="734 0"/>
+            </BlueValues>
+            <OtherBlues>
+                <blend value="-234 17"/>
+                <blend value="-222 0"/>
+            </OtherBlues>
+            <BlueScale value="0.0625"/>
+            <BlueShift value="7"/>
+            <BlueFuzz value="0"/>
+            <StdHW>
+                <blend value="28 39.0"/>
+            </StdHW>
+            <StdVW>
+                <blend value="34 51.0"/>
+            </StdVW>
+          </Private>
+        </FontDict>
+      </FDArray>
+      <CharStrings>
+        <CharString name=".notdef">
+        </CharString>
+        <CharString name="A">
+        </CharString>
+      </CharStrings>
+      <VarStore Format="1">
+        <Format value="1"/>
+        <VarRegionList>
+          <!-- RegionAxisCount=1 -->
+          <!-- RegionCount=1 -->
+          <Region index="0">
+            <VarRegionAxis index="0">
+              <StartCoord value="0.0"/>
+              <PeakCoord value="1.0"/>
+              <EndCoord value="1.0"/>
+            </VarRegionAxis>
+          </Region>
+        </VarRegionList>
+        <!-- VarDataCount=1 -->
+        <VarData index="0">
+          <!-- ItemCount=0 -->
+          <NumShorts value="0"/>
+          <!-- VarRegionCount=1 -->
+          <VarRegionIndex index="0" value="0"/>
+        </VarData>
+      </VarStore>
+    </CFFFont>
+
+    <GlobalSubrs>
+      <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+    </GlobalSubrs>
+  </CFF2>
+
+</ttFont>
diff --git a/Tests/varLib/data/test_results/test_vpal.ttx b/Tests/varLib/data/test_results/test_vpal.ttx
new file mode 100644
index 0000000..334ced5
--- /dev/null
+++ b/Tests/varLib/data/test_results/test_vpal.ttx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
+
+  <GPOS>
+    <Version value="0x00010000"/>
+    <ScriptList>
+      <!-- ScriptCount=1 -->
+      <ScriptRecord index="0">
+        <ScriptTag value="DFLT"/>
+        <Script>
+          <DefaultLangSys>
+            <ReqFeatureIndex value="65535"/>
+            <!-- FeatureCount=1 -->
+            <FeatureIndex index="0" value="0"/>
+          </DefaultLangSys>
+          <!-- LangSysCount=0 -->
+        </Script>
+      </ScriptRecord>
+    </ScriptList>
+    <FeatureList>
+      <!-- FeatureCount=1 -->
+      <FeatureRecord index="0">
+        <FeatureTag value="vpal"/>
+        <Feature>
+          <!-- LookupCount=1 -->
+          <LookupListIndex index="0" value="0"/>
+        </Feature>
+      </FeatureRecord>
+    </FeatureList>
+    <LookupList>
+      <!-- LookupCount=1 -->
+      <Lookup index="0">
+        <LookupType value="1"/>
+        <LookupFlag value="0"/>
+        <!-- SubTableCount=6 -->
+        <SinglePos index="0" Format="2">
+          <Coverage Format="1">
+            <Glyph value="uniFF1A"/>
+            <Glyph value="uni3074"/>
+          </Coverage>
+          <ValueFormat value="7"/>
+          <!-- ValueCount=2 -->
+          <Value index="0" XPlacement="-250" YPlacement="0" XAdvance="-500"/>
+          <Value index="1" XPlacement="0" YPlacement="0" XAdvance="-30"/>
+        </SinglePos>
+        <SinglePos index="1" Format="1">
+          <Coverage Format="1">
+            <Glyph value="uni3001"/>
+          </Coverage>
+          <ValueFormat value="23"/>
+          <Value XPlacement="-9" YPlacement="0" XAdvance="-500">
+            <XPlaDevice>
+              <StartSize value="0"/>
+              <EndSize value="4"/>
+              <DeltaFormat value="32768"/>
+            </XPlaDevice>
+          </Value>
+        </SinglePos>
+        <SinglePos index="2" Format="1">
+          <Coverage Format="1">
+            <Glyph value="uni30FB"/>
+          </Coverage>
+          <ValueFormat value="39"/>
+          <Value XPlacement="-250" YPlacement="1" XAdvance="-500">
+            <YPlaDevice>
+              <StartSize value="0"/>
+              <EndSize value="2"/>
+              <DeltaFormat value="32768"/>
+            </YPlaDevice>
+          </Value>
+        </SinglePos>
+        <SinglePos index="3" Format="1">
+          <Coverage Format="1">
+            <Glyph value="uniFF2D"/>
+          </Coverage>
+          <ValueFormat value="87"/>
+          <Value XPlacement="12" YPlacement="0" XAdvance="23">
+            <XPlaDevice>
+              <StartSize value="0"/>
+              <EndSize value="1"/>
+              <DeltaFormat value="32768"/>
+            </XPlaDevice>
+            <XAdvDevice>
+              <StartSize value="0"/>
+              <EndSize value="0"/>
+              <DeltaFormat value="32768"/>
+            </XAdvDevice>
+          </Value>
+        </SinglePos>
+        <SinglePos index="4" Format="1">
+          <Coverage Format="1">
+            <Glyph value="uni3073"/>
+          </Coverage>
+          <ValueFormat value="71"/>
+          <Value XPlacement="0" YPlacement="0" XAdvance="-36">
+            <XAdvDevice>
+              <StartSize value="0"/>
+              <EndSize value="3"/>
+              <DeltaFormat value="32768"/>
+            </XAdvDevice>
+          </Value>
+        </SinglePos>
+        <SinglePos index="5" Format="1">
+          <Coverage Format="1">
+            <Glyph value="uni307B"/>
+          </Coverage>
+          <ValueFormat value="23"/>
+          <Value XPlacement="11" YPlacement="0" XAdvance="0">
+            <XPlaDevice>
+              <StartSize value="0"/>
+              <EndSize value="2"/>
+              <DeltaFormat value="32768"/>
+            </XPlaDevice>
+          </Value>
+        </SinglePos>
+      </Lookup>
+    </LookupList>
+  </GPOS>
+
+</ttFont>
diff --git a/Tests/varLib/data/test_vpal.designspace b/Tests/varLib/data/test_vpal.designspace
new file mode 100644
index 0000000..a736927
--- /dev/null
+++ b/Tests/varLib/data/test_vpal.designspace
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='utf-8'?>
+<designspace format="3">
+	<axes>
+		<axis default="0" maximum="1000" minimum="0" name="weight" tag="wght" />
+	</axes>
+	<sources>
+		<source filename="master_vpal_test/master_vpal_test_0.ufo" stylename="w0.00">
+			<info copy="1" />
+			<location>
+				<dimension name="weight" xvalue="0.00" />
+			</location>
+		</source>
+		<source filename="master_vpal_test/master_vpal_test_1.ufo" stylename="w1000.00">
+			<location>
+				<dimension name="weight" xvalue="1000.00" />
+			</location>
+		</source>
+	</sources>
+	<instances>
+		<instance familyname="SHSansJPVFTest" filename="instances/SHSansJPVFTest-ExtraLight.otf" postscriptfontname="SHSansJPVFTest-ExtraLight" stylename="ExtraLight">
+			<location>
+				<dimension name="weight" xvalue="0" />
+			</location>
+			<kerning />
+			<info />
+		</instance>
+		<instance familyname="SHSansJPVFTest" filename="instances/SHSansJPVFTest-Heavy.otf" postscriptfontname="SHSansJPVFTest-Heavy" stylename="Heavy">
+			<location>
+				<dimension name="weight" xvalue="1000" />
+			</location>
+			<kerning />
+			<info />
+		</instance>
+	</instances>
+</designspace>
diff --git a/Tests/varLib/varLib_test.py b/Tests/varLib/varLib_test.py
index f303733..e29befb 100644
--- a/Tests/varLib/varLib_test.py
+++ b/Tests/varLib/varLib_test.py
@@ -2,6 +2,7 @@
 from fontTools.misc.py23 import *
 from fontTools.ttLib import TTFont, newTable
 from fontTools.varLib import build
+from fontTools.varLib.mutator import instantiateVariableFont
 from fontTools.varLib import main as varLib_main, load_masters
 from fontTools.designspaceLib import (
     DesignSpaceDocumentError, DesignSpaceDocument, SourceDescriptor,
@@ -227,6 +228,28 @@
             expected_ttx_name=test_name
         )
 
+    def test_varlib_nonmarking_CFF2(self):
+        ds_path = self.get_test_input('TestNonMarkingCFF2.designspace')
+        ttx_dir = self.get_test_input("master_non_marking_cff2")
+        expected_ttx_path = self.get_test_output("TestNonMarkingCFF2.ttx")
+
+        self.temp_dir()
+        for path in self.get_file_list(ttx_dir, '.ttx', 'TestNonMarkingCFF2_'):
+            self.compile_font(path, ".otf", self.tempdir)
+
+        ds = DesignSpaceDocument.fromfile(ds_path)
+        for source in ds.sources:
+            source.path = os.path.join(
+                self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
+            )
+        ds.updatePaths()
+
+        varfont, _, _ = build(ds)
+        varfont = reload_font(varfont)
+
+        tables = ["CFF2"]
+        self.expect_ttx(varfont, expected_ttx_path, tables)
+
     def test_varlib_build_CFF2(self):
         ds_path = self.get_test_input('TestCFF2.designspace')
         ttx_dir = self.get_test_input("master_cff2")
@@ -249,7 +272,6 @@
         tables = ["fvar", "CFF2"]
         self.expect_ttx(varfont, expected_ttx_path, tables)
 
-
     def test_varlib_build_sparse_CFF2(self):
         ds_path = self.get_test_input('TestSparseCFF2VF.designspace')
         ttx_dir = self.get_test_input("master_sparse_cff2")
@@ -272,6 +294,27 @@
         tables = ["fvar", "CFF2"]
         self.expect_ttx(varfont, expected_ttx_path, tables)
 
+    def test_varlib_build_vpal(self):
+        ds_path = self.get_test_input('test_vpal.designspace')
+        ttx_dir = self.get_test_input("master_vpal_test")
+        expected_ttx_path = self.get_test_output("test_vpal.ttx")
+
+        self.temp_dir()
+        for path in self.get_file_list(ttx_dir, '.ttx', 'master_vpal_test_'):
+            self.compile_font(path, ".otf", self.tempdir)
+
+        ds = DesignSpaceDocument.fromfile(ds_path)
+        for source in ds.sources:
+            source.path = os.path.join(
+                self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
+            )
+        ds.updatePaths()
+
+        varfont, _, _ = build(ds)
+        varfont = reload_font(varfont)
+
+        tables = ["GPOS"]
+        self.expect_ttx(varfont, expected_ttx_path, tables)
 
     def test_varlib_main_ttf(self):
         """Mostly for testing varLib.main()
@@ -496,6 +539,98 @@
         self.expect_ttx(varfont, expected_ttx_path, tables)
         self.check_ttx_dump(varfont, expected_ttx_path, tables, suffix)
 
+    def test_kerning_merging(self):
+        """Test the correct merging of class-based pair kerning.
+
+        Problem description at https://github.com/fonttools/fonttools/pull/1638.
+        Test font and Designspace generated by 
+        https://gist.github.com/madig/183d0440c9f7d05f04bd1280b9664bd1.
+        """
+        ds_path = self.get_test_input("KerningMerging.designspace")
+        ttx_dir = self.get_test_input("master_kerning_merging")
+
+        ds = DesignSpaceDocument.fromfile(ds_path)
+        for source in ds.sources:
+            ttx_dump = TTFont()
+            ttx_dump.importXML(
+                os.path.join(
+                    ttx_dir, os.path.basename(source.filename).replace(".ttf", ".ttx")
+                )
+            )
+            source.font = reload_font(ttx_dump)
+
+        varfont, _, _ = build(ds)
+        varfont = reload_font(varfont)
+
+        class_kerning_tables = [
+            t
+            for l in varfont["GPOS"].table.LookupList.Lookup
+            for t in l.SubTable
+            if t.Format == 2
+        ]
+        assert len(class_kerning_tables) == 1
+        class_kerning_table = class_kerning_tables[0]
+
+        # Test that no class kerned against class zero (containing all glyphs not
+        # classed) has a `XAdvDevice` table attached, which in the variable font
+        # context is a "VariationIndex" table and points to kerning deltas in the GDEF
+        # table. Variation deltas of any kerning class against class zero should
+        # probably never exist.
+        for class1_record in class_kerning_table.Class1Record:
+            class2_zero = class1_record.Class2Record[0]
+            assert getattr(class2_zero.Value1, "XAdvDevice", None) is None
+
+        # Assert the variable font's kerning table (without deltas) is equal to the
+        # default font's kerning table. The bug fixed in 
+        # https://github.com/fonttools/fonttools/pull/1638 caused rogue kerning
+        # values to be written to the variable font.
+        assert _extract_flat_kerning(varfont, class_kerning_table) == {
+            ("A", ".notdef"): 0,
+            ("A", "A"): 0,
+            ("A", "B"): -20,
+            ("A", "C"): 0,
+            ("A", "D"): -20,
+            ("B", ".notdef"): 0,
+            ("B", "A"): 0,
+            ("B", "B"): 0,
+            ("B", "C"): 0,
+            ("B", "D"): 0,
+        }
+
+        instance_thin = instantiateVariableFont(varfont, {"wght": 100})
+        instance_thin_kerning_table = (
+            instance_thin["GPOS"].table.LookupList.Lookup[0].SubTable[0]
+        )
+        assert _extract_flat_kerning(instance_thin, instance_thin_kerning_table) == {
+            ("A", ".notdef"): 0,
+            ("A", "A"): 0,
+            ("A", "B"): 0,
+            ("A", "C"): 10,
+            ("A", "D"): 0,
+            ("B", ".notdef"): 0,
+            ("B", "A"): 0,
+            ("B", "B"): 0,
+            ("B", "C"): 10,
+            ("B", "D"): 0,
+        }
+
+        instance_black = instantiateVariableFont(varfont, {"wght": 900})
+        instance_black_kerning_table = (
+            instance_black["GPOS"].table.LookupList.Lookup[0].SubTable[0]
+        )
+        assert _extract_flat_kerning(instance_black, instance_black_kerning_table) == {
+            ("A", ".notdef"): 0,
+            ("A", "A"): 0,
+            ("A", "B"): 0,
+            ("A", "C"): 0,
+            ("A", "D"): 40,
+            ("B", ".notdef"): 0,
+            ("B", "A"): 0,
+            ("B", "B"): 0,
+            ("B", "C"): 0,
+            ("B", "D"): 40,
+        }
+
 
 def test_load_masters_layerName_without_required_font():
     ds = DesignSpaceDocument()
@@ -511,5 +646,20 @@
         load_masters(ds)
 
 
+def _extract_flat_kerning(font, pairpos_table):
+    extracted_kerning = {}
+    for glyph_name_1 in pairpos_table.Coverage.glyphs:
+        class_def_1 = pairpos_table.ClassDef1.classDefs.get(glyph_name_1, 0)
+        for glyph_name_2 in font.getGlyphOrder():
+            class_def_2 = pairpos_table.ClassDef2.classDefs.get(glyph_name_2, 0)
+            kern_value = (
+                pairpos_table.Class1Record[class_def_1]
+                .Class2Record[class_def_2]
+                .Value1.XAdvance
+            )
+            extracted_kerning[(glyph_name_1, glyph_name_2)] = kern_value
+    return extracted_kerning
+
+
 if __name__ == "__main__":
     sys.exit(unittest.main())
diff --git a/requirements.txt b/requirements.txt
index bdfd52b..8e1fe6e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,4 +8,4 @@
 munkres==1.0.12; platform_python_implementation == "PyPy" and python_version < '3.5'  # pyup: ignore
 munkres==1.1.2; platform_python_implementation == "PyPy" and python_version >= '3.5'
 zopfli==0.1.6
-fs==2.4.5
+fs==2.4.8
diff --git a/setup.cfg b/setup.cfg
index 07b99cb..c7b9d0a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 3.42.0
+current_version = 3.43.1
 commit = True
 tag = False
 tag_name = {new_version}
diff --git a/setup.py b/setup.py
index 3c6c3b6..ea4c92a 100755
--- a/setup.py
+++ b/setup.py
@@ -352,7 +352,7 @@
 
 setup(
 	name="fonttools",
-	version="3.42.0",
+	version="3.43.1",
 	description="Tools to manipulate font files",
 	author="Just van Rossum",
 	author_email="just@letterror.com",
diff --git a/tox.ini b/tox.ini
index 2e8d9ee..6a01501 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,6 +6,7 @@
 deps =
     cov: coverage>=4.3
     pytest
+    pytest-randomly
     -rrequirements.txt
 extras =
     ufo