"""_g_l_y_f.py -- Converter classes for the 'glyf' table."""

from __future__ import print_function, division, absolute_import
from collections import namedtuple
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools import ttLib
from fontTools import version
from fontTools.misc.textTools import safeEval, pad
from fontTools.misc.arrayTools import calcBounds, calcIntBounds, pointInRect
from fontTools.misc.bezierTools import calcQuadraticBounds
from fontTools.misc.fixedTools import (
	fixedToFloat as fi2fl,
	floatToFixed as fl2fi,
	otRound,
)
from numbers import Number
from . import DefaultTable
from . import ttProgram
import sys
import struct
import array
import logging
import os
from fontTools.misc import xmlWriter
from fontTools.misc.filenames import userNameToFileName

log = logging.getLogger(__name__)

# We compute the version the same as is computed in ttlib/__init__
# so that we can write 'ttLibVersion' attribute of the glyf TTX files
# when glyf is written to separate files.
version = ".".join(version.split('.')[:2])

#
# The Apple and MS rasterizers behave differently for
# scaled composite components: one does scale first and then translate
# and the other does it vice versa. MS defined some flags to indicate
# the difference, but it seems nobody actually _sets_ those flags.
#
# Funny thing: Apple seems to _only_ do their thing in the
# WE_HAVE_A_SCALE (eg. Chicago) case, and not when it's WE_HAVE_AN_X_AND_Y_SCALE
# (eg. Charcoal)...
#
SCALE_COMPONENT_OFFSET_DEFAULT = 0   # 0 == MS, 1 == Apple


