"""fontTools.pens.basePen.py -- Tools and base classes to build pen objects.

The Pen Protocol

A Pen is a kind of object that standardizes the way how to "draw" outlines:
it is a middle man between an outline and a drawing. In other words:
it is an abstraction for drawing outlines, making sure that outline objects
don't need to know the details about how and where they're being drawn, and
that drawings don't need to know the details of how outlines are stored.

The most basic pattern is this:

    outline.draw(pen)  # 'outline' draws itself onto 'pen'

Pens can be used to render outlines to the screen, but also to construct
new outlines. Eg. an outline object can be both a drawable object (it has a
draw() method) as well as a pen itself: you *build* an outline using pen
methods.

The AbstractPen class defines the Pen protocol. It implements almost
nothing (only no-op closePath() and endPath() methods), but is useful
for documentation purposes. Subclassing it basically tells the reader:
"this class implements the Pen protocol.". An examples of an AbstractPen
subclass is fontTools.pens.transformPen.TransformPen.

The BasePen class is a base implementation useful for pens that actually
draw (for example a pen renders outlines using a native graphics engine).
BasePen contains a lot of base functionality, making it very easy to build
a pen that fully conforms to the pen protocol. Note that if you subclass
BasePen, you _don't_ override moveTo(), lineTo(), etc., but _moveTo(),
_lineTo(), etc. See the BasePen doc string for details. Examples of
BasePen subclasses are fontTools.pens.boundsPen.BoundsPen and
fontTools.pens.cocoaPen.CocoaPen.

Coordinates are usually expressed as (x, y) tuples, but generally any
sequence of length 2 will do.
"""

from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *

__all__ = ["AbstractPen", "NullPen", "BasePen",
           "decomposeSuperBezierSegment", "decomposeQuadraticSegment"]


class AbstractPen(object):

	def moveTo(self, pt):
		"""Begin a new sub path, set the current point to 'pt'. You must
		end each sub path with a call to pen.closePath() or pen.endPath().
		"""
		raise NotImplementedError

	def lineTo(self, pt):
		"""Draw a straight line from the current point to 'pt'."""
		raise NotImplementedError

	def curveTo(self, *points):
		"""Draw a cubic bezier with an arbitrary number of control points.

		The last point specified is on-curve, all others are off-curve
		(control) points. If the number of control points is > 2, the
		segment is split into multiple bezier segments. This works
		like this:

		Let n be the number of control points (which is the number of
		arguments to this call minus 1). If n==2, a plain vanilla cubic
		bezier is drawn. If n==1, we fall back to a quadratic segment and
		if n==0 we draw a straight line. It gets interesting when n>2:
		n-1 PostScript-style cubic segments will be drawn as if it were
		one curve. See decomposeSuperBezierSegment().

		The conversion algorithm used for n>2 is inspired by NURB
		splines, and is conceptually equivalent to the TrueType "implied
		points" principle. See also decomposeQuadraticSegment().
		"""
		raise NotImplementedError

	def qCurveTo(self, *points):
		"""Draw a whole string of quadratic curve segments.

		The last point specified is on-curve, all others are off-curve
		points.

		This method implements TrueType-style curves, breaking up curves
		using 'implied points': between each two consequtive off-curve points,
		there is one implied point exactly in the middle between them. See
		also decomposeQuadraticSegment().

		The last argument (normally the on-curve point) may be None.
		This is to support contours that have NO on-curve points (a rarely
		seen feature of TrueType outlines).
		"""
		raise NotImplementedError

	def closePath(self):
		"""Close the current sub path. You must call either pen.closePath()
		or pen.endPath() after each sub path.
		"""
		pass

	def endPath(self):
		"""End the current sub path, but don't close it. You must call
		either pen.closePath() or pen.endPath() after each sub path.
		"""
		pass

	def addComponent(self, glyphName, transformation):
		"""Add a sub glyph. The 'transformation' argument must be a 6-tuple
		containing an affine transformation, or a Transform object from the
		fontTools.misc.transform module. More precisely: it should be a
		sequence containing 6 numbers.
		"""
		raise NotImplementedError


