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