class table__g_l_y_f(DefaultTable.DefaultTable):

	# this attribute controls the amount of padding applied to glyph data upon compile.
	# Glyph lenghts are aligned to multiples of the specified value. 
	# Allowed values are (0, 1, 2, 4). '0' means no padding; '1' (default) also means
	# no padding, except for when padding would allow to use short loca offsets.
	padding = 1

	def decompile(self, data, ttFont):
		loca = ttFont['loca']
		last = int(loca[0])
		noname = 0
		self.glyphs = {}
		self.glyphOrder = glyphOrder = ttFont.getGlyphOrder()
		for i in range(0, len(loca)-1):
			try:
				glyphName = glyphOrder[i]
			except IndexError:
				noname = noname + 1
				glyphName = 'ttxautoglyph%s' % i
			next = int(loca[i+1])
			glyphdata = data[last:next]
			if len(glyphdata) != (next - last):
				raise ttLib.TTLibError("not enough 'glyf' table data")
			glyph = Glyph(glyphdata)
			self.glyphs[glyphName] = glyph
			last = next
		if len(data) - next >= 4:
			log.warning(
				"too much 'glyf' table data: expected %d, received %d bytes",
				next, len(data))
		if noname:
			log.warning('%s glyphs have no name', noname)
		if ttFont.lazy is False: # Be lazy for None and True
			for glyph in self.glyphs.values():
				glyph.expand(self)

	def compile(self, ttFont):
		if not hasattr(self, "glyphOrder"):
			self.glyphOrder = ttFont.getGlyphOrder()
		padding = self.padding
		assert padding in (0, 1, 2, 4)
		locations = []
		currentLocation = 0
		dataList = []
		recalcBBoxes = ttFont.recalcBBoxes
		for glyphName in self.glyphOrder:
			glyph = self.glyphs[glyphName]
			glyphData = glyph.compile(self, recalcBBoxes)
			if padding > 1:
				glyphData = pad(glyphData, size=padding)
			locations.append(currentLocation)
			currentLocation = currentLocation + len(glyphData)
			dataList.append(glyphData)
		locations.append(currentLocation)

		if padding == 1 and currentLocation < 0x20000:
			# See if we can pad any odd-lengthed glyphs to allow loca
			# table to use the short offsets.
			indices = [i for i,glyphData in enumerate(dataList) if len(glyphData) % 2 == 1]
			if indices and currentLocation + len(indices) < 0x20000:
				# It fits.  Do it.
				for i in indices:
					dataList[i] += b'\0'
				currentLocation = 0
				for i,glyphData in enumerate(dataList):
					locations[i] = currentLocation
					currentLocation += len(glyphData)
				locations[len(dataList)] = currentLocation

		data = bytesjoin(dataList)
		if 'loca' in ttFont:
			ttFont['loca'].set(locations)
		if 'maxp' in ttFont:
			ttFont['maxp'].numGlyphs = len(self.glyphs)
		return data

	def toXML(self, writer, ttFont, splitGlyphs=False):
		notice = (
			"The xMin, yMin, xMax and yMax values\n"
			"will be recalculated by the compiler.")
		glyphNames = ttFont.getGlyphNames()
		if not splitGlyphs:
			writer.newline()
			writer.comment(notice)
			writer.newline()
			writer.newline()
		numGlyphs = len(glyphNames)
		if splitGlyphs:
			path, ext = os.path.splitext(writer.file.name)
			existingGlyphFiles = set()
		for glyphName in glyphNames:
			glyph = self[glyphName]
			if glyph.numberOfContours:
				if splitGlyphs:
					glyphPath = userNameToFileName(
						tounicode(glyphName, 'utf-8'),
						existingGlyphFiles,
						prefix=path + ".",
						suffix=ext)
					existingGlyphFiles.add(glyphPath.lower())
					glyphWriter = xmlWriter.XMLWriter(
						glyphPath, idlefunc=writer.idlefunc,
						newlinestr=writer.newlinestr)
					glyphWriter.begintag("ttFont", ttLibVersion=version)
					glyphWriter.newline()
					glyphWriter.begintag("glyf")
					glyphWriter.newline()
					glyphWriter.comment(notice)
					glyphWriter.newline()
					writer.simpletag("TTGlyph", src=os.path.basename(glyphPath))
				else:
					glyphWriter = writer
				glyphWriter.begintag('TTGlyph', [
							("name", glyphName),
							("xMin", glyph.xMin),
							("yMin", glyph.yMin),
							("xMax", glyph.xMax),
							("yMax", glyph.yMax),
							])
				glyphWriter.newline()
				glyph.toXML(glyphWriter, ttFont)
				glyphWriter.endtag('TTGlyph')
				glyphWriter.newline()
				if splitGlyphs:
					glyphWriter.endtag("glyf")
					glyphWriter.newline()
					glyphWriter.endtag("ttFont")
					glyphWriter.newline()
					glyphWriter.close()
			else:
				writer.simpletag('TTGlyph', name=glyphName)
				writer.comment("contains no outline data")
				if not splitGlyphs:
					writer.newline()
			writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		if name != "TTGlyph":
			return
		if not hasattr(self, "glyphs"):
			self.glyphs = {}
		if not hasattr(self, "glyphOrder"):
			self.glyphOrder = ttFont.getGlyphOrder()
		glyphName = attrs["name"]
		log.debug("unpacking glyph '%s'", glyphName)
		glyph = Glyph()
		for attr in ['xMin', 'yMin', 'xMax', 'yMax']:
			setattr(glyph, attr, safeEval(attrs.get(attr, '0')))
		self.glyphs[glyphName] = glyph
		for element in content:
			if not isinstance(element, tuple):
				continue
			name, attrs, content = element
			glyph.fromXML(name, attrs, content, ttFont)
		if not ttFont.recalcBBoxes:
			glyph.compact(self, 0)

	def setGlyphOrder(self, glyphOrder):
		self.glyphOrder = glyphOrder

	def getGlyphName(self, glyphID):
		return self.glyphOrder[glyphID]

	def getGlyphID(self, glyphName):
		# XXX optimize with reverse dict!!!
		return self.glyphOrder.index(glyphName)

	def removeHinting(self):
		for glyph in self.glyphs.values():
			glyph.removeHinting()

	def keys(self):
		return self.glyphs.keys()

	def has_key(self, glyphName):
		return glyphName in self.glyphs

	__contains__ = has_key

	def __getitem__(self, glyphName):
		glyph = self.glyphs[glyphName]
		glyph.expand(self)
		return glyph

	def __setitem__(self, glyphName, glyph):
		self.glyphs[glyphName] = glyph
		if glyphName not in self.glyphOrder:
			self.glyphOrder.append(glyphName)

	def __delitem__(self, glyphName):
		del self.glyphs[glyphName]
		self.glyphOrder.remove(glyphName)

	def __len__(self):
		assert len(self.glyphOrder) == len(self.glyphs)
		return len(self.glyphs)

	def getPhantomPoints(self, glyphName, ttFont, defaultVerticalOrigin=None):
		"""Compute the four "phantom points" for the given glyph from its bounding box
		and the horizontal and vertical advance widths and sidebearings stored in the
		ttFont's "hmtx" and "vmtx" tables.

		If the ttFont doesn't contain a "vmtx" table, the hhea.ascent is used as the
		vertical origin, and the head.unitsPerEm as the vertical advance.

		The "defaultVerticalOrigin" (Optional[int]) is needed when the ttFont contains
		neither a "vmtx" nor an "hhea" table, as may happen with 'sparse' masters.
		The value should be the hhea.ascent of the default master.

		https://docs.microsoft.com/en-us/typography/opentype/spec/tt_instructing_glyphs#phantoms
		"""
		glyph = self[glyphName]
		assert glyphName in ttFont["hmtx"].metrics, ttFont["hmtx"].metrics
		horizontalAdvanceWidth, leftSideBearing = ttFont["hmtx"].metrics[glyphName]
		if not hasattr(glyph, 'xMin'):
			glyph.recalcBounds(self)
		leftSideX = glyph.xMin - leftSideBearing
		rightSideX = leftSideX + horizontalAdvanceWidth
		if "vmtx" in ttFont:
			verticalAdvanceWidth, topSideBearing = ttFont["vmtx"].metrics[glyphName]
			topSideY = topSideBearing + glyph.yMax
		else:
			# without vmtx, use ascent as vertical origin and UPEM as vertical advance
			# like HarfBuzz does
			verticalAdvanceWidth = ttFont["head"].unitsPerEm
			if "hhea" in ttFont:
				topSideY = ttFont["hhea"].ascent
			else:
				# sparse masters may not contain an hhea table; use the ascent
				# of the default master as the vertical origin
				if defaultVerticalOrigin is not None:
					topSideY = defaultVerticalOrigin
				else:
					log.warning(
						"font is missing both 'vmtx' and 'hhea' tables, "
						"and no 'defaultVerticalOrigin' was provided; "
						"the vertical phantom points may be incorrect."
					)
					topSideY = verticalAdvanceWidth
		bottomSideY = topSideY - verticalAdvanceWidth
		return [
			(leftSideX, 0),
			(rightSideX, 0),
			(0, topSideY),
			(0, bottomSideY),
		]

	def getCoordinatesAndControls(self, glyphName, ttFont, defaultVerticalOrigin=None):
		"""Return glyph coordinates and controls as expected by "gvar" table.

		The coordinates includes four "phantom points" for the glyph metrics,
		as mandated by the "gvar" spec.

		The glyph controls is a namedtuple with the following attributes:
			- numberOfContours: -1 for composite glyphs.
			- endPts: list of indices of end points for each contour in simple
			glyphs, or component indices in composite glyphs (used for IUP
			optimization).
			- flags: array of contour point flags for simple glyphs (None for
			composite glyphs).
			- components: list of base glyph names (str) for each component in
			composite glyphs (None for simple glyphs).

		The "ttFont" and "defaultVerticalOrigin" args are used to compute the
		"phantom points" (see "getPhantomPoints" method).

		Return None if the requested glyphName is not present.
		"""
		if glyphName not in self.glyphs:
			return None
		glyph = self[glyphName]
		if glyph.isComposite():
			coords = GlyphCoordinates(
				[(getattr(c, 'x', 0), getattr(c, 'y', 0)) for c in glyph.components]
			)
			controls = _GlyphControls(
				numberOfContours=glyph.numberOfContours,
				endPts=list(range(len(glyph.components))),
				flags=None,
				components=[c.glyphName for c in glyph.components],
			)
		else:
			coords, endPts, flags = glyph.getCoordinates(self)
			coords = coords.copy()
			controls = _GlyphControls(
				numberOfContours=glyph.numberOfContours,
				endPts=endPts,
				flags=flags,
				components=None,
			)
		# Add phantom points for (left, right, top, bottom) positions.
		phantomPoints = self.getPhantomPoints(
			glyphName, ttFont, defaultVerticalOrigin=defaultVerticalOrigin
		)
		coords.extend(phantomPoints)
		return coords, controls

	def setCoordinates(self, glyphName, coord, ttFont):
		"""Set coordinates and metrics for the given glyph.

		"coord" is an array of GlyphCoordinates which must include the "phantom
		points" as the last four coordinates.

		Both the horizontal/vertical advances and left/top sidebearings in "hmtx"
		and "vmtx" tables (if any) are updated from four phantom points and
		the glyph's bounding boxes.
		"""
		# TODO: Create new glyph if not already present
		assert glyphName in self.glyphs
		glyph = self[glyphName]

		# Handle phantom points for (left, right, top, bottom) positions.
		assert len(coord) >= 4
		leftSideX = coord[-4][0]
		rightSideX = coord[-3][0]
		topSideY = coord[-2][1]
		bottomSideY = coord[-1][1]

		coord = coord[:-4]

		if glyph.isComposite():
			assert len(coord) == len(glyph.components)
			for p, comp in zip(coord, glyph.components):
				if hasattr(comp, 'x'):
					comp.x, comp.y = p
		elif glyph.numberOfContours == 0:
			assert len(coord) == 0
		else:
			assert len(coord) == len(glyph.coordinates)
			glyph.coordinates = GlyphCoordinates(coord)

		glyph.recalcBounds(self)

		horizontalAdvanceWidth = otRound(rightSideX - leftSideX)
		if horizontalAdvanceWidth < 0:
			# unlikely, but it can happen, see:
			# https://github.com/fonttools/fonttools/pull/1198
			horizontalAdvanceWidth = 0
		leftSideBearing = otRound(glyph.xMin - leftSideX)
		ttFont["hmtx"].metrics[glyphName] = horizontalAdvanceWidth, leftSideBearing

		if "vmtx" in ttFont:
			verticalAdvanceWidth = otRound(topSideY - bottomSideY)
			if verticalAdvanceWidth < 0:  # unlikely but do the same as horizontal
				verticalAdvanceWidth = 0
			topSideBearing = otRound(topSideY - glyph.yMax)
			ttFont["vmtx"].metrics[glyphName] = verticalAdvanceWidth, topSideBearing


_GlyphControls = namedtuple(
	"_GlyphControls", "numberOfContours endPts flags components"
)


glyphHeaderFormat = """
		>	# big endian
		numberOfContours:	h
		xMin:				h
		yMin:				h
		xMax:				h
		yMax:				h
"""

# flags
flagOnCurve = 0x01
flagXShort = 0x02
flagYShort = 0x04
flagRepeat = 0x08
flagXsame =  0x10
flagYsame = 0x20
flagOverlapSimple = 0x40
flagReserved = 0x80