class NullPen(object):

	"""A pen that does nothing.
	"""

	def moveTo(self, pt):
		pass

	def lineTo(self, pt):
		pass

	def curveTo(self, *points):
		pass

	def qCurveTo(self, *points):
		pass

	def closePath(self):
		pass

	def endPath(self):
		pass

	def addComponent(self, glyphName, transformation):
		pass


class BasePen(AbstractPen):

	"""Base class for drawing pens. You must override _moveTo, _lineTo and
	_curveToOne. You may additionally override _closePath, _endPath,
	addComponent and/or _qCurveToOne. You should not override any other
	methods.
	"""

	def __init__(self, glyphSet):
		self.glyphSet = glyphSet
		self.__currentPoint = None

	# must override

	def _moveTo(self, pt):
		raise NotImplementedError

	def _lineTo(self, pt):
		raise NotImplementedError

	def _curveToOne(self, pt1, pt2, pt3):
		raise NotImplementedError

	# may override

	def _closePath(self):
		pass

	def _endPath(self):
		pass

	def _qCurveToOne(self, pt1, pt2):
		"""This method implements the basic quadratic curve type. The
		default implementation delegates the work to the cubic curve
		function. Optionally override with a native implementation.
		"""
		pt0x, pt0y = self.__currentPoint
		pt1x, pt1y = pt1
		pt2x, pt2y = pt2
		mid1x = pt0x + 0.66666666666666667 * (pt1x - pt0x)
		mid1y = pt0y + 0.66666666666666667 * (pt1y - pt0y)
		mid2x = pt2x + 0.66666666666666667 * (pt1x - pt2x)
		mid2y = pt2y + 0.66666666666666667 * (pt1y - pt2y)
		self._curveToOne((mid1x, mid1y), (mid2x, mid2y), pt2)

	def addComponent(self, glyphName, transformation):
		"""This default implementation simply transforms the points
		of the base glyph and draws it onto self.
		"""
		from fontTools.pens.transformPen import TransformPen
		try:
			glyph = self.glyphSet[glyphName]
		except KeyError:
			pass
		else:
			tPen = TransformPen(self, transformation)
			glyph.draw(tPen)

	# don't override

	def _getCurrentPoint(self):
		"""Return the current point. This is not part of the public
		interface, yet is useful for subclasses.
		"""
		return self.__currentPoint

	def closePath(self):
		self._closePath()
		self.__currentPoint = None

	def endPath(self):
		self._endPath()
		self.__currentPoint = None

	def moveTo(self, pt):
		self._moveTo(pt)
		self.__currentPoint = pt

	def lineTo(self, pt):
		self._lineTo(pt)
		self.__currentPoint = pt

	def curveTo(self, *points):
		n = len(points) - 1  # 'n' is the number of control points
		assert n >= 0
		if n == 2:
			# The common case, we have exactly two BCP's, so this is a standard
			# cubic bezier. Even though decomposeSuperBezierSegment() handles
			# this case just fine, we special-case it anyway since it's so
			# common.
			self._curveToOne(*points)
			self.__currentPoint = points[-1]
		elif n > 2:
			# n is the number of control points; split curve into n-1 cubic
			# bezier segments. The algorithm used here is inspired by NURB
			# splines and the TrueType "implied point" principle, and ensures
			# the smoothest possible connection between two curve segments,
			# with no disruption in the curvature. It is practical since it
			# allows one to construct multiple bezier segments with a much
			# smaller amount of points.
			_curveToOne = self._curveToOne
			for pt1, pt2, pt3 in decomposeSuperBezierSegment(points):
				_curveToOne(pt1, pt2, pt3)
				self.__currentPoint = pt3
		elif n == 1:
			self.qCurveTo(*points)
		elif n == 0:
			self.lineTo(points[0])
		else:
			raise AssertionError("can't get there from here")

	def qCurveTo(self, *points):
		n = len(points) - 1  # 'n' is the number of control points
		assert n >= 0
		if points[-1] is None:
			# Special case for TrueType quadratics: it is possible to
			# define a contour with NO on-curve points. BasePen supports
			# this by allowing the final argument (the expected on-curve
			# point) to be None. We simulate the feature by making the implied
			# on-curve point between the last and the first off-curve points
			# explicit.
			x, y = points[-2]  # last off-curve point
			nx, ny = points[0] # first off-curve point
			impliedStartPoint = (0.5 * (x + nx), 0.5 * (y + ny))
			self.__currentPoint = impliedStartPoint
			self._moveTo(impliedStartPoint)
			points = points[:-1] + (impliedStartPoint,)
		if n > 0:
			# Split the string of points into discrete quadratic curve
			# segments. Between any two consecutive off-curve points
			# there's an implied on-curve point exactly in the middle.
			# This is where the segment splits.
			_qCurveToOne = self._qCurveToOne
			for pt1, pt2 in decomposeQuadraticSegment(points):
				_qCurveToOne(pt1, pt2)
				self.__currentPoint = pt2
		else:
			self.lineTo(points[0])


