# Source code for fontTools.pens.statisticsPen

    """Pen calculating area, center of mass, variance and standard-deviation,
    covariance and correlation, and slant, of glyph shapes."""
    import math
    from fontTools.pens.momentsPen import MomentsPen

    __all__ = ["StatisticsPen"]

    class StatisticsPen(MomentsPen):

    	"""Pen calculating area, center of mass, variance and
    	standard-deviation, covariance and correlation, and slant,
    	of glyph shapes.

    	Note that all the calculated values are 'signed'. Ie. if the
    	glyph shape is self-intersecting, the values are not correct
    	(but well-defined). As such, area will be negative if contour
    	directions are clockwise.  Moreover, variance might be negative
    	if the shapes are self-intersecting in certain ways."""

    	def __init__(self, glyphset=None):
    		MomentsPen.__init__(self, glyphset=glyphset)
    		self.__zero()

    	def _closePath(self):
    		MomentsPen._closePath(self)
    		self.__update()

    	def __zero(self):
    		self.meanX = 0
    		self.meanY = 0
    		self.varianceX = 0
    		self.varianceY = 0
    		self.stddevX = 0
    		self.stddevY = 0
    		self.covariance = 0
    		self.correlation = 0
    		self.slant = 0

    	def __update(self):

    		area = self.area
    		if not area:
    			self.__zero()
    			return

    		# Center of mass
    		# https://en.wikipedia.org/wiki/Center_of_mass#A_continuous_volume
    		self.meanX = meanX = self.momentX / area
    		self.meanY = meanY = self.momentY / area

    		#  Var(X) = E[X^2] - E[X]^2
    		self.varianceX = varianceX = self.momentXX / area - meanX**2
    		self.varianceY = varianceY = self.momentYY / area - meanY**2

    		self.stddevX = stddevX = math.copysign(abs(varianceX)**.5, varianceX)
    		self.stddevY = stddevY = math.copysign(abs(varianceY)**.5, varianceY)

    		#  Covariance(X,Y) = ( E[X.Y] - E[X]E[Y] )
    		self.covariance = covariance = self.momentXY / area - meanX*meanY

    		#  Correlation(X,Y) = Covariance(X,Y) / ( stddev(X) * stddev(Y) )
    		# https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient
    		if stddevX * stddevY == 0:
    			correlation = float("NaN")
    		else:
    			correlation = covariance / (stddevX * stddevY)
    		self.correlation = correlation if abs(correlation) > 1e-3 else 0

    		slant = covariance / varianceY if varianceY != 0 else float("NaN")
    		self.slant = slant if abs(slant) > 1e-3 else 0

    def _test(glyphset, upem, glyphs):
    	from fontTools.pens.transformPen import TransformPen
    	from fontTools.misc.transform import Scale

    	print('upem', upem)

    	for glyph_name in glyphs:
    		print()
    		print("glyph:", glyph_name)
    		glyph = glyphset[glyph_name]
    		pen = StatisticsPen(glyphset=glyphset)
    		transformer = TransformPen(pen, Scale(1./upem))
    		glyph.draw(transformer)
    		for item in ['area', 'momentX', 'momentY', 'momentXX', 'momentYY', 'momentXY', 'meanX', 'meanY', 'varianceX', 'varianceY', 'stddevX', 'stddevY', 'covariance', 'correlation', 'slant']:
    			print ("%s: %g" % (item, getattr(pen, item)))

    def main(args):
    	if not args:
    		return
    	filename, glyphs = args[0], args[1:]
    	from fontTools.ttLib import TTFont
    	font = TTFont(filename)
    	if not glyphs:
    		glyphs = font.getGlyphOrder()
    	_test(font.getGlyphSet(), font['head'].unitsPerEm, glyphs)

    if __name__ == '__main__':
    	import sys
    	main(sys.argv[1:])