# These flags are kept for XML output after decompiling the coordinates
keepFlags = flagOnCurve + flagOverlapSimple

_flagSignBytes = {
	0: 2,
	flagXsame: 0,
	flagXShort|flagXsame: +1,
	flagXShort: -1,
	flagYsame: 0,
	flagYShort|flagYsame: +1,
	flagYShort: -1,
}

def flagBest(x, y, onCurve):
	"""For a given x,y delta pair, returns the flag that packs this pair
	most efficiently, as well as the number of byte cost of such flag."""

	flag = flagOnCurve if onCurve else 0
	cost = 0
	# do x
	if x == 0:
		flag = flag | flagXsame
	elif -255 <= x <= 255:
		flag = flag | flagXShort
		if x > 0:
			flag = flag | flagXsame
		cost += 1
	else:
		cost += 2
	# do y
	if y == 0:
		flag = flag | flagYsame
	elif -255 <= y <= 255:
		flag = flag | flagYShort
		if y > 0:
			flag = flag | flagYsame
		cost += 1
	else:
		cost += 2
	return flag, cost

def flagFits(newFlag, oldFlag, mask):
	newBytes = _flagSignBytes[newFlag & mask]
	oldBytes = _flagSignBytes[oldFlag & mask]
	return newBytes == oldBytes or abs(newBytes) > abs(oldBytes)

def flagSupports(newFlag, oldFlag):
	return ((oldFlag & flagOnCurve) == (newFlag & flagOnCurve) and
		flagFits(newFlag, oldFlag, flagXsame|flagXShort) and
		flagFits(newFlag, oldFlag, flagYsame|flagYShort))

def flagEncodeCoord(flag, mask, coord, coordBytes):
	byteCount = _flagSignBytes[flag & mask]
	if byteCount == 1:
		coordBytes.append(coord)
	elif byteCount == -1:
		coordBytes.append(-coord)
	elif byteCount == 2:
		coordBytes.append((coord >> 8) & 0xFF)
		coordBytes.append(coord & 0xFF)

def flagEncodeCoords(flag, x, y, xBytes, yBytes):
	flagEncodeCoord(flag, flagXsame|flagXShort, x, xBytes)
	flagEncodeCoord(flag, flagYsame|flagYShort, y, yBytes)


ARG_1_AND_2_ARE_WORDS		= 0x0001  # if set args are words otherwise they are bytes
ARGS_ARE_XY_VALUES		= 0x0002  # if set args are xy values, otherwise they are points
ROUND_XY_TO_GRID		= 0x0004  # for the xy values if above is true
WE_HAVE_A_SCALE			= 0x0008  # Sx = Sy, otherwise scale == 1.0
NON_OVERLAPPING			= 0x0010  # set to same value for all components (obsolete!)
MORE_COMPONENTS			= 0x0020  # indicates at least one more glyph after this one
WE_HAVE_AN_X_AND_Y_SCALE	= 0x0040  # Sx, Sy
WE_HAVE_A_TWO_BY_TWO		= 0x0080  # t00, t01, t10, t11
WE_HAVE_INSTRUCTIONS		= 0x0100  # instructions follow
USE_MY_METRICS			= 0x0200  # apply these metrics to parent glyph
OVERLAP_COMPOUND		= 0x0400  # used by Apple in GX fonts
SCALED_COMPONENT_OFFSET		= 0x0800  # composite designed to have the component offset scaled (designed for Apple)
UNSCALED_COMPONENT_OFFSET	= 0x1000  # composite designed not to have the component offset scaled (designed for MS)


CompositeMaxpValues = namedtuple('CompositeMaxpValues', ['nPoints', 'nContours', 'maxComponentDepth'])