def decomposeSuperBezierSegment(points):
	"""Split the SuperBezier described by 'points' into a list of regular
	bezier segments. The 'points' argument must be a sequence with length
	3 or greater, containing (x, y) coordinates. The last point is the
	destination on-curve point, the rest of the points are off-curve points.
	The start point should not be supplied.

	This function returns a list of (pt1, pt2, pt3) tuples, which each
	specify a regular curveto-style bezier segment.
	"""
	n = len(points) - 1
	assert n > 1
	bezierSegments = []
	pt1, pt2, pt3 = points[0], None, None
	for i in range(2, n+1):
		# calculate points in between control points.
		nDivisions = min(i, 3, n-i+2)
		for j in range(1, nDivisions):
			factor = j / nDivisions
			temp1 = points[i-1]
			temp2 = points[i-2]
			temp = (temp2[0] + factor * (temp1[0] - temp2[0]),
					temp2[1] + factor * (temp1[1] - temp2[1]))
			if pt2 is None:
				pt2 = temp
			else:
				pt3 = (0.5 * (pt2[0] + temp[0]),
					   0.5 * (pt2[1] + temp[1]))
				bezierSegments.append((pt1, pt2, pt3))
				pt1, pt2, pt3 = temp, None, None
	bezierSegments.append((pt1, points[-2], points[-1]))
	return bezierSegments


def decomposeQuadraticSegment(points):
	"""Split the quadratic curve segment described by 'points' into a list
	of "atomic" quadratic segments. The 'points' argument must be a sequence
	with length 2 or greater, containing (x, y) coordinates. The last point
	is the destination on-curve point, the rest of the points are off-curve
	points. The start point should not be supplied.

	This function returns a list of (pt1, pt2) tuples, which each specify a
	plain quadratic bezier segment.
	"""
	n = len(points) - 1
	assert n > 0
	quadSegments = []
	for i in range(n - 1):
		x, y = points[i]
		nx, ny = points[i+1]
		impliedPt = (0.5 * (x + nx), 0.5 * (y + ny))
		quadSegments.append((points[i], impliedPt))
	quadSegments.append((points[-2], points[-1]))
	return quadSegments


class _TestPen(BasePen):
	"""Test class that prints PostScript to stdout."""
	def _moveTo(self, pt):
		print("%s %s moveto" % (pt[0], pt[1]))
	def _lineTo(self, pt):
		print("%s %s lineto" % (pt[0], pt[1]))
	def _curveToOne(self, bcp1, bcp2, pt):
		print("%s %s %s %s %s %s curveto" % (bcp1[0], bcp1[1],
				bcp2[0], bcp2[1], pt[0], pt[1]))
	def _closePath(self):
		print("closepath")


if __name__ == "__main__":
	pen = _TestPen(None)
	pen.moveTo((0, 0))
	pen.lineTo((0, 100))
	pen.curveTo((50, 75), (60, 50), (50, 25), (0, 0))
	pen.closePath()

	pen = _TestPen(None)
	# testing the "no on-curve point" scenario
	pen.qCurveTo((0, 0), (0, 100), (100, 100), (100, 0), None)
	pen.closePath()
