• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Calculate the area of a glyph."""
2
3from __future__ import print_function, division, absolute_import
4from fontTools.misc.py23 import *
5from fontTools.pens.basePen import BasePen
6
7
8__all__ = ["AreaPen"]
9
10
11class AreaPen(BasePen):
12
13	def __init__(self, glyphset=None):
14		BasePen.__init__(self, glyphset)
15		self.value = 0
16
17	def _moveTo(self, p0):
18		self._p0 = self._startPoint = p0
19
20	def _lineTo(self, p1):
21		x0, y0 = self._p0
22		x1, y1 = p1
23		self.value -= (x1 - x0) * (y1 + y0) * .5
24		self._p0 = p1
25
26	def _qCurveToOne(self, p1, p2):
27		# https://github.com/Pomax/bezierinfo/issues/44
28		p0 = self._p0
29		x0, y0 = p0[0], p0[1]
30		x1, y1 = p1[0] - x0, p1[1] - y0
31		x2, y2 = p2[0] - x0, p2[1] - y0
32		self.value -= (x2 * y1 - x1 * y2) / 3
33		self._lineTo(p2)
34		self._p0 = p2
35
36	def _curveToOne(self, p1, p2, p3):
37		# https://github.com/Pomax/bezierinfo/issues/44
38		p0 = self._p0
39		x0, y0 = p0[0], p0[1]
40		x1, y1 = p1[0] - x0, p1[1] - y0
41		x2, y2 = p2[0] - x0, p2[1] - y0
42		x3, y3 = p3[0] - x0, p3[1] - y0
43		self.value -= (
44				x1 * (   -   y2 -   y3) +
45				x2 * (y1        - 2*y3) +
46				x3 * (y1 + 2*y2       )
47			      ) * 0.15
48		self._lineTo(p3)
49		self._p0 = p3
50
51	def _closePath(self):
52		self._lineTo(self._startPoint)
53		del self._p0, self._startPoint
54
55	def _endPath(self):
56		if self._p0 != self._startPoint:
57			# Area is not defined for open contours.
58			raise NotImplementedError
59		del self._p0, self._startPoint
60