class Glyph(object):

	def __init__(self, data=""):
		if not data:
			# empty char
			self.numberOfContours = 0
			return
		self.data = data

	def compact(self, glyfTable, recalcBBoxes=True):
		data = self.compile(glyfTable, recalcBBoxes)
		self.__dict__.clear()
		self.data = data

	def expand(self, glyfTable):
		if not hasattr(self, "data"):
			# already unpacked
			return
		if not self.data:
			# empty char
			del self.data
			self.numberOfContours = 0
			return
		dummy, data = sstruct.unpack2(glyphHeaderFormat, self.data, self)
		del self.data
		# Some fonts (eg. Neirizi.ttf) have a 0 for numberOfContours in
		# some glyphs; decompileCoordinates assumes that there's at least
		# one, so short-circuit here.
		if self.numberOfContours == 0:
			return
		if self.isComposite():
			self.decompileComponents(data, glyfTable)
		else:
			self.decompileCoordinates(data)

	def compile(self, glyfTable, recalcBBoxes=True):
		if hasattr(self, "data"):
			if recalcBBoxes:
				# must unpack glyph in order to recalculate bounding box
				self.expand(glyfTable)
			else:
				return self.data
		if self.numberOfContours == 0:
			return ""
		if recalcBBoxes:
			self.recalcBounds(glyfTable)
		data = sstruct.pack(glyphHeaderFormat, self)
		if self.isComposite():
			data = data + self.compileComponents(glyfTable)
		else:
			data = data + self.compileCoordinates()
		return data

	def toXML(self, writer, ttFont):
		if self.isComposite():
			for compo in self.components:
				compo.toXML(writer, ttFont)
			haveInstructions = hasattr(self, "program")
		else:
			last = 0
			for i in range(self.numberOfContours):
				writer.begintag("contour")
				writer.newline()
				for j in range(last, self.endPtsOfContours[i] + 1):
					attrs = [
							("x", self.coordinates[j][0]),
							("y", self.coordinates[j][1]),
							("on", self.flags[j] & flagOnCurve),
						]
					if self.flags[j] & flagOverlapSimple:
						# Apple's rasterizer uses flagOverlapSimple in the first contour/first pt to flag glyphs that contain overlapping contours
						attrs.append(("overlap", 1))
					writer.simpletag("pt", attrs)
					writer.newline()
				last = self.endPtsOfContours[i] + 1
				writer.endtag("contour")
				writer.newline()
			haveInstructions = self.numberOfContours > 0
		if haveInstructions:
			if self.program:
				writer.begintag("instructions")
				writer.newline()
				self.program.toXML(writer, ttFont)
				writer.endtag("instructions")
			else:
				writer.simpletag("instructions")
			writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		if name == "contour":
			if self.numberOfContours < 0:
				raise ttLib.TTLibError("can't mix composites and contours in glyph")
			self.numberOfContours = self.numberOfContours + 1
			coordinates = GlyphCoordinates()
			flags = []
			for element in content:
				if not isinstance(element, tuple):
					continue
				name, attrs, content = element
				if name != "pt":
					continue  # ignore anything but "pt"
				coordinates.append((safeEval(attrs["x"]), safeEval(attrs["y"])))
				flag = not not safeEval(attrs["on"])
				if "overlap" in attrs and bool(safeEval(attrs["overlap"])):
					flag |= flagOverlapSimple
				flags.append(flag)
			flags = array.array("B", flags)
			if not hasattr(self, "coordinates"):
				self.coordinates = coordinates
				self.flags = flags
				self.endPtsOfContours = [len(coordinates)-1]
			else:
				self.coordinates.extend (coordinates)
				self.flags.extend(flags)
				self.endPtsOfContours.append(len(self.coordinates)-1)
		elif name == "component":
			if self.numberOfContours > 0:
				raise ttLib.TTLibError("can't mix composites and contours in glyph")
			self.numberOfContours = -1
			if not hasattr(self, "components"):
				self.components = []
			component = GlyphComponent()
			self.components.append(component)
			component.fromXML(name, attrs, content, ttFont)
		elif name == "instructions":
			self.program = ttProgram.Program()
			for element in content:
				if not isinstance(element, tuple):
					continue
				name, attrs, content = element
				self.program.fromXML(name, attrs, content, ttFont)

	def getCompositeMaxpValues(self, glyfTable, maxComponentDepth=1):
		assert self.isComposite()
		nContours = 0
		nPoints = 0
		for compo in self.components:
			baseGlyph = glyfTable[compo.glyphName]
			if baseGlyph.numberOfContours == 0:
				continue
			elif baseGlyph.numberOfContours > 0:
				nP, nC = baseGlyph.getMaxpValues()
			else:
				nP, nC, maxComponentDepth = baseGlyph.getCompositeMaxpValues(
						glyfTable, maxComponentDepth + 1)
			nPoints = nPoints + nP
			nContours = nContours + nC
		return CompositeMaxpValues(nPoints, nContours, maxComponentDepth)

	def getMaxpValues(self):
		assert self.numberOfContours > 0
		return len(self.coordinates), len(self.endPtsOfContours)

	def decompileComponents(self, data, glyfTable):
		self.components = []
		more = 1
		haveInstructions = 0
		while more:
			component = GlyphComponent()
			more, haveInstr, data = component.decompile(data, glyfTable)
			haveInstructions = haveInstructions | haveInstr
			self.components.append(component)
		if haveInstructions:
			numInstructions, = struct.unpack(">h", data[:2])
			data = data[2:]
			self.program = ttProgram.Program()
			self.program.fromBytecode(data[:numInstructions])
			data = data[numInstructions:]
			if len(data) >= 4:
				log.warning(
					"too much glyph data at the end of composite glyph: %d excess bytes",
					len(data))

	def decompileCoordinates(self, data):
		endPtsOfContours = array.array("h")
		endPtsOfContours.fromstring(data[:2*self.numberOfContours])
		if sys.byteorder != "big": endPtsOfContours.byteswap()
		self.endPtsOfContours = endPtsOfContours.tolist()

		data = data[2*self.numberOfContours:]

		instructionLength, = struct.unpack(">h", data[:2])
		data = data[2:]
		self.program = ttProgram.Program()
		self.program.fromBytecode(data[:instructionLength])
		data = data[instructionLength:]
		nCoordinates = self.endPtsOfContours[-1] + 1
		flags, xCoordinates, yCoordinates = \
				self.decompileCoordinatesRaw(nCoordinates, data)

		# fill in repetitions and apply signs
		self.coordinates = coordinates = GlyphCoordinates.zeros(nCoordinates)
		xIndex = 0
		yIndex = 0
		for i in range(nCoordinates):
			flag = flags[i]
			# x coordinate
			if flag & flagXShort:
				if flag & flagXsame:
					x = xCoordinates[xIndex]
				else:
					x = -xCoordinates[xIndex]
				xIndex = xIndex + 1
			elif flag & flagXsame:
				x = 0
			else:
				x = xCoordinates[xIndex]
				xIndex = xIndex + 1
			# y coordinate
			if flag & flagYShort:
				if flag & flagYsame:
					y = yCoordinates[yIndex]
				else:
					y = -yCoordinates[yIndex]
				yIndex = yIndex + 1
			elif flag & flagYsame:
				y = 0
			else:
				y = yCoordinates[yIndex]
				yIndex = yIndex + 1
			coordinates[i] = (x, y)
		assert xIndex == len(xCoordinates)
		assert yIndex == len(yCoordinates)
		coordinates.relativeToAbsolute()
		# discard all flags except "keepFlags"
		self.flags = array.array("B", (f & keepFlags for f in flags))

	def decompileCoordinatesRaw(self, nCoordinates, data):
		# unpack flags and prepare unpacking of coordinates
		flags = array.array("B", [0] * nCoordinates)
		# Warning: deep Python trickery going on. We use the struct module to unpack
		# the coordinates. We build a format string based on the flags, so we can
		# unpack the coordinates in one struct.unpack() call.
		xFormat = ">" # big endian
		yFormat = ">" # big endian
		i = j = 0
		while True:
			flag = byteord(data[i])
			i = i + 1
			repeat = 1
			if flag & flagRepeat:
				repeat = byteord(data[i]) + 1
				i = i + 1
			for k in range(repeat):
				if flag & flagXShort:
					xFormat = xFormat + 'B'
				elif not (flag & flagXsame):
					xFormat = xFormat + 'h'
				if flag & flagYShort:
					yFormat = yFormat + 'B'
				elif not (flag & flagYsame):
					yFormat = yFormat + 'h'
				flags[j] = flag
				j = j + 1
			if j >= nCoordinates:
				break
		assert j == nCoordinates, "bad glyph flags"
		data = data[i:]
		# unpack raw coordinates, krrrrrr-tching!
		xDataLen = struct.calcsize(xFormat)
		yDataLen = struct.calcsize(yFormat)
		if len(data) - (xDataLen + yDataLen) >= 4:
			log.warning(
				"too much glyph data: %d excess bytes", len(data) - (xDataLen + yDataLen))
		xCoordinates = struct.unpack(xFormat, data[:xDataLen])
		yCoordinates = struct.unpack(yFormat, data[xDataLen:xDataLen+yDataLen])
		return flags, xCoordinates, yCoordinates

	def compileComponents(self, glyfTable):
		data = b""
		lastcomponent = len(self.components) - 1
		more = 1
		haveInstructions = 0
		for i in range(len(self.components)):
			if i == lastcomponent:
				haveInstructions = hasattr(self, "program")
				more = 0
			compo = self.components[i]
			data = data + compo.compile(more, haveInstructions, glyfTable)
		if haveInstructions:
			instructions = self.program.getBytecode()
			data = data + struct.pack(">h", len(instructions)) + instructions
		return data

	def compileCoordinates(self):
		assert len(self.coordinates) == len(self.flags)
		data = []
		endPtsOfContours = array.array("h", self.endPtsOfContours)
		if sys.byteorder != "big": endPtsOfContours.byteswap()
		data.append(endPtsOfContours.tostring())
		instructions = self.program.getBytecode()
		data.append(struct.pack(">h", len(instructions)))
		data.append(instructions)

		deltas = self.coordinates.copy()
		if deltas.isFloat():
			# Warn?
			deltas.toInt()
		deltas.absoluteToRelative()

		# TODO(behdad): Add a configuration option for this?
		deltas = self.compileDeltasGreedy(self.flags, deltas)
		#deltas = self.compileDeltasOptimal(self.flags, deltas)

		data.extend(deltas)
		return bytesjoin(data)

	def compileDeltasGreedy(self, flags, deltas):
		# Implements greedy algorithm for packing coordinate deltas:
		# uses shortest representation one coordinate at a time.
		compressedflags = []
		xPoints = []
		yPoints = []
		lastflag = None
		repeat = 0
		for flag,(x,y) in zip(flags, deltas):
			# Oh, the horrors of TrueType
			# do x
			if x == 0:
				flag = flag | flagXsame
			elif -255 <= x <= 255:
				flag = flag | flagXShort
				if x > 0:
					flag = flag | flagXsame
				else:
					x = -x
				xPoints.append(bytechr(x))
			else:
				xPoints.append(struct.pack(">h", x))
			# do y
			if y == 0:
				flag = flag | flagYsame
			elif -255 <= y <= 255:
				flag = flag | flagYShort
				if y > 0:
					flag = flag | flagYsame
				else:
					y = -y
				yPoints.append(bytechr(y))
			else:
				yPoints.append(struct.pack(">h", y))
			# handle repeating flags
			if flag == lastflag and repeat != 255:
				repeat = repeat + 1
				if repeat == 1:
					compressedflags.append(flag)
				else:
					compressedflags[-2] = flag | flagRepeat
					compressedflags[-1] = repeat
			else:
				repeat = 0
				compressedflags.append(flag)
			lastflag = flag
		compressedFlags = array.array("B", compressedflags).tostring()
		compressedXs = bytesjoin(xPoints)
		compressedYs = bytesjoin(yPoints)
		return (compressedFlags, compressedXs, compressedYs)

	def compileDeltasOptimal(self, flags, deltas):
		# Implements optimal, dynaic-programming, algorithm for packing coordinate
		# deltas.  The savings are negligible :(.
		candidates = []
		bestTuple = None
		bestCost = 0
		repeat = 0
		for flag,(x,y) in zip(flags, deltas):
			# Oh, the horrors of TrueType
			flag, coordBytes = flagBest(x, y, flag)
			bestCost += 1 + coordBytes
			newCandidates = [(bestCost, bestTuple, flag, coordBytes),
							(bestCost+1, bestTuple, (flag|flagRepeat), coordBytes)]
			for lastCost,lastTuple,lastFlag,coordBytes in candidates:
				if lastCost + coordBytes <= bestCost + 1 and (lastFlag & flagRepeat) and (lastFlag < 0xff00) and flagSupports(lastFlag, flag):
					if (lastFlag & 0xFF) == (flag|flagRepeat) and lastCost == bestCost + 1:
						continue
					newCandidates.append((lastCost + coordBytes, lastTuple, lastFlag+256, coordBytes))
			candidates = newCandidates
			bestTuple = min(candidates, key=lambda t:t[0])
			bestCost = bestTuple[0]

		flags = []
		while bestTuple:
			cost, bestTuple, flag, coordBytes = bestTuple
			flags.append(flag)
		flags.reverse()

		compressedFlags = array.array("B")
		compressedXs = array.array("B")
		compressedYs = array.array("B")
		coords = iter(deltas)
		ff = []
		for flag in flags:
			repeatCount, flag = flag >> 8, flag & 0xFF
			compressedFlags.append(flag)
			if flag & flagRepeat:
				assert(repeatCount > 0)
				compressedFlags.append(repeatCount)
			else:
				assert(repeatCount == 0)
			for i in range(1 + repeatCount):
				x,y = next(coords)
				flagEncodeCoords(flag, x, y, compressedXs, compressedYs)
				ff.append(flag)
		try:
			next(coords)
			raise Exception("internal error")
		except StopIteration:
			pass
		compressedFlags = compressedFlags.tostring()
		compressedXs = compressedXs.tostring()
		compressedYs = compressedYs.tostring()

		return (compressedFlags, compressedXs, compressedYs)

	def recalcBounds(self, glyfTable):
		coords, endPts, flags = self.getCoordinates(glyfTable)
		if len(coords) > 0:
			if 0:
				# This branch calculates exact glyph outline bounds
				# analytically, handling cases without on-curve
				# extremas, etc.  However, the glyf table header
				# simply says that the bounds should be min/max x/y
				# "for coordinate data", so I suppose that means no
				# fancy thing here, just get extremas of all coord
				# points (on and off).  As such, this branch is
				# disabled.

				# Collect on-curve points
				onCurveCoords = [coords[j] for j in range(len(coords))
								if flags[j] & flagOnCurve]
				# Add implicit on-curve points
				start = 0
				for end in endPts:
					last = end
					for j in range(start, end + 1):
						if not ((flags[j] | flags[last]) & flagOnCurve):
							x = (coords[last][0] + coords[j][0]) / 2
							y = (coords[last][1] + coords[j][1]) / 2
							onCurveCoords.append((x,y))
						last = j
					start = end + 1
				# Add bounds for curves without an explicit extrema
				start = 0
				for end in endPts:
					last = end
					for j in range(start, end + 1):
						if not (flags[j] & flagOnCurve):
							next = j + 1 if j < end else start
							bbox = calcBounds([coords[last], coords[next]])
							if not pointInRect(coords[j], bbox):
								# Ouch!
								log.warning("Outline has curve with implicit extrema.")
								# Ouch!  Find analytical curve bounds.
								pthis = coords[j]
								plast = coords[last]
								if not (flags[last] & flagOnCurve):
									plast = ((pthis[0]+plast[0])/2, (pthis[1]+plast[1])/2)
								pnext = coords[next]
								if not (flags[next] & flagOnCurve):
									pnext = ((pthis[0]+pnext[0])/2, (pthis[1]+pnext[1])/2)
								bbox = calcQuadraticBounds(plast, pthis, pnext)
								onCurveCoords.append((bbox[0],bbox[1]))
								onCurveCoords.append((bbox[2],bbox[3]))
						last = j
					start = end + 1

				self.xMin, self.yMin, self.xMax, self.yMax = calcIntBounds(onCurveCoords)
			else:
				self.xMin, self.yMin, self.xMax, self.yMax = calcIntBounds(coords)
		else:
			self.xMin, self.yMin, self.xMax, self.yMax = (0, 0, 0, 0)

	def isComposite(self):
		"""Can be called on compact or expanded glyph."""
		if hasattr(self, "data") and self.data:
			return struct.unpack(">h", self.data[:2])[0] == -1
		else:
			return self.numberOfContours == -1

	def __getitem__(self, componentIndex):
		if not self.isComposite():
			raise ttLib.TTLibError("can't use glyph as sequence")
		return self.components[componentIndex]

	def getCoordinates(self, glyfTable):
		if self.numberOfContours > 0:
			return self.coordinates, self.endPtsOfContours, self.flags
		elif self.isComposite():
			# it's a composite
			allCoords = GlyphCoordinates()
			allFlags = array.array("B")
			allEndPts = []
			for compo in self.components:
				g = glyfTable[compo.glyphName]
				try:
					coordinates, endPts, flags = g.getCoordinates(glyfTable)
				except RecursionError:
					raise ttLib.TTLibError("glyph '%s' contains a recursive component reference" % compo.glyphName)
				if hasattr(compo, "firstPt"):
					# move according to two reference points
					x1,y1 = allCoords[compo.firstPt]
					x2,y2 = coordinates[compo.secondPt]
					move = x1-x2, y1-y2
				else:
					move = compo.x, compo.y

				coordinates = GlyphCoordinates(coordinates)
				if not hasattr(compo, "transform"):
					coordinates.translate(move)
				else:
					apple_way = compo.flags & SCALED_COMPONENT_OFFSET
					ms_way = compo.flags & UNSCALED_COMPONENT_OFFSET
					assert not (apple_way and ms_way)
					if not (apple_way or ms_way):
						scale_component_offset = SCALE_COMPONENT_OFFSET_DEFAULT  # see top of this file
					else:
						scale_component_offset = apple_way
					if scale_component_offset:
						# the Apple way: first move, then scale (ie. scale the component offset)
						coordinates.translate(move)
						coordinates.transform(compo.transform)
					else:
						# the MS way: first scale, then move
						coordinates.transform(compo.transform)
						coordinates.translate(move)
				offset = len(allCoords)
				allEndPts.extend(e + offset for e in endPts)
				allCoords.extend(coordinates)
				allFlags.extend(flags)
			return allCoords, allEndPts, allFlags
		else:
			return GlyphCoordinates(), [], array.array("B")

	def getComponentNames(self, glyfTable):
		if not hasattr(self, "data"):
			if self.isComposite():
				return [c.glyphName for c in self.components]
			else:
				return []

		# Extract components without expanding glyph

		if not self.data or struct.unpack(">h", self.data[:2])[0] >= 0:
			return []  # Not composite

		data = self.data
		i = 10
		components = []
		more = 1
		while more:
			flags, glyphID = struct.unpack(">HH", data[i:i+4])
			i += 4
			flags = int(flags)
			components.append(glyfTable.getGlyphName(int(glyphID)))

			if flags & ARG_1_AND_2_ARE_WORDS: i += 4
			else: i += 2
			if flags & WE_HAVE_A_SCALE: i += 2
			elif flags & WE_HAVE_AN_X_AND_Y_SCALE: i += 4
			elif flags & WE_HAVE_A_TWO_BY_TWO: i += 8
			more = flags & MORE_COMPONENTS

		return components

	def trim(self, remove_hinting=False):
		""" Remove padding and, if requested, hinting, from a glyph.
			This works on both expanded and compacted glyphs, without
			expanding it."""
		if not hasattr(self, "data"):
			if remove_hinting:
				if self.isComposite():
					if hasattr(self, "program"):
						del self.program
				else:
					self.program = ttProgram.Program()
					self.program.fromBytecode([])
			# No padding to trim.
			return
		if not self.data:
			return
		numContours = struct.unpack(">h", self.data[:2])[0]
		data = array.array("B", self.data)
		i = 10
		if numContours >= 0:
			i += 2 * numContours # endPtsOfContours
			nCoordinates = ((data[i-2] << 8) | data[i-1]) + 1
			instructionLen = (data[i] << 8) | data[i+1]
			if remove_hinting:
				# Zero instruction length
				data[i] = data [i+1] = 0
				i += 2
				if instructionLen:
					# Splice it out
					data = data[:i] + data[i+instructionLen:]
				instructionLen = 0
			else:
				i += 2 + instructionLen

			coordBytes = 0
			j = 0
			while True:
				flag = data[i]
				i = i + 1
				repeat = 1
				if flag & flagRepeat:
					repeat = data[i] + 1
					i = i + 1
				xBytes = yBytes = 0
				if flag & flagXShort:
					xBytes = 1
				elif not (flag & flagXsame):
					xBytes = 2
				if flag & flagYShort:
					yBytes = 1
				elif not (flag & flagYsame):
					yBytes = 2
				coordBytes += (xBytes + yBytes) * repeat
				j += repeat
				if j >= nCoordinates:
					break
			assert j == nCoordinates, "bad glyph flags"
			i += coordBytes
			# Remove padding
			data = data[:i]
		else:
			more = 1
			we_have_instructions = False
			while more:
				flags =(data[i] << 8) | data[i+1]
				if remove_hinting:
					flags &= ~WE_HAVE_INSTRUCTIONS
				if flags & WE_HAVE_INSTRUCTIONS:
					we_have_instructions = True
				data[i+0] = flags >> 8
				data[i+1] = flags & 0xFF
				i += 4
				flags = int(flags)

				if flags & ARG_1_AND_2_ARE_WORDS: i += 4
				else: i += 2
				if flags & WE_HAVE_A_SCALE: i += 2
				elif flags & WE_HAVE_AN_X_AND_Y_SCALE: i += 4
				elif flags & WE_HAVE_A_TWO_BY_TWO: i += 8
				more = flags & MORE_COMPONENTS
			if we_have_instructions:
				instructionLen = (data[i] << 8) | data[i+1]
				i += 2 + instructionLen
			# Remove padding
			data = data[:i]

		self.data = data.tostring()

	def removeHinting(self):
		self.trim (remove_hinting=True)

	def draw(self, pen, glyfTable, offset=0):

		if self.isComposite():
			for component in self.components:
				glyphName, transform = component.getComponentInfo()
				pen.addComponent(glyphName, transform)
			return

		coordinates, endPts, flags = self.getCoordinates(glyfTable)
		if offset:
			coordinates = coordinates.copy()
			coordinates.translate((offset, 0))
		start = 0
		for end in endPts:
			end = end + 1
			contour = coordinates[start:end]
			cFlags = flags[start:end]
			start = end
			if 1 not in cFlags:
				# There is not a single on-curve point on the curve,
				# use pen.qCurveTo's special case by specifying None
				# as the on-curve point.
				contour.append(None)
				pen.qCurveTo(*contour)
			else:
				# Shuffle the points so that contour the is guaranteed
				# to *end* in an on-curve point, which we'll use for
				# the moveTo.
				firstOnCurve = cFlags.index(1) + 1
				contour = contour[firstOnCurve:] + contour[:firstOnCurve]
				cFlags = cFlags[firstOnCurve:] + cFlags[:firstOnCurve]
				pen.moveTo(contour[-1])
				while contour:
					nextOnCurve = cFlags.index(1) + 1
					if nextOnCurve == 1:
						pen.lineTo(contour[0])
					else:
						pen.qCurveTo(*contour[:nextOnCurve])
					contour = contour[nextOnCurve:]
					cFlags = cFlags[nextOnCurve:]
			pen.closePath()

	def drawPoints(self, pen, glyfTable, offset=0):
		"""Draw the glyph using the supplied pointPen. Opposed to Glyph.draw(),
		this will not change the point indices.
		"""

		if self.isComposite():
			for component in self.components:
				glyphName, transform = component.getComponentInfo()
				pen.addComponent(glyphName, transform)
			return

		coordinates, endPts, flags = self.getCoordinates(glyfTable)
		if offset:
			coordinates = coordinates.copy()
			coordinates.translate((offset, 0))
		start = 0
		for end in endPts:
			end = end + 1
			contour = coordinates[start:end]
			cFlags = flags[start:end]
			start = end
			pen.beginPath()
			# Start with the appropriate segment type based on the final segment
			segmentType = "line" if cFlags[-1] == 1 else "qcurve"
			for i, pt in enumerate(contour):
				if cFlags[i] == 1:
					pen.addPoint(pt, segmentType=segmentType)
					segmentType = "line"
				else:
					pen.addPoint(pt)
					segmentType = "qcurve"
			pen.endPath()

	def __eq__(self, other):
		if type(self) != type(other):
			return NotImplemented
		return self.__dict__ == other.__dict__

	def __ne__(self, other):
		result = self.__eq__(other)
		return result if result is NotImplemented else not result

class GlyphComponent(object):

	def __init__(self):
		pass

	def getComponentInfo(self):
		"""Return the base glyph name and a transform."""
		# XXX Ignoring self.firstPt & self.lastpt for now: I need to implement
		# something equivalent in fontTools.objects.glyph (I'd rather not
		# convert it to an absolute offset, since it is valuable information).
		# This method will now raise "AttributeError: x" on glyphs that use
		# this TT feature.
		if hasattr(self, "transform"):
			[[xx, xy], [yx, yy]] = self.transform
			trans = (xx, xy, yx, yy, self.x, self.y)
		else:
			trans = (1, 0, 0, 1, self.x, self.y)
		return self.glyphName, trans

	def decompile(self, data, glyfTable):
		flags, glyphID = struct.unpack(">HH", data[:4])
		self.flags = int(flags)
		glyphID = int(glyphID)
		self.glyphName = glyfTable.getGlyphName(int(glyphID))
		data = data[4:]

		if self.flags & ARG_1_AND_2_ARE_WORDS:
			if self.flags & ARGS_ARE_XY_VALUES:
				self.x, self.y = struct.unpack(">hh", data[:4])
			else:
				x, y = struct.unpack(">HH", data[:4])
				self.firstPt, self.secondPt = int(x), int(y)
			data = data[4:]
		else:
			if self.flags & ARGS_ARE_XY_VALUES:
				self.x, self.y = struct.unpack(">bb", data[:2])
			else:
				x, y = struct.unpack(">BB", data[:2])
				self.firstPt, self.secondPt = int(x), int(y)
			data = data[2:]

		if self.flags & WE_HAVE_A_SCALE:
			scale, = struct.unpack(">h", data[:2])
			self.transform = [[fi2fl(scale,14), 0], [0, fi2fl(scale,14)]]  # fixed 2.14
			data = data[2:]
		elif self.flags & WE_HAVE_AN_X_AND_Y_SCALE:
			xscale, yscale = struct.unpack(">hh", data[:4])
			self.transform = [[fi2fl(xscale,14), 0], [0, fi2fl(yscale,14)]]  # fixed 2.14
			data = data[4:]
		elif self.flags & WE_HAVE_A_TWO_BY_TWO:
			(xscale, scale01,
					scale10, yscale) = struct.unpack(">hhhh", data[:8])
			self.transform = [[fi2fl(xscale,14), fi2fl(scale01,14)],
							[fi2fl(scale10,14), fi2fl(yscale,14)]] # fixed 2.14
			data = data[8:]
		more = self.flags & MORE_COMPONENTS
		haveInstructions = self.flags & WE_HAVE_INSTRUCTIONS
		self.flags = self.flags & (ROUND_XY_TO_GRID | USE_MY_METRICS |
				SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET |
				NON_OVERLAPPING | OVERLAP_COMPOUND)
		return more, haveInstructions, data

	def compile(self, more, haveInstructions, glyfTable):
		data = b""

		# reset all flags we will calculate ourselves
		flags = self.flags & (ROUND_XY_TO_GRID | USE_MY_METRICS |
				SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET |
				NON_OVERLAPPING | OVERLAP_COMPOUND)
		if more:
			flags = flags | MORE_COMPONENTS
		if haveInstructions:
			flags = flags | WE_HAVE_INSTRUCTIONS

		if hasattr(self, "firstPt"):
			if (0 <= self.firstPt <= 255) and (0 <= self.secondPt <= 255):
				data = data + struct.pack(">BB", self.firstPt, self.secondPt)
			else:
				data = data + struct.pack(">HH", self.firstPt, self.secondPt)
				flags = flags | ARG_1_AND_2_ARE_WORDS
		else:
			x = otRound(self.x)
			y = otRound(self.y)
			flags = flags | ARGS_ARE_XY_VALUES
			if (-128 <= x <= 127) and (-128 <= y <= 127):
				data = data + struct.pack(">bb", x, y)
			else:
				data = data + struct.pack(">hh", x, y)
				flags = flags | ARG_1_AND_2_ARE_WORDS

		if hasattr(self, "transform"):
			transform = [[fl2fi(x,14) for x in row] for row in self.transform]
			if transform[0][1] or transform[1][0]:
				flags = flags | WE_HAVE_A_TWO_BY_TWO
				data = data + struct.pack(">hhhh",
						transform[0][0], transform[0][1],
						transform[1][0], transform[1][1])
			elif transform[0][0] != transform[1][1]:
				flags = flags | WE_HAVE_AN_X_AND_Y_SCALE
				data = data + struct.pack(">hh",
						transform[0][0], transform[1][1])
			else:
				flags = flags | WE_HAVE_A_SCALE
				data = data + struct.pack(">h",
						transform[0][0])

		glyphID = glyfTable.getGlyphID(self.glyphName)
		return struct.pack(">HH", flags, glyphID) + data

	def toXML(self, writer, ttFont):
		attrs = [("glyphName", self.glyphName)]
		if not hasattr(self, "firstPt"):
			attrs = attrs + [("x", self.x), ("y", self.y)]
		else:
			attrs = attrs + [("firstPt", self.firstPt), ("secondPt", self.secondPt)]

		if hasattr(self, "transform"):
			transform = self.transform
			if transform[0][1] or transform[1][0]:
				attrs = attrs + [
						("scalex", transform[0][0]), ("scale01", transform[0][1]),
						("scale10", transform[1][0]), ("scaley", transform[1][1]),
						]
			elif transform[0][0] != transform[1][1]:
				attrs = attrs + [
						("scalex", transform[0][0]), ("scaley", transform[1][1]),
						]
			else:
				attrs = attrs + [("scale", transform[0][0])]
		attrs = attrs + [("flags", hex(self.flags))]
		writer.simpletag("component", attrs)
		writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		self.glyphName = attrs["glyphName"]
		if "firstPt" in attrs:
			self.firstPt = safeEval(attrs["firstPt"])
			self.secondPt = safeEval(attrs["secondPt"])
		else:
			self.x = safeEval(attrs["x"])
			self.y = safeEval(attrs["y"])
		if "scale01" in attrs:
			scalex = safeEval(attrs["scalex"])
			scale01 = safeEval(attrs["scale01"])
			scale10 = safeEval(attrs["scale10"])
			scaley = safeEval(attrs["scaley"])
			self.transform = [[scalex, scale01], [scale10, scaley]]
		elif "scalex" in attrs:
			scalex = safeEval(attrs["scalex"])
			scaley = safeEval(attrs["scaley"])
			self.transform = [[scalex, 0], [0, scaley]]
		elif "scale" in attrs:
			scale = safeEval(attrs["scale"])
			self.transform = [[scale, 0], [0, scale]]
		self.flags = safeEval(attrs["flags"])

	def __eq__(self, other):
		if type(self) != type(other):
			return NotImplemented
		return self.__dict__ == other.__dict__

	def __ne__(self, other):
		result = self.__eq__(other)
		return result if result is NotImplemented else not result

class GlyphCoordinates(object):

	def __init__(self, iterable=[], typecode="h"):
		self._a = array.array(typecode)
		self.extend(iterable)

	@property
	def array(self):
		return self._a

	def isFloat(self):
		return self._a.typecode == 'd'

	def _ensureFloat(self):
		if self.isFloat():
			return
		# The conversion to list() is to work around Jython bug
		self._a = array.array("d", list(self._a))

	def _checkFloat(self, p):
		if self.isFloat():
			return p
		if any(v > 0x7FFF or v < -0x8000 for v in p):
			self._ensureFloat()
			return p
		if any(isinstance(v, float) for v in p):
			p = [int(v) if int(v) == v else v for v in p]
			if any(isinstance(v, float) for v in p):
				self._ensureFloat()
		return p

	@staticmethod
	def zeros(count):
		return GlyphCoordinates([(0,0)] * count)

	def copy(self):
		c = GlyphCoordinates(typecode=self._a.typecode)
		c._a.extend(self._a)
		return c

	def __len__(self):
		return len(self._a) // 2

	def __getitem__(self, k):
		if isinstance(k, slice):
			indices = range(*k.indices(len(self)))
			return [self[i] for i in indices]
		return self._a[2*k],self._a[2*k+1]

	def __setitem__(self, k, v):
		if isinstance(k, slice):
			indices = range(*k.indices(len(self)))
			# XXX This only works if len(v) == len(indices)
			for j,i in enumerate(indices):
				self[i] = v[j]
			return
		v = self._checkFloat(v)
		self._a[2*k],self._a[2*k+1] = v

	def __delitem__(self, i):
		i = (2*i) % len(self._a)
		del self._a[i]
		del self._a[i]

	def __repr__(self):
		return 'GlyphCoordinates(['+','.join(str(c) for c in self)+'])'

	def append(self, p):
		p = self._checkFloat(p)
		self._a.extend(tuple(p))

	def extend(self, iterable):
		for p in iterable:
			p = self._checkFloat(p)
			self._a.extend(p)

	def toInt(self):
		if not self.isFloat():
			return
		a = array.array("h")
		for n in self._a:
			a.append(otRound(n))
		self._a = a

	def relativeToAbsolute(self):
		a = self._a
		x,y = 0,0
		for i in range(len(a) // 2):
			x = a[2*i  ] + x
			y = a[2*i+1] + y
			self[i] = (x, y)

	def absoluteToRelative(self):
		a = self._a
		x,y = 0,0
		for i in range(len(a) // 2):
			dx = a[2*i  ] - x
			dy = a[2*i+1] - y
			x = a[2*i  ]
			y = a[2*i+1]
			self[i] = (dx, dy)

	def translate(self, p):
		"""
		>>> GlyphCoordinates([(1,2)]).translate((.5,0))
		"""
		(x,y) = self._checkFloat(p)
		a = self._a
		for i in range(len(a) // 2):
			self[i] = (a[2*i] + x, a[2*i+1] + y)

	def scale(self, p):
		"""
		>>> GlyphCoordinates([(1,2)]).scale((.5,0))
		"""
		(x,y) = self._checkFloat(p)
		a = self._a
		for i in range(len(a) // 2):
			self[i] = (a[2*i] * x, a[2*i+1] * y)

	def transform(self, t):
		"""
		>>> GlyphCoordinates([(1,2)]).transform(((.5,0),(.2,.5)))
		"""
		a = self._a
		for i in range(len(a) // 2):
			x = a[2*i  ]
			y = a[2*i+1]
			px = x * t[0][0] + y * t[1][0]
			py = x * t[0][1] + y * t[1][1]
			self[i] = (px, py)

	def __eq__(self, other):
		"""
		>>> g = GlyphCoordinates([(1,2)])
		>>> g2 = GlyphCoordinates([(1.0,2)])
		>>> g3 = GlyphCoordinates([(1.5,2)])
		>>> g == g2
		True
		>>> g == g3
		False
		>>> g2 == g3
		False
		"""
		if type(self) != type(other):
			return NotImplemented
		return self._a == other._a

	def __ne__(self, other):
		"""
		>>> g = GlyphCoordinates([(1,2)])
		>>> g2 = GlyphCoordinates([(1.0,2)])
		>>> g3 = GlyphCoordinates([(1.5,2)])
		>>> g != g2
		False
		>>> g != g3
		True
		>>> g2 != g3
		True
		"""
		result = self.__eq__(other)
		return result if result is NotImplemented else not result

	# Math operations

	def __pos__(self):
		"""
		>>> g = GlyphCoordinates([(1,2)])
		>>> g
		GlyphCoordinates([(1, 2)])
		>>> g2 = +g
		>>> g2
		GlyphCoordinates([(1, 2)])
		>>> g2.translate((1,0))
		>>> g2
		GlyphCoordinates([(2, 2)])
		>>> g
		GlyphCoordinates([(1, 2)])
		"""
		return self.copy()
	def __neg__(self):
		"""
		>>> g = GlyphCoordinates([(1,2)])
		>>> g
		GlyphCoordinates([(1, 2)])
		>>> g2 = -g
		>>> g2
		GlyphCoordinates([(-1, -2)])
		>>> g
		GlyphCoordinates([(1, 2)])
		"""
		r = self.copy()
		a = r._a
		for i in range(len(a)):
			a[i] = -a[i]
		return r
	def __round__(self):
		"""
		Note: This is Python 3 only.  Python 2 does not call __round__.
		As such, we cannot test this method either. :(
		"""
		r = self.copy()
		r.toInt()
		return r

	def __add__(self, other): return self.copy().__iadd__(other)
	def __sub__(self, other): return self.copy().__isub__(other)
	def __mul__(self, other): return self.copy().__imul__(other)
	def __truediv__(self, other): return self.copy().__itruediv__(other)

	__radd__ = __add__
	__rmul__ = __mul__
	def __rsub__(self, other): return other + (-self)

	def __iadd__(self, other):
		"""
		>>> g = GlyphCoordinates([(1,2)])
		>>> g += (.5,0)
		>>> g
		GlyphCoordinates([(1.5, 2.0)])
		>>> g2 = GlyphCoordinates([(3,4)])
		>>> g += g2
		>>> g
		GlyphCoordinates([(4.5, 6.0)])
		"""
		if isinstance(other, tuple):
			assert len(other) ==  2
			self.translate(other)
			return self
		if isinstance(other, GlyphCoordinates):
			if other.isFloat(): self._ensureFloat()
			other = other._a
			a = self._a
			assert len(a) == len(other)
			for i in range(len(a) // 2):
				self[i] = (a[2*i] + other[2*i], a[2*i+1] + other[2*i+1])
			return self
		return NotImplemented

	def __isub__(self, other):
		"""
		>>> g = GlyphCoordinates([(1,2)])
		>>> g -= (.5,0)
		>>> g
		GlyphCoordinates([(0.5, 2.0)])
		>>> g2 = GlyphCoordinates([(3,4)])
		>>> g -= g2
		>>> g
		GlyphCoordinates([(-2.5, -2.0)])
		"""
		if isinstance(other, tuple):
			assert len(other) ==  2
			self.translate((-other[0],-other[1]))
			return self
		if isinstance(other, GlyphCoordinates):
			if other.isFloat(): self._ensureFloat()
			other = other._a
			a = self._a
			assert len(a) == len(other)
			for i in range(len(a) // 2):
				self[i] = (a[2*i] - other[2*i], a[2*i+1] - other[2*i+1])
			return self
		return NotImplemented

	def __imul__(self, other):
		"""
		>>> g = GlyphCoordinates([(1,2)])
		>>> g *= (2,.5)
		>>> g *= 2
		>>> g
		GlyphCoordinates([(4.0, 2.0)])
		>>> g = GlyphCoordinates([(1,2)])
		>>> g *= 2
		>>> g
		GlyphCoordinates([(2, 4)])
		"""
		if isinstance(other, Number):
			other = (other, other)
		if isinstance(other, tuple):
			if other == (1,1):
				return self
			assert len(other) ==  2
			self.scale(other)
			return self
		return NotImplemented

	def __itruediv__(self, other):
		"""
		>>> g = GlyphCoordinates([(1,3)])
		>>> g /= (.5,1.5)
		>>> g /= 2
		>>> g
		GlyphCoordinates([(1.0, 1.0)])
		"""
		if isinstance(other, Number):
			other = (other, other)
		if isinstance(other, tuple):
			if other == (1,1):
				return self
			assert len(other) ==  2
			self.scale((1./other[0],1./other[1]))
			return self
		return NotImplemented

	def __bool__(self):
		"""
		>>> g = GlyphCoordinates([])
		>>> bool(g)
		False
		>>> g = GlyphCoordinates([(0,0), (0.,0)])
		>>> bool(g)
		True
		>>> g = GlyphCoordinates([(0,0), (1,0)])
		>>> bool(g)
		True
		>>> g = GlyphCoordinates([(0,.5), (0,0)])
		>>> bool(g)
		True
		"""
		return bool(self._a)

	__nonzero__ = __bool__


def reprflag(flag):
	bin = ""
	if isinstance(flag, str):
		flag = byteord(flag)
	while flag:
		if flag & 0x01:
			bin = "1" + bin
		else:
			bin = "0" + bin
		flag = flag >> 1
	bin = (14 - len(bin)) * "0" + bin
	return bin


if __name__ == "__main__":
	import doctest, sys
	sys.exit(doctest.testmod().failed)
