-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Embedded domain-specific language for declarative graphics
--   
--   Diagrams is a flexible, extensible EDSL for creating graphics of many
--   types. Graphics can be created in arbitrary vector spaces and rendered
--   with multiple backends. diagrams-lib provides a standard library of
--   primitives and operations for creating diagrams. To get started using
--   it, see <a>Diagrams.Prelude</a>.
@package diagrams-lib
@version 1.2.0.3


-- | Diagrams may have <i>attributes</i> which affect the way they are
--   rendered. This module defines some common attributes relevant in 3D;
--   particular backends may also define more backend-specific attributes.
--   
--   Every attribute type must have a <i>semigroup</i> structure, that is,
--   an associative binary operation for combining two attributes into one.
--   Unless otherwise noted, all the attributes defined here use the
--   <a>Last</a> structure, that is, combining two attributes simply keeps
--   the second one and throws away the first. This means that child
--   attributes always override parent attributes.
module Diagrams.ThreeD.Attributes

-- | <tt>SurfaceColor</tt> is the inherent pigment of an object, assumed to
--   be opaque.
newtype SurfaceColor
SurfaceColor :: (Last (Colour Double)) -> SurfaceColor
surfaceColor :: Iso' SurfaceColor (Colour Double)

-- | Set the surface color.
sc :: HasStyle d => Colour Double -> d -> d

-- | <tt>Diffuse</tt> is the fraction of incident light reflected
--   diffusely, that is, in all directions. The actual light reflected is
--   the product of this value, the incident light, and the
--   <tt>SurfaceColor</tt> Attribute. For physical reasonableness,
--   <tt>Diffuse</tt> should have a value between 0 and 1; this is not
--   checked.
newtype Diffuse
Diffuse :: (Last Double) -> Diffuse
_Diffuse :: Iso' Diffuse Double

-- | Set the diffuse reflectance.
diffuse :: HasStyle d => Double -> d -> d

-- | <tt>Ambient</tt> is an ad-hoc representation of indirect lighting. The
--   product of <tt>Ambient</tt> and <tt>SurfaceColor</tt> is added to the
--   light leaving an object due to diffuse and specular terms.
--   <tt>Ambient</tt> can be set per-object, and can be loosely thought of
--   as the product of indirect lighting incident on that object and the
--   diffuse reflectance.
newtype Ambient
Ambient :: (Last Double) -> Ambient
_Ambient :: Iso' Ambient Double

-- | Set the emittance due to ambient light.
ambient :: HasStyle d => Double -> d -> d

-- | A specular highlight has two terms, the intensity, between 0 and 1,
--   and the size. The highlight size is assumed to be the exponent in a
--   Phong shading model (though Backends are free to use a different
--   shading model). In this model, reasonable values are between 1 and 50
--   or so, with higher values for shinier objects. Physically, the
--   intensity and the value of <tt>Diffuse</tt> must add up to less than
--   1; this is not enforced.
data Specular
Specular :: Double -> Double -> Specular
_specularIntensity :: Specular -> Double
_specularSize :: Specular -> Double
specularSize :: Lens' Specular Double
specularIntensity :: Lens' Specular Double
newtype Highlight
Highlight :: (Last Specular) -> Highlight
_Highlight :: Iso' Highlight Specular

-- | Set the specular highlight.
highlight :: HasStyle d => Specular -> d -> d
instance Typeable Highlight
instance Semigroup Highlight
instance AttributeClass Highlight
instance Typeable SurfaceColor
instance Typeable Diffuse
instance Typeable Ambient
instance Semigroup SurfaceColor
instance Semigroup Diffuse
instance Semigroup Ambient
instance AttributeClass Ambient
instance AttributeClass Diffuse
instance AttributeClass SurfaceColor


-- | Bounding boxes are not very compositional (<i>e.g.</i> it is not
--   possible to do anything sensible with them under rotation), so they
--   are not used in the diagrams core. However, they do have their uses;
--   this module provides definitions and functions for working with them.
module Diagrams.BoundingBox

-- | A bounding box is an axis-aligned region determined by two points
--   indicating its "lower" and "upper" corners. It can also represent an
--   empty bounding box - the points are wrapped in <tt>Maybe</tt>.
data BoundingBox v

-- | An empty bounding box. This is the same thing as <tt>mempty</tt>, but
--   it doesn't require the same type constraints that the <tt>Monoid</tt>
emptyBox :: BoundingBox v

-- | Create a bounding box from a point that is component-wise
--   <tt>(&lt;=)</tt> than the other. If this is not the case, then
--   <tt>mempty</tt> is returned.
fromCorners :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => Point v -> Point v -> BoundingBox v

-- | Create a degenerate bounding "box" containing only a single point.
fromPoint :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => Point v -> BoundingBox v

-- | Create the smallest bounding box containing all the given points.
fromPoints :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => [Point v] -> BoundingBox v

-- | Create a bounding box for any enveloped object (such as a diagram or
--   path).
boundingBox :: (Enveloped a, HasBasis (V a), AdditiveGroup (V a), Ord (Basis (V a))) => a -> BoundingBox (V a)

-- | Queries whether the BoundingBox is empty.
isEmptyBox :: BoundingBox v -> Bool

-- | Gets the lower and upper corners that define the bounding box.
getCorners :: BoundingBox v -> Maybe (Point v, Point v)

-- | Computes all of the corners of the bounding box.
getAllCorners :: (HasBasis v, AdditiveGroup (Scalar v), Ord (Basis v)) => BoundingBox v -> [Point v]

-- | Get the size of the bounding box - the vector from the
--   (component-wise) lesser point to the greater point.
boxExtents :: AdditiveGroup v => BoundingBox v -> v

-- | Create a transformation mapping points from one bounding box to the
--   other.
boxTransform :: (AdditiveGroup v, HasLinearMap v, Fractional (Scalar v), AdditiveGroup (Scalar v), Ord (Basis v)) => BoundingBox v -> BoundingBox v -> Maybe (Transformation v)

-- | Transforms an enveloped thing to fit within a <tt>BoundingBox</tt>. If
--   it's empty, then the result is also <tt>mempty</tt>.
boxFit :: (Enveloped a, Transformable a, Monoid a, Ord (Basis (V a))) => BoundingBox (V a) -> a -> a

-- | Check whether a point is contained in a bounding box (including its
--   edges).
contains :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> Point v -> Bool

-- | Check whether a point is <i>strictly</i> contained in a bounding box.
contains' :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> Point v -> Bool

-- | Test whether the first bounding box is contained inside the second.
inside :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> BoundingBox v -> Bool

-- | Test whether the first bounding box is <i>strictly</i> contained
--   inside the second.
inside' :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> BoundingBox v -> Bool

-- | Test whether the first bounding box lies outside the second (although
--   they may intersect in their boundaries).
outside :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> BoundingBox v -> Bool

-- | Test whether the first bounding box lies <i>strictly</i> outside the
--   second (they do not intersect at all).
outside' :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> BoundingBox v -> Bool

-- | Form the smallest bounding box containing the given two bound union.
--   This function is just an alias for <tt>mappend</tt>.
union :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> BoundingBox v -> BoundingBox v

-- | Form the largest bounding box contained within this given two bounding
--   boxes, or <tt>Nothing</tt> if the two bounding boxes do not overlap at
--   all.
intersection :: (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => BoundingBox v -> BoundingBox v -> BoundingBox v
instance Typeable1 NonEmptyBoundingBox
instance Typeable1 BoundingBox
instance (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => Monoid (BoundingBox v)
instance (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => Semigroup (BoundingBox v)
instance Eq v => Eq (NonEmptyBoundingBox v)
instance Data v => Data (NonEmptyBoundingBox v)
instance Eq v => Eq (BoundingBox v)
instance Data v => Data (BoundingBox v)
instance Show v => Show (BoundingBox v)
instance (InnerSpace v, HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v), Floating (Scalar v)) => Enveloped (BoundingBox v)
instance (VectorSpace v, HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => HasOrigin (BoundingBox v)
instance (HasBasis v, Ord (Basis v), AdditiveGroup (Scalar v), Ord (Scalar v)) => Semigroup (NonEmptyBoundingBox v)


-- | A <i>cubic spline</i> is a smooth, connected sequence of cubic curves
--   passing through a given sequence of points. This module implements a
--   straightforward spline generation algorithm based on solving
--   tridiagonal systems of linear equations.
module Diagrams.CubicSpline.Internal

-- | Solves a system of the form 'A*X=D' for <tt>x</tt> where <tt>A</tt> is
--   an <tt>n</tt> by <tt>n</tt> matrix with <tt>bs</tt> as the main
--   diagonal and <tt>as</tt> the diagonal below and <tt>cs</tt> the
--   diagonal above. See:
--   <a>http://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm</a>
solveTriDiagonal :: Fractional a => [a] -> [a] -> [a] -> [a] -> [a]

-- | Solves a system similar to the tri-diagonal system using a special
--   case of the Sherman-Morrison formula
--   <a>http://en.wikipedia.org/wiki/Sherman-Morrison_formula</a>. This
--   code is based on <i>Numerical Recpies in C</i>'s <tt>cyclic</tt>
--   function in section 2.7.
solveCyclicTriDiagonal :: Fractional a => [a] -> [a] -> [a] -> [a] -> a -> a -> [a]

-- | Use the tri-diagonal solver with the appropriate parameters for an
--   open cubic spline.
solveCubicSplineDerivatives :: Fractional a => [a] -> [a]

-- | Use the cyclic-tri-diagonal solver with the appropriate parameters for
--   a closed cubic spline.
solveCubicSplineDerivativesClosed :: Fractional a => [a] -> [a]

-- | Use the cyclic-tri-diagonal solver with the appropriate parameters for
--   a closed cubic spline.
solveCubicSplineCoefficients :: Fractional a => Bool -> [a] -> [[a]]


-- | XXX
module Diagrams.Attributes.Compile
class (AttributeClass (AttrType code), Typeable (PrimType code)) => SplitAttribute code where type family AttrType code :: * type family PrimType code :: *
primOK :: SplitAttribute code => code -> PrimType code -> Bool

-- | Push certain attributes down until they are at the roots of trees
--   containing only <a>safe</a> nodes. In particular this is used to push
--   fill attributes down until they are over only loops; see
--   <tt>splitFills</tt>.
splitAttr :: SplitAttribute code => code -> RTree b v a -> RTree b v a


-- | Some miscellaneous utilities provided by the diagrams-lib package.
module Diagrams.Util

-- | Several functions exported by the diagrams library take a number of
--   arguments giving the user control to "tweak" various aspects of their
--   behavior. Rather than give such functions a long list of arguments,
--   and to make it possible for the user to selectively override only
--   certain arguments and use default values for others, such sets of
--   arguments are collected into a record with named fields (see
--   <tt>PolygonOpts</tt> in <a>Diagrams.TwoD.Shapes</a> for an example).
--   Such record types are made instances of the <a>Default</a> class,
--   which provides a single record structure (<a>def</a>) collecting the
--   "default" arguments to the function. <tt>with</tt> is a synonym for
--   <a>def</a>, which provides nice-looking syntax for simulating
--   optional, named arguments in Haskell. For example,
--   
--   <pre>
--   polygon with {sides = 7, edgeSkip = 2}
--   </pre>
--   
--   calls the <tt>polygon</tt> function with a single argument (note that
--   record update binds more tightly than function application!), namely,
--   <a>with</a> (the record of default arguments) where the <tt>sides</tt>
--   and <tt>edgeSkip</tt> fields have been updated.
with :: Default d => d

-- | <tt>applyAll</tt> takes a list of functions and applies them all to a
--   value, in sequence from the last function in the list to the first.
--   For example, <tt>applyAll [f1, f2, f3] a == f1 . f2 . f3 $ a</tt>.
applyAll :: [a -> a] -> a -> a

-- | Postfix function application, for conveniently applying attributes.
--   Unlike <tt>($)</tt>, <tt>(#)</tt> has a high precedence (8), so <tt>d
--   # foo # bar</tt> can be combined with other things using operators
--   like <tt>(|||)</tt> or <tt>(&lt;&gt;)</tt> without needing
--   parentheses.
(#) :: a -> (a -> b) -> b

-- | <tt>iterateN n f x</tt> returns the list of the first <tt>n</tt>
--   iterates of <tt>f</tt> starting at <tt>x</tt>, that is, the list
--   <tt>[x, f x, f (f x), ...]</tt> of length <tt>n</tt>. (Note that the
--   last element of the list will be <tt>f</tt> applied to <tt>x</tt>
--   <tt>(n-1)</tt> times.)
iterateN :: Int -> (a -> a) -> a -> [a]

-- | The circle constant, the ratio of a circle's circumference to its
--   <i>radius</i>. Note that <tt>pi = tau/2</tt>.
--   
--   For more information and a well-reasoned argument why we should all be
--   using tau instead of pi, see <i>The Tau Manifesto</i>,
--   <a>http://tauday.com/</a>.
--   
--   To hear what it sounds like (and to easily memorize the first 30
--   digits or so), try <a>http://youtu.be/3174T-3-59Q</a>.
tau :: Floating a => a

-- | Given an associative binary operation and a default value to use in
--   the case of an empty list, perform a <i>balanced</i> fold over a list.
--   For example,
--   
--   <pre>
--   foldB (+) z [a,b,c,d,e,f] == ((a+b) + (c+d)) + (e+f)
--   </pre>
foldB :: (a -> a -> a) -> a -> [a] -> a


-- | Exact solving of low-degree (n &lt;= 4) polynomials.
module Diagrams.Solve

-- | The quadratic formula.
quadForm :: (Floating d, Ord d) => d -> d -> d -> [d]

-- | Solve the cubic equation ax^3 + bx^2 + cx + d = 0, returning a list of
--   all real roots within 1e-10 tolerance (although currently it's closer
--   to 1e-5)
cubForm :: (Floating d, Ord d) => d -> d -> d -> d -> [d]

-- | Solve the quartic equation c4 x^4 + c3 x^3 + c2 x^2 + c1 x + c0 = 0,
--   returning a list of all real roots within 1e-10 tolerance (although
--   currently it's closer to 1e-5)
quartForm :: (Floating d, Ord d) => d -> d -> d -> d -> d -> [d]

-- | Solve the cubic equation ax^3 + bx^2 + cx + d = 0, returning a list of
--   all real roots. First argument is tolerance.
cubForm' :: (Floating d, Ord d) => d -> d -> d -> d -> d -> [d]

-- | Solve the quartic equation c4 x^4 + c3 x^3 + c2 x^2 + c1 x + c0 = 0,
--   returning a list of all real roots. First argument is tolerance.
quartForm' :: (Floating d, Ord d) => d -> d -> d -> d -> d -> d -> [d]


-- | Nice syntax for constructing and pattern-matching on literal points
--   and vectors.
module Diagrams.Coordinates

-- | A pair of values, with a convenient infix (left-associative) data
--   constructor.
data (:&) a b
(:&) :: a -> b -> :& a b

-- | Types which are instances of the <tt>Coordinates</tt> class can be
--   constructed using <a>^&amp;</a> (for example, a three-dimensional
--   vector could be constructed by <tt>1 ^&amp; 6 ^&amp; 3</tt>), and
--   deconstructed using <a>coords</a>. A common pattern is to use
--   <a>coords</a> in conjunction with the <tt>ViewPatterns</tt> extension,
--   like so:
--   
--   <pre>
--   foo :: Vector3 -&gt; ...
--   foo (coords -&gt; x :&amp; y :&amp; z) = ...
--   </pre>
class Coordinates c where type family FinalCoord c :: * type family PrevDim c :: * type family Decomposition c :: * pr = (^&)
(^&) :: Coordinates c => PrevDim c -> FinalCoord c -> c
pr :: Coordinates c => PrevDim c -> FinalCoord c -> c
coords :: Coordinates c => c -> Decomposition c

-- | The class of types with at least one coordinate, called _x.
class HasX t
_x :: HasX t => Lens' t Double

-- | The class of types with at least two coordinates, the second called
--   _y.
class HasY t
_y :: HasY t => Lens' t Double

-- | The class of types with at least three coordinates, the third called
--   _z.
class HasZ t
_z :: HasZ t => Lens' t Double

-- | The class of types with a single length coordinate _r. _r is magnitude
--   of a vector, or the distance from the origin of a point.
class HasR t
_r :: HasR t => Lens' t Double
instance (Eq a, Eq b) => Eq (a :& b)
instance (Ord a, Ord b) => Ord (a :& b)
instance (Show a, Show b) => Show (a :& b)
instance Coordinates v => Coordinates (Point v)
instance Coordinates (a, b, c, d)
instance Coordinates (a, b, c)
instance Coordinates (a, b)


-- | Type for representing angles, independent of vector-space
module Diagrams.Angle

-- | Angles can be expressed in a variety of units. Internally, they are
--   represented in radians.
data Angle

-- | The radian measure of an <tt>Angle</tt> <tt>a</tt> can be accessed as
--   <tt>a ^. rad</tt>. A new <tt>Angle</tt> can be defined in radians as
--   <tt>pi @@ rad</tt>.
rad :: Iso' Angle Double

-- | The measure of an <tt>Angle</tt> <tt>a</tt> in full circles can be
--   accessed as <tt>a ^. turn</tt>. A new <tt>Angle</tt> of one-half
--   circle can be defined in as <tt>1/2 @@ turn</tt>.
turn :: Iso' Angle Double

-- | The degree measure of an <tt>Angle</tt> <tt>a</tt> can be accessed as
--   <tt>a ^. deg</tt>. A new <tt>Angle</tt> can be defined in degrees as
--   <tt>180 @@ deg</tt>.
deg :: Iso' Angle Double

-- | An angle representing one full turn.
fullTurn :: Angle

-- | Deprecated synonym for <a>fullTurn</a>, retained for backwards
--   compatibility.
fullCircle :: Angle

-- | Calculate ratio between two angles.
angleRatio :: Angle -> Angle -> Double

-- | The sine of the given <tt>Angle</tt>.
sinA :: Angle -> Double

-- | The cosine of the given <tt>Angle</tt>.
cosA :: Angle -> Double

-- | The tangent function of the given <tt>Angle</tt>.
tanA :: Angle -> Double

-- | The <tt>Angle</tt> with the given sine.
asinA :: Double -> Angle

-- | The <tt>Angle</tt> with the given cosine.
acosA :: Double -> Angle

-- | The <tt>Angle</tt> with the given tangent.
atanA :: Double -> Angle

-- | <tt>30 @@ deg</tt> is an <tt>Angle</tt> of the given measure and
--   units.
--   
--   More generally, <tt>@@</tt> reverses the <tt>Iso'</tt> on its right,
--   and applies the <tt>Iso'</tt> to the value on the left.
--   <tt>Angle</tt>s are the motivating example where this order improves
--   readability.
(@@) :: b -> Iso' a b -> a

-- | compute the positive angle between the two vectors in their common
--   plane
angleBetween :: (InnerSpace v, Scalar v ~ Double) => v -> v -> Angle

-- | The class of types with at least one angle coordinate, called _theta.
class HasTheta t
_theta :: HasTheta t => Lens' t Angle
instance Read Angle
instance Show Angle
instance Eq Angle
instance Ord Angle
instance Enum Angle
instance AdditiveGroup Angle
instance VectorSpace Angle


-- | Basic types for two-dimensional Euclidean space.
module Diagrams.TwoD.Types

-- | The two-dimensional Euclidean vector space R^2. This type is
--   intentionally abstract.
--   
--   <ul>
--   <li>To construct a vector, use <a>r2</a>, or <a>^&amp;</a> (from
--   <a>Diagrams.Coordinates</a>):</li>
--   </ul>
--   
--   <pre>
--   r2 (3,4) :: R2
--   3 ^&amp; 4    :: R2
--   </pre>
--   
--   Note that <a>Diagrams.Coordinates</a> is not re-exported by
--   <a>Diagrams.Prelude</a> and must be explicitly imported.
--   
--   <ul>
--   <li>To construct the vector from the origin to a point <tt>p</tt>, use
--   <tt>p <a>.-.</a> <a>origin</a></tt>.</li>
--   <li>To convert a vector <tt>v</tt> into the point obtained by
--   following <tt>v</tt> from the origin, use <tt><a>origin</a> <a>.+^</a>
--   v</tt>.</li>
--   <li>To convert a vector back into a pair of components, use
--   <tt>unv2</tt> or <a>coords</a> (from <a>Diagrams.Coordinates</a>).
--   These are typically used in conjunction with the <tt>ViewPatterns</tt>
--   extension:</li>
--   </ul>
--   
--   <pre>
--   foo (unr2 -&gt; (x,y)) = ...
--   foo (coords -&gt; x :&amp; y) = ...
--   </pre>
data R2
R2 :: {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> R2

-- | Construct a 2D vector from a pair of components. See also
--   <tt>&amp;</tt>.
r2 :: (Double, Double) -> R2

-- | Convert a 2D vector back into a pair of components. See also
--   <a>coords</a>.
unr2 :: R2 -> (Double, Double)

-- | Curried form of <a>r2</a>.
mkR2 :: Double -> Double -> R2
r2Iso :: Iso' R2 (Double, Double)

-- | Points in R^2. This type is intentionally abstract.
--   
--   <ul>
--   <li>To construct a point, use <a>p2</a>, or <a>^&amp;</a> (see
--   <a>Diagrams.Coordinates</a>):</li>
--   </ul>
--   
--   <pre>
--   p2 (3,4)  :: P2
--   3 ^&amp; 4    :: P2
--   </pre>
--   
--   <ul>
--   <li>To construct a point from a vector <tt>v</tt>, use
--   <tt><a>origin</a> <a>.+^</a> v</tt>.</li>
--   <li>To convert a point <tt>p</tt> into the vector from the origin to
--   <tt>p</tt>, use <tt>p <a>.-.</a> <a>origin</a></tt>.</li>
--   <li>To convert a point back into a pair of coordinates, use
--   <a>unp2</a>, or <a>coords</a> (from <a>Diagrams.Coordinates</a>). It's
--   common to use these in conjunction with the <tt>ViewPatterns</tt>
--   extension:</li>
--   </ul>
--   
--   <pre>
--   foo (unp2 -&gt; (x,y)) = ...
--   foo (coords -&gt; x :&amp; y) = ...
--   </pre>
type P2 = Point R2

-- | Construct a 2D point from a pair of coordinates. See also
--   <a>^&amp;</a>.
p2 :: (Double, Double) -> P2

-- | Curried form of <a>p2</a>.
mkP2 :: Double -> Double -> P2

-- | Convert a 2D point back into a pair of coordinates. See also
--   <a>coords</a>.
unp2 :: P2 -> (Double, Double)
p2Iso :: Iso' P2 (Double, Double)

-- | Transformations in R^2.
type T2 = Transformation R2
instance Typeable R2
instance Eq R2
instance Ord R2
instance Data R2
instance Eq R2Basis
instance Ord R2Basis
instance Enum R2Basis
instance HasTheta P2
instance HasR P2
instance HasY P2
instance HasX P2
instance Transformable R2
instance HasR R2
instance HasTheta R2
instance HasY R2
instance HasX R2
instance Coordinates R2
instance InnerSpace R2
instance HasBasis R2
instance HasTrie R2Basis
instance VectorSpace R2
instance Rewrapped R2 R2
instance Wrapped R2
instance Read R2
instance Show R2
instance Fractional R2
instance Num R2
instance AdditiveGroup R2


-- | Two-dimensional vectors.
module Diagrams.TwoD.Vector

-- | The unit vector in the positive X direction.
unitX :: R2

-- | The unit vector in the positive Y direction.
unitY :: R2

-- | The unit vector in the negative X direction.
unit_X :: R2

-- | The unit vector in the negative Y direction.
unit_Y :: R2

-- | Compute the direction of a vector, measured counterclockwise from the
--   positive x-axis as a fraction of a full turn. The zero vector is
--   arbitrarily assigned the direction 0.
direction :: R2 -> Angle

-- | compute the positive angle between the two vectors in their common
--   plane
angleBetween :: (InnerSpace v, Scalar v ~ Double) => v -> v -> Angle

-- | Convert an angle into a unit vector pointing in that direction.
fromDirection :: Angle -> R2

-- | A convenient synonym for <a>fromDirection</a>.
e :: Angle -> R2

-- | <tt>perp v</tt> is perpendicular to and has the same magnitude as
--   <tt>v</tt>. In particular <tt>perp v == rotateBy (1/4) v</tt>.
perp :: R2 -> R2

-- | <tt>leftTurn v1 v2</tt> tests whether the direction of <tt>v2</tt> is
--   a left turn from <tt>v1</tt> (that is, if the direction of <tt>v2</tt>
--   can be obtained from that of <tt>v1</tt> by adding an angle 0 &lt;=
--   theta &lt;= tau/2).
leftTurn :: R2 -> R2 -> Bool


-- | Utilities for working with sizes of two-dimensional objects.
module Diagrams.TwoD.Size

-- | Compute the width of an enveloped object.
width :: (Enveloped a, V a ~ R2) => a -> Double

-- | Compute the height of an enveloped object.
height :: (Enveloped a, V a ~ R2) => a -> Double

-- | Compute the width and height of an enveloped object.
size2D :: (Enveloped a, V a ~ R2) => a -> (Double, Double)

-- | Compute the size of an enveloped object as a <a>SizeSpec2D</a> value.
sizeSpec2D :: (Enveloped a, V a ~ R2) => a -> SizeSpec2D

-- | Compute the absolute x-coordinate range of an enveloped object in R2,
--   in the form (lo,hi). Return <tt>Nothing</tt> for objects with an empty
--   envelope.
extentX :: (Enveloped a, V a ~ R2) => a -> Maybe (Double, Double)

-- | Compute the absolute y-coordinate range of an enveloped object in R2,
--   in the form (lo,hi).
extentY :: (Enveloped a, V a ~ R2) => a -> Maybe (Double, Double)

-- | Compute the point at the center (in the x- and y-directions) of a
--   enveloped object. Return the origin for objects with an empty
--   envelope.
center2D :: (Enveloped a, V a ~ R2) => a -> P2

-- | A specification of a (requested) rectangular size.
data SizeSpec2D

-- | Specify an explicit width. The height should be determined
--   automatically (so as to preserve aspect ratio).
Width :: !Double -> SizeSpec2D

-- | Specify an explicit height. The width should be determined
--   automatically (so as to preserve aspect ratio).
Height :: !Double -> SizeSpec2D

-- | An explicit specification of a width and height.
Dims :: !Double -> !Double -> SizeSpec2D

-- | Absolute size: use whatever size an object already has; do not
--   rescale.
Absolute :: SizeSpec2D

-- | Create a size specification from a possibly-specified width and
--   height.
mkSizeSpec :: Maybe Double -> Maybe Double -> SizeSpec2D

-- | <tt>requiredScaleT spec sz</tt> returns a transformation (a uniform
--   scale) which can be applied to something of size <tt>sz</tt> to make
--   it fit the requested size <tt>spec</tt>, without changing the aspect
--   ratio.
requiredScaleT :: SizeSpec2D -> (Double, Double) -> Transformation R2

-- | <tt>requiredScale spec sz</tt> returns a scaling factor necessary to
--   make something of size <tt>sz</tt> fit the requested size
--   <tt>spec</tt>, without changing the aspect ratio. Hence an explicit
--   specification of both dimensions may not be honored if the aspect
--   ratios do not match; in that case the scaling will be as large as
--   possible so that the object still fits within the requested size.
requiredScale :: SizeSpec2D -> (Double, Double) -> Double

-- | Uniformly scale any enveloped object so that it fits within the given
--   size.
sized :: (Transformable a, Enveloped a, V a ~ R2) => SizeSpec2D -> a -> a

-- | Uniformly scale an enveloped object so that it "has the same size as"
--   (fits within the width and height of) some other object.
sizedAs :: (Transformable a, Enveloped a, V a ~ R2, Enveloped b, V b ~ R2) => b -> a -> a

-- | Make width and height of <a>SizeSpec2D</a> into a tuple.
sizePair :: SizeSpec2D -> (Double, Double)
instance Eq SizeSpec2D
instance Ord SizeSpec2D
instance Show SizeSpec2D
instance Generic SizeSpec2D
instance Datatype D1SizeSpec2D
instance Constructor C1_0SizeSpec2D
instance Constructor C1_1SizeSpec2D
instance Constructor C1_2SizeSpec2D
instance Constructor C1_3SizeSpec2D
instance Hashable SizeSpec2D


-- | Basic types for three-dimensional Euclidean space.
module Diagrams.ThreeD.Types

-- | The three-dimensional Euclidean vector space R^3.
data R3
R3 :: !Double -> !Double -> !Double -> R3

-- | Construct a 3D vector from a triple of components.
r3 :: (Double, Double, Double) -> R3

-- | Convert a 3D vector back into a triple of components.
unr3 :: R3 -> (Double, Double, Double)

-- | Curried version of <a>r3</a>.
mkR3 :: Double -> Double -> Double -> R3

-- | Points in R^3.
type P3 = Point R3

-- | Construct a 3D point from a triple of coordinates.
p3 :: (Double, Double, Double) -> P3

-- | Convert a 3D point back into a triple of coordinates.
unp3 :: P3 -> (Double, Double, Double)

-- | Curried version of <a>r3</a>.
mkP3 :: Double -> Double -> Double -> P3

-- | Transformations in R^3.
type T3 = Transformation R3
r3Iso :: Iso' R3 (Double, Double, Double)
p3Iso :: Iso' P3 (Double, Double, Double)

-- | A <tt>Direction</tt> represents directions in R3. The constructor is
--   not exported; <tt>Direction</tt>s can be used with
--   <a>fromDirection</a> and the lenses provided by its instances.
data Direction

-- | <tt>direction v</tt> is the direction in which <tt>v</tt> points.
--   Returns an unspecified value when given the zero vector as input.
direction :: R3 -> Direction

-- | <tt>fromDirection d</tt> is the unit vector in the direction
--   <tt>d</tt>.
fromDirection :: Direction -> R3

-- | compute the positive angle between the two directions in their common
--   plane
angleBetweenDirs :: Direction -> Direction -> Angle

-- | Types which can be expressed in spherical 3D coordinates, as a triple
--   (r,θ,φ), where θ is rotation about the Z axis, and φ is th angle from
--   the Z axis.
class Spherical t
spherical :: Spherical t => Iso' t (Double, Angle, Angle)

-- | Types which can be expressed in cylindrical 3D coordinates.
class Cylindrical t
cylindrical :: Cylindrical t => Iso' t (Double, Angle, Double)

-- | The class of types with at least two angle coordinates, the second
--   called _phi.
class HasPhi t
_phi :: HasPhi t => Lens' t Angle
instance Eq R3
instance Ord R3
instance Show R3
instance Read R3
instance HasPhi Direction
instance HasTheta Direction
instance Spherical P3
instance Cylindrical P3
instance HasPhi P3
instance HasPhi R3
instance HasTheta P3
instance HasTheta R3
instance HasR P3
instance HasR R3
instance Spherical R3
instance Cylindrical R3
instance HasZ P3
instance HasZ R3
instance HasY P3
instance HasY R3
instance HasX P3
instance HasX R3
instance HasCross3 R3
instance Transformable R3
instance Coordinates R3
instance InnerSpace R3
instance HasBasis R3
instance VectorSpace R3
instance AdditiveGroup R3


-- | Three-dimensional vectors.
module Diagrams.ThreeD.Vector

-- | The unit vector in the positive X direction.
unitX :: R3

-- | The unit vector in the positive Y direction.
unitY :: R3

-- | The unit vector in the positive Z direction.
unitZ :: R3

-- | The unit vector in the negative X direction.
unit_X :: R3

-- | The unit vector in the negative Y direction.
unit_Y :: R3

-- | The unit vector in the negative Z direction.
unit_Z :: R3


-- | Types to specify lighting for 3D rendering.
module Diagrams.ThreeD.Light
data PointLight
PointLight :: P3 -> (Colour Double) -> PointLight
data ParallelLight
ParallelLight :: R3 -> (Colour Double) -> ParallelLight

-- | Construct a Diagram with a single PointLight at the origin, which
--   takes up no space.
pointLight :: (Backend b R3, Renderable PointLight b) => Colour Double -> Diagram b R3

-- | Construct a Diagram with a single ParallelLight, which takes up no
--   space.
parallelLight :: (Backend b R3, Renderable ParallelLight b) => Direction -> Colour Double -> Diagram b R3
instance Typeable PointLight
instance Typeable ParallelLight
instance Transformable ParallelLight
instance Transformable PointLight


-- | Types to specify viewpoint for 3D rendering.
module Diagrams.ThreeD.Camera
data Camera l

-- | A perspective projection
data PerspectiveLens
PerspectiveLens :: Angle -> Angle -> PerspectiveLens

-- | Horizontal field of view.
_horizontalFieldOfView :: PerspectiveLens -> Angle

-- | Vertical field of view.
_verticalFieldOfView :: PerspectiveLens -> Angle

-- | An orthographic projection
data OrthoLens
OrthoLens :: Double -> Double -> OrthoLens

-- | Width
_orthoWidth :: OrthoLens -> Double

-- | Height
_orthoHeight :: OrthoLens -> Double
horizontalFieldOfView :: Lens' PerspectiveLens Angle
verticalFieldOfView :: Lens' PerspectiveLens Angle
orthoWidth :: Lens' OrthoLens Double
orthoHeight :: Lens' OrthoLens Double
camLoc :: Camera l -> P3
camForward :: Camera l -> Direction
camUp :: Camera l -> Direction
camRight :: Camera l -> Direction
camLens :: Camera l -> l

-- | 'facing_ZCamera l' is a camera at the origin facing along the negative
--   Z axis, with its up-axis coincident with the positive Y axis, with the
--   projection defined by l.
facing_ZCamera :: (CameraLens l, Backend b R3, Renderable (Camera l) b) => l -> Diagram b R3

-- | A camera at the origin facing along the negative Z axis, with its
--   up-axis coincident with the positive Y axis. The field of view is
--   chosen to match a 50mm camera on 35mm film. Note that Cameras take up
--   no space in the Diagram.
mm50Camera :: (Backend b R3, Renderable (Camera PerspectiveLens) b) => Diagram b R3

-- | mm50 has the field of view of a 50mm lens on standard 35mm film, hence
--   an aspect ratio of 3:2.
mm50 :: PerspectiveLens

-- | mm50blWide has the same vertical field of view as mm50, but an aspect
--   ratio of 1.6, suitable for wide screen computer monitors.
mm50Wide :: PerspectiveLens

-- | mm50Narrow has the same vertical field of view as mm50, but an aspect
--   ratio of 4:3, for VGA and similar computer resulotions.
mm50Narrow :: PerspectiveLens

-- | The natural aspect ratio of the projection.
aspect :: CameraLens l => l -> Double
camAspect :: CameraLens l => Camera l -> Double
instance Renderable (Camera l) NullBackend
instance Transformable (Camera l)
instance CameraLens OrthoLens
instance Typeable OrthoLens
instance CameraLens PerspectiveLens
instance Typeable1 Camera
instance Typeable PerspectiveLens


-- | Various three-dimensional shapes.
module Diagrams.ThreeD.Shapes
data Ellipsoid
Ellipsoid :: T3 -> Ellipsoid

-- | A sphere of radius 1 with its center at the origin.
sphere :: (Backend b R3, Renderable Ellipsoid b) => Diagram b R3
data Box
Box :: T3 -> Box

-- | A cube with side length 1, in the positive octant, with one vertex at
--   the origin.
cube :: (Backend b R3, Renderable Box b) => Diagram b R3
data Frustum
Frustum :: Double -> Double -> T3 -> Frustum

-- | A frustum of a right circular cone. It has height 1 oriented along the
--   positive z axis, and radii r0 and r1 at Z=0 and Z=1. <a>cone</a> and
--   <a>cylinder</a> are special cases.
frustum :: (Backend b R3, Renderable Frustum b) => Double -> Double -> Diagram b R3

-- | A cone with its base centered on the origin, with radius 1 at the
--   base, height 1, and it's apex on the positive Z axis.
cone :: (Backend b R3, Renderable Frustum b) => Diagram b R3

-- | A circular cylinder of radius 1 with one end cap centered on the
--   origin, and extending to Z=1.
cylinder :: (Backend b R3, Renderable Frustum b) => Diagram b R3
instance Typeable Ellipsoid
instance Typeable Box
instance Typeable Frustum
instance Renderable Frustum NullBackend
instance Transformable Frustum
instance Renderable Box NullBackend
instance Transformable Box
instance Renderable Ellipsoid NullBackend
instance Transformable Ellipsoid


-- | Points in space. For more tools for working with points and vectors,
--   see <a>Data.AffineSpace</a> and <a>Diagrams.Coordinates</a>.
module Diagrams.Points

-- | <tt>Point</tt> is a newtype wrapper around vectors used to represent
--   points, so we don't get them mixed up. The distinction between vectors
--   and points is important: translations affect points, but leave vectors
--   unchanged. Points are instances of the <a>AffineSpace</a> class from
--   <a>Data.AffineSpace</a>.
data Point v :: * -> *

-- | The origin of the vector space <tt>v</tt>.
origin :: AdditiveGroup v => Point v

-- | Scale a point by a scalar.
(*.) :: VectorSpace v => Scalar v -> Point v -> Point v

-- | The centroid of a set of <i>n</i> points is their sum divided by
--   <i>n</i>.
centroid :: (VectorSpace v, Fractional (Scalar v)) => [Point v] -> Point v

-- | Create a "point diagram", which has no content, no trace, an empty
--   query, and a point envelope.
pointDiagram :: (Fractional (Scalar v), InnerSpace v) => Point v -> QDiagram b v m


-- | A query is a function that maps points in a vector space to values in
--   some monoid. Queries naturally form a monoid, with two queries being
--   combined pointwise.
module Diagrams.Query

-- | A query is a function that maps points in a vector space to values in
--   some monoid. Queries naturally form a monoid, with two queries being
--   combined pointwise.
--   
--   The idea for annotating diagrams with monoidal queries came from the
--   graphics-drawingcombinators package,
--   <a>http://hackage.haskell.org/package/graphics-drawingcombinators</a>.
newtype Query v m :: * -> * -> *
Query :: (Point v -> m) -> Query v m
runQuery :: Query v m -> Point v -> m

-- | Get the query function associated with a diagram.
query :: Monoid m => QDiagram b v m -> Query v m

-- | Sample a diagram's query function at a given point.
sample :: Monoid m => QDiagram b v m -> Point v -> m

-- | Set the query value for <a>True</a> points in a diagram (<i>i.e.</i>
--   points "inside" the diagram); <a>False</a> points will be set to
--   <a>mempty</a>.
value :: Monoid m => m -> QDiagram b v Any -> QDiagram b v m

-- | Reset the query values of a diagram to <tt>True</tt>/<tt>False</tt>:
--   any values equal to <a>mempty</a> are set to <a>False</a>; any other
--   values are set to <a>True</a>.
resetValue :: (Eq m, Monoid m) => QDiagram b v m -> QDiagram b v Any

-- | Set all the query values of a diagram to <a>False</a>.
clearValue :: QDiagram b v m -> QDiagram b v Any


-- | Names can be given to subdiagrams, and subdiagrams can later be
--   queried by name. This module exports types for representing names and
--   subdiagrams, and various functions for working with them.
module Diagrams.Names

-- | Atomic names. <tt>AName</tt> is just an existential wrapper around
--   things which are <a>Typeable</a>, <a>Ord</a> and <a>Show</a>.
data AName :: *

-- | A (qualified) name is a (possibly empty) sequence of atomic names.
data Name :: *

-- | Class for those types which can be used as names. They must support
--   <a>Typeable</a> (to facilitate extracting them from existential
--   wrappers), <a>Ord</a> (for comparison and efficient storage) and
--   <a>Show</a>.
--   
--   To make an instance of <a>IsName</a>, you need not define any methods,
--   just declare it.
--   
--   WARNING: it is not recommended to use
--   <tt>GeneralizedNewtypeDeriving</tt> in conjunction with
--   <tt>IsName</tt>, since in that case the underlying type and the
--   <tt>newtype</tt> will be considered equivalent when comparing names.
--   For example:
--   
--   <pre>
--   newtype WordN = WordN Int deriving (Show, Ord, Eq, Typeable, IsName)
--   </pre>
--   
--   is unlikely to work as intended, since <tt>(1 :: Int)</tt> and
--   <tt>(WordN 1)</tt> will be considered equal as names. Instead, use
--   
--   <pre>
--   newtype WordN = WordN Int deriving (Show, Ord, Eq, Typeable, IsName)
--   instance IsName WordN
--   </pre>
class (Typeable a, Ord a, Show a) => IsName a
toName :: IsName a => a -> Name

-- | Convenient operator for writing qualified names with atomic components
--   of different types. Instead of writing <tt>toName a1 &lt;&gt; toName
--   a2 &lt;&gt; toName a3</tt> you can just write <tt>a1 .&gt; a2 .&gt;
--   a3</tt>.
(.>) :: (IsName a1, IsName a2) => a1 -> a2 -> Name

-- | Instances of <a>Qualifiable</a> are things which can be qualified by
--   prefixing them with a name.
class Qualifiable q
(|>) :: (Qualifiable q, IsName a) => a -> q -> q

-- | A <tt>Subdiagram</tt> represents a diagram embedded within the context
--   of a larger diagram. Essentially, it consists of a diagram paired with
--   any accumulated information from the larger context (transformations,
--   attributes, etc.).
data Subdiagram b v m :: * -> * -> * -> *

-- | Turn a diagram into a subdiagram with no accumulated context.
mkSubdiagram :: QDiagram b v m -> Subdiagram b v m

-- | Create a "point subdiagram", that is, a <a>pointDiagram</a> (with no
--   content and a point envelope) treated as a subdiagram with local
--   origin at the given point. Note this is not the same as
--   <tt>mkSubdiagram . pointDiagram</tt>, which would result in a
--   subdiagram with local origin at the parent origin, rather than at the
--   given point.
subPoint :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => Point v -> Subdiagram b v m

-- | Turn a subdiagram into a normal diagram, including the enclosing
--   context. Concretely, a subdiagram is a pair of (1) a diagram and (2) a
--   "context" consisting of an extra transformation and attributes.
--   <tt>getSub</tt> simply applies the transformation and attributes to
--   the diagram to get the corresponding "top-level" diagram.
getSub :: (HasLinearMap v, InnerSpace v, Floating (Scalar v), Ord (Scalar v), Semigroup m) => Subdiagram b v m -> QDiagram b v m

-- | Extract the "raw" content of a subdiagram, by throwing away the
--   context.
rawSub :: Subdiagram b v m -> QDiagram b v m

-- | Get the location of a subdiagram; that is, the location of its local
--   origin <i>with respect to</i> the vector space of its parent diagram.
--   In other words, the point where its local origin "ended up".
location :: HasLinearMap v => Subdiagram b v m -> Point v

-- | A <a>SubMap</a> is a map associating names to subdiagrams. There can
--   be multiple associations for any given name.
data SubMap b v m :: * -> * -> * -> *

-- | Construct a <a>SubMap</a> from a list of associations between names
--   and subdiagrams.
fromNames :: IsName a => [(a, Subdiagram b v m)] -> SubMap b v m

-- | Add a name/diagram association to a submap.
rememberAs :: IsName a => a -> QDiagram b v m -> SubMap b v m -> SubMap b v m

-- | Look for the given name in a name map, returning a list of subdiagrams
--   associated with that name. If no names match the given name exactly,
--   return all the subdiagrams associated with names of which the given
--   name is a suffix.
lookupSub :: IsName n => n -> SubMap b v m -> Maybe [Subdiagram b v m]

-- | Attach an atomic name to a diagram.
named :: (IsName n, HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => n -> QDiagram b v m -> QDiagram b v m

-- | Attach an atomic name to a certain subdiagram, computed from the given
--   diagram /with the mapping from name to subdiagram included/. The
--   upshot of this knot-tying is that if <tt>d' = d # named x</tt>, then
--   <tt>lookupName x d' == Just d'</tt> (instead of <tt>Just d</tt>).
nameSub :: (IsName n, HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => (QDiagram b v m -> Subdiagram b v m) -> n -> QDiagram b v m -> QDiagram b v m

-- | Attach an atomic name to a certain point (which may be computed from
--   the given diagram), treated as a subdiagram with no content and a
--   point envelope.
namePoint :: (IsName n, HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => (QDiagram b v m -> Point v) -> n -> QDiagram b v m -> QDiagram b v m

-- | "Localize" a diagram by hiding all the names, so they are no longer
--   visible to the outside.
localize :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => QDiagram b v m -> QDiagram b v m

-- | Get a list of names of subdiagrams and their locations.
names :: (HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => QDiagram b v m -> [(Name, [Point v])]

-- | Lookup the most recent diagram associated with (some qualification of)
--   the given name.
lookupName :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> QDiagram b v m -> Maybe (Subdiagram b v m)

-- | Given a name and a diagram transformation indexed by a subdiagram,
--   perform the transformation using the most recent subdiagram associated
--   with (some qualification of) the name, or perform the identity
--   transformation if the name does not exist.
withName :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> (Subdiagram b v m -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | Given a name and a diagram transformation indexed by a list of
--   subdiagrams, perform the transformation using the collection of all
--   such subdiagrams associated with (some qualification of) the given
--   name.
withNameAll :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> ([Subdiagram b v m] -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | Given a list of names and a diagram transformation indexed by a list
--   of subdiagrams, perform the transformation using the list of most
--   recent subdiagrams associated with (some qualification of) each name.
--   Do nothing (the identity transformation) if any of the names do not
--   exist.
withNames :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => [n] -> ([Subdiagram b v m] -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m


-- | Affine transformations, parameterized by any vector space. For
--   transformations on particular vector spaces, see <i>e.g.</i>
--   <a>Diagrams.TwoD.Transform</a>.
module Diagrams.Transform

-- | General (affine) transformations, represented by an invertible linear
--   map, its <i>transpose</i>, and a vector representing a translation
--   component.
--   
--   By the <i>transpose</i> of a linear map we mean simply the linear map
--   corresponding to the transpose of the map's matrix representation. For
--   example, any scale is its own transpose, since scales are represented
--   by matrices with zeros everywhere except the diagonal. The transpose
--   of a rotation is the same as its inverse.
--   
--   The reason we need to keep track of transposes is because it turns out
--   that when transforming a shape according to some linear map L, the
--   shape's <i>normal vectors</i> transform according to L's inverse
--   transpose. This is exactly what we need when transforming bounding
--   functions, which are defined in terms of <i>perpendicular</i> (i.e.
--   normal) hyperplanes.
--   
--   For more general, non-invertable transformations, see
--   <tt>Diagrams.Deform</tt> (in <tt>diagrams-lib</tt>).
data Transformation v :: * -> *

-- | Invert a transformation.
inv :: HasLinearMap v => Transformation v -> Transformation v

-- | Get the translational component of a transformation.
transl :: Transformation v -> v

-- | Apply a transformation to a vector. Note that any translational
--   component of the transformation will not affect the vector, since
--   vectors are invariant under translation.
apply :: HasLinearMap v => Transformation v -> v -> v

-- | Apply a transformation to a point.
papply :: HasLinearMap v => Transformation v -> Point v -> Point v

-- | Type class for things <tt>t</tt> which can be transformed.
class HasLinearMap (V t) => Transformable t
transform :: Transformable t => Transformation (V t) -> t -> t

-- | Create a translation.
translation :: HasLinearMap v => v -> Transformation v

-- | Translate by a vector.
translate :: (Transformable t, HasLinearMap (V t)) => V t -> t -> t

-- | Translate the object by the translation that sends the origin to the
--   given point. Note that this is dual to <a>moveOriginTo</a>, i.e. we
--   should have
--   
--   <pre>
--   moveTo (origin .^+ v) === moveOriginTo (origin .^- v)
--   </pre>
--   
--   For types which are also <tt>Transformable</tt>, this is essentially
--   the same as <tt>translate</tt>, i.e.
--   
--   <pre>
--   moveTo (origin .^+ v) === translate v
--   </pre>
moveTo :: HasOrigin t => Point (V t) -> t -> t

-- | A flipped variant of <a>moveTo</a>, provided for convenience. Useful
--   when writing a function which takes a point as an argument, such as
--   when using <tt>withName</tt> and friends.
place :: HasOrigin t => t -> Point (V t) -> t

-- | Create a uniform scaling transformation.
scaling :: (HasLinearMap v, Fractional (Scalar v)) => Scalar v -> Transformation v

-- | Scale uniformly in every dimension by the given scalar.
scale :: (Transformable t, Fractional (Scalar (V t)), Eq (Scalar (V t))) => Scalar (V t) -> t -> t

-- | Conjugate one transformation by another. <tt>conjugate t1 t2</tt> is
--   the transformation which performs first <tt>t1</tt>, then <tt>t2</tt>,
--   then the inverse of <tt>t1</tt>.
conjugate :: HasLinearMap v => Transformation v -> Transformation v -> Transformation v

-- | Carry out some transformation "under" another one: <tt>f
--   `<a>under</a>` t</tt> first applies <tt>t</tt>, then <tt>f</tt>, then
--   the inverse of <tt>t</tt>. For example, <tt><tt>scaleX</tt> 2
--   `<a>under</a>` <tt>rotation</tt> (-1/8 @@ Turn)</tt> is the
--   transformation which scales by a factor of 2 along the diagonal line y
--   = x.
--   
--   Note that
--   
--   <pre>
--   (transform t2) <a>under</a> t1 == transform (conjugate t1 t2)
--   </pre>
--   
--   for all transformations <tt>t1</tt> and <tt>t2</tt>.
under :: (Transformable a, Transformable b, V a ~ V b) => (a -> b) -> Transformation (V a) -> a -> b

-- | Class of types which have an intrinsic notion of a "local origin",
--   i.e. things which are not invariant under translation, and which allow
--   the origin to be moved.
--   
--   One might wonder why not just use <tt>Transformable</tt> instead of
--   having a separate class for <a>HasOrigin</a>; indeed, for types which
--   are instances of both we should have the identity
--   
--   <pre>
--   moveOriginTo (origin .^+ v) === translate (negateV v)
--   </pre>
--   
--   The reason is that some things (e.g. vectors, <tt>Trail</tt>s) are
--   transformable but are translationally invariant, i.e. have no origin.
class VectorSpace (V t) => HasOrigin t
moveOriginTo :: HasOrigin t => Point (V t) -> t -> t

-- | Move the local origin by a relative vector.
moveOriginBy :: HasOrigin t => V t -> t -> t


-- | Transformations specific to two dimensions, with a few generic
--   transformations (uniform scaling, translation) also re-exported for
--   convenience.
module Diagrams.TwoD.Transform

-- | Create a transformation which performs a rotation about the local
--   origin by the given angle. See also <a>rotate</a>.
rotation :: Angle -> T2

-- | Rotate about the local origin by the given angle. Positive angles
--   correspond to counterclockwise rotation, negative to clockwise. The
--   angle can be expressed using any of the <tt>Iso</tt>s on <a>Angle</a>.
--   For example, <tt>rotate (1/4 @@ <a>turn</a>)</tt>, <tt>rotate (tau/4
--   @@ rad)</tt>, and <tt>rotate (90 @@ deg)</tt> all represent the same
--   transformation, namely, a counterclockwise rotation by a right angle.
--   To rotate about some point other than the local origin, see
--   <a>rotateAbout</a>.
--   
--   Note that writing <tt>rotate (1/4)</tt>, with no <a>Angle</a>
--   constructor, will yield an error since GHC cannot figure out which
--   sort of angle you want to use. In this common situation you can use
--   <a>rotateBy</a>, which interprets its argument as a number of turns.
rotate :: (Transformable t, V t ~ R2) => Angle -> t -> t

-- | A synonym for <a>rotate</a>, interpreting its argument in units of
--   turns; it can be more convenient to write <tt>rotateBy (1/4)</tt> than
--   <tt><a>rotate</a> (1/4 @@ <a>turn</a>)</tt>.
rotateBy :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>rotationAbout p</tt> is a rotation about the point <tt>p</tt>
--   (instead of around the local origin).
rotationAbout :: P2 -> Angle -> T2

-- | <tt>rotateAbout p</tt> is like <a>rotate</a>, except it rotates around
--   the point <tt>p</tt> instead of around the local origin.
rotateAbout :: (Transformable t, V t ~ R2) => P2 -> Angle -> t -> t

-- | Construct a transformation which scales by the given factor in the x
--   (horizontal) direction.
scalingX :: Double -> T2

-- | Scale a diagram by the given factor in the x (horizontal) direction.
--   To scale uniformly, use <a>scale</a>.
scaleX :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Construct a transformation which scales by the given factor in the y
--   (vertical) direction.
scalingY :: Double -> T2

-- | Scale a diagram by the given factor in the y (vertical) direction. To
--   scale uniformly, use <a>scale</a>.
scaleY :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Create a uniform scaling transformation.
scaling :: (HasLinearMap v, Fractional (Scalar v)) => Scalar v -> Transformation v

-- | Scale uniformly in every dimension by the given scalar.
scale :: (Transformable t, Fractional (Scalar (V t)), Eq (Scalar (V t))) => Scalar (V t) -> t -> t

-- | <tt>scaleToX w</tt> scales a diagram in the x (horizontal) direction
--   by whatever factor required to make its width <tt>w</tt>.
--   <tt>scaleToX</tt> should not be applied to diagrams with a width of 0,
--   such as <tt>vrule</tt>.
scaleToX :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>scaleToY h</tt> scales a diagram in the y (vertical) direction by
--   whatever factor required to make its height <tt>h</tt>.
--   <tt>scaleToY</tt> should not be applied to diagrams with a height of
--   0, such as <tt>hrule</tt>.
scaleToY :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>scaleUToX w</tt> scales a diagram <i>uniformly</i> by whatever
--   factor required to make its width <tt>w</tt>. <tt>scaleUToX</tt>
--   should not be applied to diagrams with a width of 0, such as
--   <tt>vrule</tt>.
scaleUToX :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>scaleUToY h</tt> scales a diagram <i>uniformly</i> by whatever
--   factor required to make its height <tt>h</tt>. <tt>scaleUToY</tt>
--   should not be applied to diagrams with a height of 0, such as
--   <tt>hrule</tt>.
scaleUToY :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | Construct a transformation which translates by the given distance in
--   the x (horizontal) direction.
translationX :: Double -> T2

-- | Translate a diagram by the given distance in the x (horizontal)
--   direction.
translateX :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Construct a transformation which translates by the given distance in
--   the y (vertical) direction.
translationY :: Double -> T2

-- | Translate a diagram by the given distance in the y (vertical)
--   direction.
translateY :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Create a translation.
translation :: HasLinearMap v => v -> Transformation v

-- | Translate by a vector.
translate :: (Transformable t, HasLinearMap (V t)) => V t -> t -> t

-- | Construct a transformation which flips a diagram from left to right,
--   i.e. sends the point (x,y) to (-x,y).
reflectionX :: T2

-- | Flip a diagram from left to right, i.e. send the point (x,y) to
--   (-x,y).
reflectX :: (Transformable t, V t ~ R2) => t -> t

-- | Construct a transformation which flips a diagram from top to bottom,
--   i.e. sends the point (x,y) to (x,-y).
reflectionY :: T2

-- | Flip a diagram from top to bottom, i.e. send the point (x,y) to
--   (x,-y).
reflectY :: (Transformable t, V t ~ R2) => t -> t

-- | <tt>reflectionAbout p v</tt> is a reflection in the line determined by
--   the point <tt>p</tt> and vector <tt>v</tt>.
reflectionAbout :: P2 -> R2 -> T2

-- | <tt>reflectAbout p v</tt> reflects a diagram in the line determined by
--   the point <tt>p</tt> and the vector <tt>v</tt>.
reflectAbout :: (Transformable t, V t ~ R2) => P2 -> R2 -> t -> t

-- | <tt>shearingX d</tt> is the linear transformation which is the
--   identity on y coordinates and sends <tt>(0,1)</tt> to <tt>(d,1)</tt>.
shearingX :: Double -> T2

-- | <tt>shearX d</tt> performs a shear in the x-direction which sends
--   <tt>(0,1)</tt> to <tt>(d,1)</tt>.
shearX :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>shearingY d</tt> is the linear transformation which is the
--   identity on x coordinates and sends <tt>(1,0)</tt> to <tt>(1,d)</tt>.
shearingY :: Double -> T2

-- | <tt>shearY d</tt> performs a shear in the y-direction which sends
--   <tt>(1,0)</tt> to <tt>(1,d)</tt>.
shearY :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Get the matrix equivalent of the linear transform, (as a pair of
--   columns) and the translation vector. This is mostly useful for
--   implementing backends.
onBasis :: Transformation R2 -> ((R2, R2), R2)


-- | Wrapper for creating scale-invariant objects in two dimensions.
module Diagrams.TwoD.Transform.ScaleInv

-- | The <tt>ScaleInv</tt> wrapper creates two-dimensional
--   <i>scale-invariant</i> objects. Intuitively, a scale-invariant object
--   is affected by transformations like translations and rotations, but
--   not by scales.
--   
--   However, this is problematic when it comes to <i>non-uniform</i>
--   scales (<i>e.g.</i> <tt>scaleX 2 . scaleY 3</tt>) since they can
--   introduce a perceived rotational component. The prototypical example
--   is an arrowhead on the end of a path, which should be scale-invariant.
--   However, applying a non-uniform scale to the path but not the
--   arrowhead would leave the arrowhead pointing in the wrong direction.
--   
--   Moreover, for objects whose local origin is not at the local origin of
--   the parent diagram, any scale can result in a translational component
--   as well.
--   
--   The solution is to also store a point (indicating the location,
--   <i>i.e.</i> the local origin) and a unit vector (indicating the
--   <i>direction</i>) along with a scale-invariant object. A
--   transformation to be applied is decomposed into rotational and
--   translational components as follows:
--   
--   <ul>
--   <li>The transformation is applied to the direction vector, and the
--   difference in angle between the original direction vector and its
--   image under the transformation determines the rotational component.
--   The rotation is applied with respect to the stored location, rather
--   than the global origin.</li>
--   <li>The vector from the location to the image of the location under
--   the transformation determines the translational component.</li>
--   </ul>
data ScaleInv t
ScaleInv :: t -> R2 -> P2 -> ScaleInv t
_scaleInvObj :: ScaleInv t -> t
_scaleInvDir :: ScaleInv t -> R2
_scaleInvLoc :: ScaleInv t -> P2
scaleInvObj :: Lens (ScaleInv t_aO6U) (ScaleInv t_aO8h) t_aO6U t_aO8h
scaleInvDir :: Lens' (ScaleInv t_aO6U) R2
scaleInvLoc :: Lens' (ScaleInv t_aO6U) P2

-- | Create a scale-invariant object pointing in the given direction,
--   located at the origin.
scaleInv :: t -> R2 -> ScaleInv t

-- | Create a diagram from a single scale-invariant primitive. The vector
--   argument specifies the direction in which the primitive is "pointing"
--   (for the purpose of keeping it rotated correctly under non-uniform
--   scaling). The primitive is assumed to be "located" at the origin (for
--   the purpose of translating it correctly under scaling).
--   
--   Note that the resulting diagram will have an <i>empty</i> envelope,
--   trace, and query. The reason is that the envelope, trace, and query
--   cannot be cached---applying a transformation would cause the cached
--   envelope, etc. to get "out of sync" with the scale-invariant object.
--   The intention, at any rate, is that scale-invariant things will be
--   used only as "decorations" (<i>e.g.</i> arrowheads) which should not
--   affect the envelope, trace, and query.
scaleInvPrim :: (Transformable t, Typeable t, Renderable t b, V t ~ R2, Monoid m) => t -> R2 -> QDiagram b R2 m
instance (Renderable t b, V t ~ R2) => Renderable (ScaleInv t) b
instance (V t ~ R2, Transformable t) => Transformable (ScaleInv t)
instance (V t ~ R2, HasOrigin t) => HasOrigin (ScaleInv t)
instance Typeable1 ScaleInv
instance Show t => Show (ScaleInv t)


-- | Transformations specific to three dimensions, with a few generic
--   transformations (uniform scaling, translation) also re-exported for
--   convenience.
module Diagrams.ThreeD.Transform

-- | Like <a>aboutZ</a>, but rotates about the X axis, bringing positive
--   y-values towards the positive z-axis.
aboutX :: Angle -> T3

-- | Like <a>aboutZ</a>, but rotates about the Y axis, bringing postive
--   x-values towards the negative z-axis.
aboutY :: Angle -> T3

-- | Create a transformation which rotates by the given angle about a line
--   parallel the Z axis passing through the local origin. A positive angle
--   brings positive x-values towards the positive-y axis.
--   
--   The angle can be expressed using any type which is an instance of
--   <a>Angle</a>. For example, <tt>aboutZ (1/4 @@ <a>turn</a>)</tt>,
--   <tt>aboutZ (tau/4 @@ <a>rad</a>)</tt>, and <tt>aboutZ (90 @@
--   <a>deg</a>)</tt> all represent the same transformation, namely, a
--   counterclockwise rotation by a right angle. For more general
--   rotations, see <a>rotationAbout</a>.
--   
--   Note that writing <tt>aboutZ (1/4)</tt>, with no type annotation, will
--   yield an error since GHC cannot figure out which sort of angle you
--   want to use.
aboutZ :: Angle -> T3

-- | <tt>rotationAbout p d a</tt> is a rotation about a line parallel to
--   <tt>d</tt> passing through <tt>p</tt>.
rotationAbout :: P3 -> Direction -> Angle -> T3

-- | <tt>pointAt about initial final</tt> produces a rotation which brings
--   the direction <tt>initial</tt> to point in the direction
--   <tt>final</tt> by first panning around <tt>about</tt>, then tilting
--   about the axis perpendicular to initial and final. In particular, if
--   this can be accomplished without tilting, it will be, otherwise if
--   only tilting is necessary, no panning will occur. The tilt will always
--   be between ± /4 turn.
pointAt :: Direction -> Direction -> Direction -> T3

-- | pointAt' has the same behavior as <a>pointAt</a>, but takes vectors
--   instead of directions.
pointAt' :: R3 -> R3 -> R3 -> T3

-- | Construct a transformation which scales by the given factor in the x
--   direction.
scalingX :: Double -> T3

-- | Construct a transformation which scales by the given factor in the y
--   direction.
scalingY :: Double -> T3

-- | Construct a transformation which scales by the given factor in the z
--   direction.
scalingZ :: Double -> T3

-- | Scale a diagram by the given factor in the x (horizontal) direction.
--   To scale uniformly, use <a>scale</a>.
scaleX :: (Transformable t, V t ~ R3) => Double -> t -> t

-- | Scale a diagram by the given factor in the y (vertical) direction. To
--   scale uniformly, use <a>scale</a>.
scaleY :: (Transformable t, V t ~ R3) => Double -> t -> t

-- | Scale a diagram by the given factor in the z direction. To scale
--   uniformly, use <a>scale</a>.
scaleZ :: (Transformable t, V t ~ R3) => Double -> t -> t

-- | Create a uniform scaling transformation.
scaling :: (HasLinearMap v, Fractional (Scalar v)) => Scalar v -> Transformation v

-- | Scale uniformly in every dimension by the given scalar.
scale :: (Transformable t, Fractional (Scalar (V t)), Eq (Scalar (V t))) => Scalar (V t) -> t -> t

-- | Construct a transformation which translates by the given distance in
--   the x direction.
translationX :: Double -> T3

-- | Translate a diagram by the given distance in the x direction.
translateX :: (Transformable t, V t ~ R3) => Double -> t -> t

-- | Construct a transformation which translates by the given distance in
--   the y direction.
translationY :: Double -> T3

-- | Translate a diagram by the given distance in the y direction.
translateY :: (Transformable t, V t ~ R3) => Double -> t -> t

-- | Construct a transformation which translates by the given distance in
--   the z direction.
translationZ :: Double -> T3

-- | Translate a diagram by the given distance in the y direction.
translateZ :: (Transformable t, V t ~ R3) => Double -> t -> t

-- | Create a translation.
translation :: HasLinearMap v => v -> Transformation v

-- | Translate by a vector.
translate :: (Transformable t, HasLinearMap (V t)) => V t -> t -> t

-- | Construct a transformation which flips a diagram across x=0, i.e.
--   sends the point (x,y,z) to (-x,y,z).
reflectionX :: T3

-- | Flip a diagram across x=0, i.e. send the point (x,y,z) to (-x,y,z).
reflectX :: (Transformable t, V t ~ R3) => t -> t

-- | Construct a transformation which flips a diagram across y=0, i.e.
--   sends the point (x,y,z) to (x,-y,z).
reflectionY :: T3

-- | Flip a diagram across y=0, i.e. send the point (x,y,z) to (x,-y,z).
reflectY :: (Transformable t, V t ~ R3) => t -> t

-- | Construct a transformation which flips a diagram across z=0, i.e.
--   sends the point (x,y,z) to (x,y,-z).
reflectionZ :: T3

-- | Flip a diagram across z=0, i.e. send the point (x,y,z) to (x,y,-z).
reflectZ :: (Transformable t, V t ~ R3) => t -> t

-- | <tt>reflectionAbout p v</tt> is a reflection across the plane through
--   the point <tt>p</tt> and normal to vector <tt>v</tt>.
reflectionAbout :: P3 -> R3 -> T3

-- | <tt>reflectAbout p v</tt> reflects a diagram in the line determined by
--   the point <tt>p</tt> and the vector <tt>v</tt>.
reflectAbout :: (Transformable t, V t ~ R3) => P3 -> R3 -> t -> t

-- | Get the matrix equivalent of an affine transform, as a triple of
--   columns paired with the translation vector. This is mostly useful for
--   implementing backends.
onBasis :: T3 -> ((R3, R3, R3), R3)


-- | Type classes for things which are parameterized in some way,
--   <i>e.g.</i> segments and trails.
module Diagrams.Parametric

-- | The standard tolerance used by <tt>std...</tt> functions (like
--   <a>stdArcLength</a> and <a>stdArcLengthToParam</a>, currently set at
--   <tt>1e-6</tt>.
stdTolerance :: Fractional a => a

-- | Codomain of parametric classes. This is usually either <tt>(V p)</tt>,
--   for relative vector results, or <tt>(Point (V p))</tt>, for functions
--   with absolute coordinates.

-- | Type class for parametric functions.
class Parametric p
atParam :: Parametric p => p -> Scalar (V p) -> Codomain p

-- | Type class for parametric functions with a bounded domain. The default
--   bounds are <tt>[0,1]</tt>.
--   
--   Note that this domain indicates the main "interesting" portion of the
--   function. It must be defined within this range, but for some instances
--   may still have sensible values outside.
class DomainBounds p where domainLower = const 0 domainUpper = const 1
domainLower :: DomainBounds p => p -> Scalar (V p)
domainUpper :: DomainBounds p => p -> Scalar (V p)

-- | Return the lower and upper bounds of a parametric domain together as a
--   pair.
domainBounds :: DomainBounds p => p -> (Scalar (V p), Scalar (V p))

-- | Type class for querying the values of a parametric object at the ends
--   of its domain.
class (Parametric p, DomainBounds p) => EndValues p where atStart x = x `atParam` domainLower x atEnd x = x `atParam` domainUpper x
atStart :: EndValues p => p -> Codomain p
atEnd :: EndValues p => p -> Codomain p

-- | Type class for parametric objects which can be split into subobjects.
--   
--   Minimal definition: Either <a>splitAtParam</a> or <a>section</a>, plus
--   <a>reverseDomain</a>.
class DomainBounds p => Sectionable p where splitAtParam x t = (section x (domainLower x) t, section x t (domainUpper x)) section x t1 t2 = snd (splitAtParam (fst (splitAtParam x t2)) (t1 / t2))
splitAtParam :: Sectionable p => p -> Scalar (V p) -> (p, p)
section :: Sectionable p => p -> Scalar (V p) -> Scalar (V p) -> p
reverseDomain :: Sectionable p => p -> p

-- | Type class for parametric things with a notion of arc length.
class Parametric p => HasArcLength p where arcLength eps = midpoint . arcLengthBounded eps stdArcLength = arcLength stdTolerance stdArcLengthToParam = arcLengthToParam stdTolerance
arcLengthBounded :: HasArcLength p => Scalar (V p) -> p -> Interval (Scalar (V p))
arcLength :: HasArcLength p => Scalar (V p) -> p -> Scalar (V p)
stdArcLength :: HasArcLength p => p -> Scalar (V p)
arcLengthToParam :: HasArcLength p => Scalar (V p) -> p -> Scalar (V p) -> Scalar (V p)
stdArcLengthToParam :: HasArcLength p => p -> Scalar (V p) -> Scalar (V p)


-- | Tools for adjusting the length of parametric objects such as segments
--   and trails.
module Diagrams.Parametric.Adjust

-- | Adjust the length of a parametric object such as a segment or trail.
--   The second parameter is an option record which controls how the
--   adjustment should be performed; see <a>AdjustOpts</a>.
adjust :: (DomainBounds a, Sectionable a, HasArcLength a, Fractional (Scalar (V a))) => a -> AdjustOpts (V a) -> a

-- | How should a segment, trail, or path be adjusted?
data AdjustOpts v

-- | Which method should be used for adjusting?
adjMethod :: Lens' (AdjustOpts v) (AdjustMethod v)

-- | Which end(s) of the object should be adjusted?
adjSide :: Lens' (AdjustOpts v) AdjustSide

-- | Tolerance to use when doing adjustment.
adjEps :: Lens' (AdjustOpts v) (Scalar v)

-- | What method should be used for adjusting a segment, trail, or path?
data AdjustMethod v

-- | Extend by the given parameter value (use a negative parameter to
--   shrink)
ByParam :: (Scalar v) -> AdjustMethod v

-- | Extend by the given arc length (use a negative length to shrink)
ByAbsolute :: (Scalar v) -> AdjustMethod v

-- | Extend or shrink to the given arc length
ToAbsolute :: (Scalar v) -> AdjustMethod v

-- | Which side of a segment, trail, or path should be adjusted?
data AdjustSide

-- | Adjust only the beginning
Start :: AdjustSide

-- | Adjust only the end
End :: AdjustSide

-- | Adjust both sides equally
Both :: AdjustSide
instance Fractional (Scalar v) => Default (AdjustOpts v)
instance Default AdjustSide
instance Fractional (Scalar v) => Default (AdjustMethod v)
instance Show AdjustSide
instance Read AdjustSide
instance Eq AdjustSide
instance Ord AdjustSide
instance Bounded AdjustSide
instance Enum AdjustSide


-- | "Located" things, <i>i.e.</i> things with a concrete location:
--   intuitively, <tt>Located a ~ (a, Point)</tt>. Wrapping a
--   translationally invariant thing (<i>e.g.</i> a <tt>Segment</tt> or
--   <tt>Trail</tt>) in <tt>Located</tt> pins it down to a particular
--   location and makes it no longer translationally invariant.
module Diagrams.Located

-- | "Located" things, <i>i.e.</i> things with a concrete location:
--   intuitively, <tt>Located a ~ (Point, a)</tt>. Wrapping a
--   translationally invariant thing (<i>e.g.</i> a <tt>Segment</tt> or
--   <tt>Trail</tt>) in <a>Located</a> pins it down to a particular
--   location and makes it no longer translationally invariant.
--   
--   <tt>Located</tt> is intentionally abstract. To construct
--   <tt>Located</tt> values, use <a>at</a>. To destruct, use
--   <a>viewLoc</a>, <a>unLoc</a>, or <a>loc</a>. To map, use
--   <a>mapLoc</a>.
--   
--   Much of the utility of having a concrete type for the <tt>Located</tt>
--   concept lies in the type class instances we can give it. The
--   <a>HasOrigin</a>, <a>Transformable</a>, <a>Enveloped</a>,
--   <a>Traced</a>, and <tt>TrailLike</tt> instances are particularly
--   useful; see the documented instances below for more information.
data Located a

-- | Construct a <tt>Located a</tt> from a value of type <tt>a</tt> and a
--   location. <tt>at</tt> is intended to be used infix, like <tt>x `at`
--   origin</tt>.
at :: a -> Point (V a) -> Located a

-- | Deconstruct a <tt>Located a</tt> into a location and a value of type
--   <tt>a</tt>. <tt>viewLoc</tt> can be especially useful in conjunction
--   with the <tt>ViewPatterns</tt> extension.
viewLoc :: Located a -> (Point (V a), a)

-- | Project the value of type <tt>a</tt> out of a <tt>Located a</tt>,
--   discarding the location.
unLoc :: Located a -> a

-- | Project out the location of a <tt>Located</tt> value.
loc :: Located a -> Point (V a)

-- | <a>Located</a> is not a <tt>Functor</tt>, since changing the type
--   could change the type of the associated vector space, in which case
--   the associated location would no longer have the right type.
--   <a>mapLoc</a> has an extra constraint specifying that the vector space
--   must stay the same.
--   
--   (Technically, one can say that for every vector space <tt>v</tt>,
--   <tt>Located</tt> is a little-f (endo)functor on the category of types
--   with associated vector space <tt>v</tt>; but that is not covered by
--   the standard <tt>Functor</tt> class.)
mapLoc :: V a ~ V b => (a -> b) -> Located a -> Located b

-- | A lens giving access to the object within a <a>Located</a> wrapper.
located :: V a ~ V a' => Lens (Located a) (Located a') a a'
instance (Show (V a), Show a) => Show (Located a)
instance (Ord (V a), Ord a) => Ord (Located a)
instance (Eq (V a), Eq a) => Eq (Located a)
instance (Codomain a ~ V a, AdditiveGroup (V a), Fractional (Scalar (V a)), HasArcLength a) => HasArcLength (Located a)
instance (Codomain a ~ V a, Fractional (Scalar (V a)), AdditiveGroup (V a), Sectionable a, Parametric a) => Sectionable (Located a)
instance (Codomain a ~ V a, AdditiveGroup (V a), EndValues a) => EndValues (Located a)
instance DomainBounds a => DomainBounds (Located a)
instance (Codomain a ~ V a, AdditiveGroup (V a), Parametric a) => Parametric (Located a)
instance Qualifiable a => Qualifiable (Located a)
instance Traced a => Traced (Located a)
instance Enveloped a => Juxtaposable (Located a)
instance Enveloped a => Enveloped (Located a)
instance Transformable a => Transformable (Located a)
instance VectorSpace (V a) => HasOrigin (Located a)


-- | A <i>segment</i> is a translation-invariant, atomic path. Currently,
--   there are two types: linear (<i>i.e.</i> just a straight line to the
--   endpoint) and cubic Bézier curves (<i>i.e.</i> a curve to an endpoint
--   with two control points). This module contains tools for creating and
--   manipulating segments, as well as a definition of segments with a
--   fixed location (useful for backend implementors).
--   
--   Generally speaking, casual users of diagrams should not need this
--   module; the higher-level functionality provided by
--   <a>Diagrams.Trail</a>, <a>Diagrams.TrailLike</a>, and
--   <a>Diagrams.Path</a> should usually suffice. However, directly
--   manipulating segments can occasionally be useful.
module Diagrams.Segment

-- | Type tag for open segments.
data Open

-- | Type tag for closed segments.
data Closed

-- | The <i>offset</i> of a segment is the vector from its starting point
--   to its end. The offset for an <i>open</i> segment is determined by the
--   context, <i>i.e.</i> its endpoint is not fixed. The offset for a
--   <i>closed</i> segment is stored explicitly, <i>i.e.</i> its endpoint
--   is at a fixed offset from its start.
data Offset c v
OffsetOpen :: Offset Open v
OffsetClosed :: !v -> Offset Closed v

-- | Compute the offset from the start of a segment to the end. Note that
--   in the case of a Bézier segment this is <i>not</i> the same as the
--   length of the curve itself; for that, see <a>arcLength</a>.
segOffset :: Segment Closed v -> v

-- | The atomic constituents of the concrete representation currently used
--   for trails are <i>segments</i>, currently limited to single straight
--   lines or cubic Bézier curves. Segments are <i>translationally
--   invariant</i>, that is, they have no particular "location" and are
--   unaffected by translations. They are, however, affected by other
--   transformations such as rotations and scales.
data Segment c v

-- | A linear segment with given offset.
Linear :: !(Offset c v) -> Segment c v

-- | A cubic Bézier segment specified by three offsets from the starting
--   point to the first control point, second control point, and ending
--   point, respectively.
Cubic :: !v -> !v -> !(Offset c v) -> Segment c v

-- | <tt><a>straight</a> v</tt> constructs a translationally invariant
--   linear segment with direction and length given by the vector
--   <tt>v</tt>.
straight :: v -> Segment Closed v

-- | <tt>bezier3 c1 c2 x</tt> constructs a translationally invariant cubic
--   Bézier curve where the offsets from the first endpoint to the first
--   and second control point and endpoint are respectively given by
--   <tt>c1</tt>, <tt>c2</tt>, and <tt>x</tt>.
bezier3 :: v -> v -> v -> Segment Closed v

-- | <tt>bézier3</tt> is the same as <tt>bezier3</tt>, but with more
--   snobbery.
bézier3 :: v -> v -> v -> Segment Closed v

-- | Reverse the direction of a segment.
reverseSegment :: AdditiveGroup v => Segment Closed v -> Segment Closed v

-- | <tt>FixedSegment</tt>s are like <a>Segment</a>s except that they have
--   absolute locations. <tt>FixedSegment v</tt> is isomorphic to
--   <tt>Located (Segment Closed v)</tt>, as witnessed by <a>mkFixedSeg</a>
--   and <a>fromFixedSeg</a>, but <tt>FixedSegment</tt> is convenient when
--   one needs the absolute locations of the vertices and control points.
data FixedSegment v
FLinear :: (Point v) -> (Point v) -> FixedSegment v
FCubic :: (Point v) -> (Point v) -> (Point v) -> (Point v) -> FixedSegment v

-- | Create a <a>FixedSegment</a> from a located <a>Segment</a>.
mkFixedSeg :: AdditiveGroup v => Located (Segment Closed v) -> FixedSegment v

-- | Convert a <a>FixedSegment</a> back into a located <a>Segment</a>.
fromFixedSeg :: AdditiveGroup v => FixedSegment v -> Located (Segment Closed v)

-- | A type to track the count of segments in a <tt>Trail</tt>.
newtype SegCount
SegCount :: (Sum Int) -> SegCount

-- | A type to represent the total arc length of a chain of segments. The
--   first component is a "standard" arc length, computed to within a
--   tolerance of <tt>10e-6</tt>. The second component is a generic arc
--   length function taking the tolerance as an argument.
newtype ArcLength v
ArcLength :: (Sum (Interval (Scalar v)), Scalar v -> Sum (Interval (Scalar v))) -> ArcLength v

-- | Project out the cached arc length, stored together with error bounds.
getArcLengthCached :: ArcLength v -> Interval (Scalar v)

-- | Project out the generic arc length function taking the tolerance as an
--   argument.
getArcLengthFun :: ArcLength v -> Scalar v -> Interval (Scalar v)

-- | Given a specified tolerance, project out the cached arc length if it
--   is accurate enough; otherwise call the generic arc length function
--   with the given tolerance.
getArcLengthBounded :: (Num (Scalar v), Ord (Scalar v)) => Scalar v -> ArcLength v -> Interval (Scalar v)

-- | A type to represent the total cumulative offset of a chain of
--   segments.
newtype TotalOffset v
TotalOffset :: v -> TotalOffset v

-- | A type to represent the offset and envelope of a chain of segments.
--   They have to be paired into one data structure, since combining the
--   envelopes of two consecutive chains needs to take the offset of the
--   the offset of the first into account.
data OffsetEnvelope v
OffsetEnvelope :: !(TotalOffset v) -> Envelope v -> OffsetEnvelope v
_oeOffset :: OffsetEnvelope v -> !(TotalOffset v)
_oeEnvelope :: OffsetEnvelope v -> Envelope v
oeOffset :: Lens' (OffsetEnvelope v_a10hw) (TotalOffset v_a10hw)
oeEnvelope :: Lens' (OffsetEnvelope v_a10hw) (Envelope v_a10hw)

-- | <tt>SegMeasure</tt> collects up all the measurements over a chain of
--   segments.
type SegMeasure v = SegCount ::: (ArcLength v ::: (OffsetEnvelope v ::: ()))
instance (OrderedField (Scalar v), InnerSpace v) => Measured (SegMeasure v) (Segment Closed v)
instance (InnerSpace v, OrderedField (Scalar v)) => Measured (SegMeasure v) (SegMeasure v)
instance (InnerSpace v, OrderedField (Scalar v)) => Semigroup (OffsetEnvelope v)
instance (Num (Scalar v), Ord (Scalar v)) => Monoid (ArcLength v)
instance (Num (Scalar v), Ord (Scalar v)) => Semigroup (ArcLength v)
instance Ord v => Ord (Offset c v)
instance Eq v => Eq (Offset c v)
instance Show v => Show (Offset c v)
instance Show v => Show (Segment c v)
instance Functor (Segment c)
instance Eq v => Eq (Segment c v)
instance Ord v => Ord (Segment c v)
instance Show v => Show (FixedSegment v)
instance Semigroup SegCount
instance Monoid SegCount
instance AdditiveGroup v => Monoid (TotalOffset v)
instance AdditiveGroup v => Semigroup (TotalOffset v)
instance Rewrapped (TotalOffset v) (TotalOffset v')
instance Wrapped (TotalOffset v)
instance Rewrapped (ArcLength v) (ArcLength v')
instance Wrapped (ArcLength v)
instance Rewrapped SegCount SegCount
instance Wrapped SegCount
instance (VectorSpace v, Fractional (Scalar v)) => Sectionable (FixedSegment v)
instance (VectorSpace v, Num (Scalar v)) => EndValues (FixedSegment v)
instance Num (Scalar v) => DomainBounds (FixedSegment v)
instance VectorSpace v => Parametric (FixedSegment v)
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (FixedSegment v)
instance VectorSpace v => HasOrigin (FixedSegment v)
instance HasLinearMap v => Transformable (FixedSegment v)
instance (InnerSpace v, Floating (Scalar v), Ord (Scalar v), AdditiveGroup v) => HasArcLength (Segment Closed v)
instance (VectorSpace v, Fractional (Scalar v)) => Sectionable (Segment Closed v)
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Segment Closed v)
instance (VectorSpace v, Num (Scalar v)) => EndValues (Segment Closed v)
instance Num (Scalar v) => DomainBounds (Segment Closed v)
instance (VectorSpace v, Num (Scalar v)) => Parametric (Segment Closed v)
instance HasLinearMap v => Renderable (Segment c v) NullBackend
instance HasLinearMap v => Transformable (Segment c v)
instance HasLinearMap v => Transformable (Offset c v)
instance Functor (Offset c)


-- | This module defines <i>trails</i>, translationally invariant paths
--   through space. Trails form a central part of the diagrams-lib API, so
--   the documentation for this module merits careful study.
--   
--   Related modules include:
--   
--   <ul>
--   <li>The <tt>TrailLike</tt> class (<a>Diagrams.TrailLike</a>) exposes a
--   generic API for building a wide range of things out of trails.</li>
--   <li><tt>Path</tt>s (<a>Diagrams.Path</a>) are collections of
--   <a>Located</a> (<a>Diagrams.Located</a>) trails.</li>
--   <li>Trails are composed of <a>Segment</a>s (see
--   <a>Diagrams.Segment</a>), though most users should not need to work
--   with segments directly.</li>
--   </ul>
module Diagrams.Trail

-- | Intuitively, a trail is a single, continuous path through space.
--   However, a trail has no fixed starting point; it merely specifies
--   <i>how</i> to move through space, not <i>where</i>. For example, "take
--   three steps forward, then turn right twenty degrees and take two more
--   steps" is an intuitive analog of a trail; these instructions specify a
--   path through space from any given starting location. To be precise,
--   trails are <i>translation-invariant</i>; applying a translation to a
--   trail has no effect.
--   
--   A <tt><a>Located</a> Trail</tt>, on the other hand, is a trail paired
--   with some concrete starting location ("start at the big tree on the
--   corner, then take three steps forward, ..."). See the
--   <a>Diagrams.Located</a> module for help working with <a>Located</a>
--   values.
--   
--   Formally, the semantics of a trail is a continuous (though not
--   necessarily differentiable) function from the real interval [0,1] to
--   vectors in some vector space. (In contrast, a <a>Located</a> trail is
--   a continuous function from [0,1] to <i>points</i> in some
--   <i>affine</i> space.)
--   
--   There are two types of trails:
--   
--   <ul>
--   <li>A "line" (think of the "train", "subway", or "bus" variety, rather
--   than the "straight" variety...) is a trail with two distinct
--   endpoints. Actually, a line can have the same start and end points,
--   but it is still <i>drawn</i> as if it had distinct endpoints: the two
--   endpoints will have the appropriate end caps, and the trail will not
--   be filled. Lines have a <tt>Monoid</tt> instance where
--   <tt>mappend</tt> corresponds to concatenation, <i>i.e.</i> chaining
--   one line after the other.</li>
--   <li>A "loop" is required to end in the same place it starts (that is,
--   t(0) = t(1)). Loops are filled and are drawn as one continuous loop,
--   with the appropriate join at the start/endpoint rather than end caps.
--   Loops do not have a <tt>Monoid</tt> instance.</li>
--   </ul>
--   
--   To convert between lines and loops, see <a>glueLine</a>,
--   <a>closeLine</a>, and <a>cutLoop</a>.
--   
--   To construct trails, see <a>emptyTrail</a>, <a>trailFromSegments</a>,
--   <a>trailFromVertices</a>, <a>trailFromOffsets</a>, and friends. You
--   can also get any type of trail from any function which returns a
--   <tt>TrailLike</tt> (<i>e.g.</i> functions in
--   <a>Diagrams.TwoD.Shapes</a>, and many others; see
--   <a>Diagrams.TrailLike</a>).
--   
--   To extract information from trails, see <a>withLine</a>,
--   <a>isLoop</a>, <a>trailSegments</a>, <a>trailOffsets</a>,
--   <a>trailVertices</a>, and friends.
data Trail' l v
Line :: SegTree v -> Trail' Line v
Loop :: SegTree v -> Segment Open v -> Trail' Loop v

-- | Make a line into a loop by "gluing" the endpoint to the starting
--   point. In particular, the offset of the final segment is modified so
--   that it ends at the starting point of the entire trail. Typically, you
--   would first construct a line which you know happens to end where it
--   starts, and then call <a>glueLine</a> to turn it into a loop.
--   
--   
--   <pre>
--   glueLineEx = pad 1.1 . hcat' (with &amp; sep .~ 1)
--     $ [almostClosed # strokeLine, almostClosed # glueLine # strokeLoop]
--   
--   almostClosed :: Trail' Line R2
--   almostClosed = fromOffsets $ map r2 [(2, -1), (-3, -0.5), (-2, 1), (1, 0.5)]
--   </pre>
--   
--   <tt>glueLine</tt> is left inverse to <a>cutLoop</a>, that is,
--   
--   <pre>
--   glueLine . cutLoop === id
--   </pre>
glueLine :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Line v -> Trail' Loop v

-- | Make a line into a loop by adding a new linear segment from the line's
--   end to its start.
--   
--   <tt>closeLine</tt> does not have any particularly nice theoretical
--   properties, but can be useful <i>e.g.</i> when you want to make a
--   closed polygon out of a list of points where the initial point is not
--   repeated at the end. To use <a>glueLine</a>, one would first have to
--   duplicate the initial vertex, like
--   
--   <pre>
--   <a>glueLine</a> . <a>lineFromVertices</a> $ ps ++ [head ps]
--   </pre>
--   
--   Using <tt>closeLine</tt>, however, one can simply
--   
--   <pre>
--   closeLine . lineFromVertices $ ps
--   </pre>
--   
--   
--   <pre>
--   closeLineEx = pad 1.1 . centerXY . hcat' (with &amp; sep .~ 1)
--     $ [almostClosed # strokeLine, almostClosed # closeLine # strokeLoop]
--   </pre>
closeLine :: Trail' Line v -> Trail' Loop v

-- | Turn a loop into a line by "cutting" it at the common start/end point,
--   resulting in a line which just happens to start and end at the same
--   place.
--   
--   <tt>cutLoop</tt> is right inverse to <a>glueLine</a>, that is,
--   
--   <pre>
--   glueLine . cutLoop === id
--   </pre>
cutLoop :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Loop v -> Trail' Line v

-- | <tt>Trail</tt> is a wrapper around <tt>Trail'</tt>, hiding whether the
--   underlying <tt>Trail'</tt> is a line or loop (though which it is can
--   be recovered; see <i>e.g.</i> <a>withTrail</a>).
data Trail v
Trail :: Trail' l v -> Trail v

-- | Convert a <a>Trail'</a> into a <a>Trail</a>, hiding the type-level
--   distinction between lines and loops.
wrapTrail :: Trail' l v -> Trail v

-- | Convert a line into a <a>Trail</a>. This is the same as
--   <a>wrapTrail</a>, but with a more specific type, which can
--   occasionally be convenient for fixing the type of a polymorphic
--   expression.
wrapLine :: Trail' Line v -> Trail v

-- | Convert a loop into a <a>Trail</a>. This is the same as
--   <a>wrapTrail</a>, but with a more specific type, which can
--   occasionally be convenient for fixing the type of a polymorphic
--   expression.
wrapLoop :: Trail' Loop v -> Trail v

-- | Modify a <tt>Trail</tt>, specifying two separate transformations for
--   the cases of a line or a loop.
onTrail :: (Trail' Line v -> Trail' l1 v) -> (Trail' Loop v -> Trail' l2 v) -> (Trail v -> Trail v)

-- | Modify a <tt>Trail</tt> by specifying a transformation on lines. If
--   the trail is a line, the transformation will be applied directly. If
--   it is a loop, it will first be cut using <a>cutLoop</a>, the
--   transformation applied, and then glued back into a loop with
--   <a>glueLine</a>. That is,
--   
--   <pre>
--   onLine f === onTrail f (glueLine . f . cutLoop)
--   </pre>
--   
--   Note that there is no corresponding <tt>onLoop</tt> function, because
--   there is no nice way in general to convert a line into a loop, operate
--   on it, and then convert back.
onLine :: (InnerSpace v, OrderedField (Scalar v)) => (Trail' Line v -> Trail' Line v) -> Trail v -> Trail v

-- | <tt>glueTrail</tt> is a variant of <a>glueLine</a> which works on
--   <a>Trail</a>s. It performs <a>glueLine</a> on lines and is the
--   identity on loops.
glueTrail :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> Trail v

-- | <tt>closeTrail</tt> is a variant of <a>closeLine</a> for <a>Trail</a>,
--   which performs <a>closeLine</a> on lines and is the identity on loops.
closeTrail :: Trail v -> Trail v

-- | <tt>cutTrail</tt> is a variant of <a>cutLoop</a> for <a>Trail</a>; it
--   is the is the identity on lines and performs <a>cutLoop</a> on loops.
cutTrail :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> Trail v

-- | The empty line, which is the identity for concatenation of lines.
emptyLine :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Line v

-- | A wrapped variant of <a>emptyLine</a>.
emptyTrail :: (InnerSpace v, OrderedField (Scalar v)) => Trail v

-- | Construct a line containing only linear segments from a list of
--   vertices. Note that only the relative offsets between the vertices
--   matters; the information about their absolute position will be
--   discarded. That is, for all vectors <tt>v</tt>,
--   
--   <pre>
--   lineFromVertices === lineFromVertices . <a>translate</a> v
--   </pre>
--   
--   If you want to retain the position information, you should instead use
--   the more general <tt>fromVertices</tt> function to construct, say, a
--   <tt><a>Located</a> (<a>Trail'</a> <a>Line</a> v)</tt> or a
--   <tt><a>Located</a> (<a>Trail</a> v)</tt>.
--   
--   
--   <pre>
--   import Diagrams.Coordinates
--   lineFromVerticesEx = pad 1.1 . centerXY . strokeLine
--     $ lineFromVertices [origin, 0 ^&amp; 1, 1 ^&amp; 2, 5 ^&amp; 1]
--   </pre>
lineFromVertices :: (InnerSpace v, OrderedField (Scalar v)) => [Point v] -> Trail' Line v

-- | <tt>trailFromVertices === <a>wrapTrail</a> .
--   <a>lineFromVertices</a></tt>, for conveniently constructing a
--   <tt>Trail</tt> instead of a <tt>Trail' Line</tt>.
trailFromVertices :: (InnerSpace v, OrderedField (Scalar v)) => [Point v] -> Trail v

-- | Construct a line containing only linear segments from a list of
--   vectors, where each vector represents the offset from one vertex to
--   the next. See also <tt>fromOffsets</tt>.
--   
--   
--   <pre>
--   import Diagrams.Coordinates
--   lineFromOffsetsEx = strokeLine $ lineFromOffsets [ 2 ^&amp; 1, 2 ^&amp; (-1), 2 ^&amp; 0.5 ]
--   </pre>
lineFromOffsets :: (InnerSpace v, OrderedField (Scalar v)) => [v] -> Trail' Line v

-- | <tt>trailFromOffsets === <a>wrapTrail</a> .
--   <a>lineFromOffsets</a></tt>, for conveniently constructing a
--   <tt>Trail</tt> instead of a <tt>Trail' Line</tt>.
trailFromOffsets :: (InnerSpace v, OrderedField (Scalar v)) => [v] -> Trail v

-- | Construct a line from a list of closed segments.
lineFromSegments :: (InnerSpace v, OrderedField (Scalar v)) => [Segment Closed v] -> Trail' Line v

-- | <tt>trailFromSegments === <a>wrapTrail</a> .
--   <a>lineFromSegments</a></tt>, for conveniently constructing a
--   <tt>Trail</tt> instead of a <tt>Trail'</tt>.
trailFromSegments :: (InnerSpace v, OrderedField (Scalar v)) => [Segment Closed v] -> Trail v

-- | A generic eliminator for <a>Trail'</a>, taking functions specifying
--   what to do in the case of a line or a loop.
withTrail' :: (Trail' Line v -> r) -> (Trail' Loop v -> r) -> Trail' l v -> r

-- | A generic eliminator for <a>Trail</a>, taking functions specifying
--   what to do in the case of a line or a loop.
withTrail :: (Trail' Line v -> r) -> (Trail' Loop v -> r) -> Trail v -> r

-- | An eliminator for <tt>Trail</tt> based on eliminating lines: if the
--   trail is a line, the given function is applied; if it is a loop, it is
--   first converted to a line with <a>cutLoop</a>. That is,
--   
--   <pre>
--   withLine f === <a>withTrail</a> f (f . <a>cutLoop</a>)
--   </pre>
withLine :: (InnerSpace v, OrderedField (Scalar v)) => (Trail' Line v -> r) -> Trail v -> r

-- | Test whether a line is empty.
isLineEmpty :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Line v -> Bool

-- | Test whether a trail is empty. Note that loops are never empty.
isTrailEmpty :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> Bool

-- | Determine whether a trail is a line.
isLine :: Trail v -> Bool

-- | Determine whether a trail is a loop.
isLoop :: Trail v -> Bool

-- | Extract the segments of a trail. If the trail is a loop it will first
--   have <a>cutLoop</a> applied.
trailSegments :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> [Segment Closed v]

-- | Extract the segments comprising a line.
lineSegments :: Trail' Line v -> [Segment Closed v]

-- | Extract the segments comprising a loop: a list of closed segments, and
--   one final open segment.
loopSegments :: Trail' Loop v -> ([Segment Closed v], Segment Open v)

-- | Modify a line by applying a function to its list of segments.
onLineSegments :: (InnerSpace v, OrderedField (Scalar v)) => ([Segment Closed v] -> [Segment Closed v]) -> Trail' Line v -> Trail' Line v

-- | Extract the offsets of the segments of a trail.
trailOffsets :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> [v]

-- | Compute the offset from the start of a trail to the end. Satisfies
--   
--   <pre>
--   trailOffset === sumV . trailOffsets
--   </pre>
--   
--   but is more efficient.
--   
--   
--   <pre>
--   trailOffsetEx = (strokeLine almostClosed &lt;&gt; showOffset) # centerXY # pad 1.1
--     where showOffset = fromOffsets [trailOffset (wrapLine almostClosed)]
--                      # stroke # lc red
--   </pre>
trailOffset :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> v

-- | Extract the offsets of the segments of a line.
lineOffsets :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Line v -> [v]

-- | Compute the offset from the start of a line to the end. (Note, there
--   is no corresponding <tt>loopOffset</tt> function because by definition
--   it would be constantly zero.)
lineOffset :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Line v -> v

-- | Extract the offsets of the segments of a loop.
loopOffsets :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Loop v -> [v]

-- | Extract the vertices of a concretely located trail. Note that for
--   loops, the starting vertex will <i>not</i> be repeated at the end. If
--   you want this behavior, you can use <a>cutTrail</a> to make the loop
--   into a line first, which happens to repeat the same vertex at the
--   start and end, <i>e.g.</i> with <tt>trailVertices . mapLoc
--   cutTrail</tt>.
--   
--   Note that it does not make sense to ask for the vertices of a
--   <a>Trail</a> by itself; if you want the vertices of a trail with the
--   first vertex at, say, the origin, you can use <tt>trailVertices .
--   (`at` origin)</tt>.
trailVertices :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail v) -> [Point v]

-- | Extract the vertices of a concretely located line. See
--   <a>trailVertices</a> for more information.
lineVertices :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail' Line v) -> [Point v]

-- | Extract the vertices of a concretely located loop. Note that the
--   initial vertex is not repeated at the end. See <a>trailVertices</a>
--   for more information.
loopVertices :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail' Loop v) -> [Point v]

-- | Convert a concretely located trail into a list of located segments.
trailLocSegments :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail v) -> [Located (Segment Closed v)]

-- | Convert a concretely located trail into a list of fixed segments.
fixTrail :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail v) -> [FixedSegment v]

-- | Reverse a trail. Semantically, if a trail given by a function t from
--   [0,1] to vectors, then the reverse of t is given by t'(s) = t(1-s).
--   <tt>reverseTrail</tt> is an involution, that is,
--   
--   <pre>
--   reverseTrail . reverseTrail === id
--   </pre>
reverseTrail :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> Trail v

-- | Reverse a concretely located trail. The endpoint of the original trail
--   becomes the starting point of the reversed trail, so the original and
--   reversed trails comprise exactly the same set of points.
--   <tt>reverseLocTrail</tt> is an involution, <i>i.e.</i>
--   
--   <pre>
--   reverseLocTrail . reverseLocTrail === id
--   </pre>
reverseLocTrail :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail v) -> Located (Trail v)

-- | Reverse a line. See <a>reverseTrail</a>.
reverseLine :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Line v -> Trail' Line v

-- | Reverse a concretely located line. See <a>reverseLocTrail</a>.
reverseLocLine :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail' Line v) -> Located (Trail' Line v)

-- | Reverse a loop. See <a>reverseTrail</a>.
reverseLoop :: (InnerSpace v, OrderedField (Scalar v)) => Trail' Loop v -> Trail' Loop v

-- | Reverse a concretely located loop. See <a>reverseLocTrail</a>. Note
--   that this is guaranteed to preserve the location.
reverseLocLoop :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail' Loop v) -> Located (Trail' Loop v)

-- | Type tag for trails with distinct endpoints.
data Line

-- | Type tag for "loopy" trails which return to their starting point.
data Loop

-- | A <tt>SegTree</tt> represents a sequence of closed segments, stored in
--   a fingertree so we can easily recover various monoidal measures of the
--   segments (number of segments, arc length, envelope...) and also easily
--   slice and dice them according to the measures (<i>e.g.</i>, split off
--   the smallest number of segments from the beginning which have a
--   combined arc length of at least 5).
newtype SegTree v
SegTree :: (FingerTree (SegMeasure v) (Segment Closed v)) -> SegTree v

-- | Given a default result (to be used in the case of an empty trail), and
--   a function to map a single measure to a result, extract the given
--   measure for a trail and use it to compute a result. Put another way,
--   lift a function on a single measure (along with a default value) to a
--   function on an entire trail.
trailMeasure :: (InnerSpace v, OrderedField (Scalar v), SegMeasure v :>: m, Measured (SegMeasure v) t) => a -> (m -> a) -> t -> a

-- | Compute the number of segments of anything measured by
--   <a>SegMeasure</a> (<i>e.g.</i> <tt>SegMeasure</tt> itself,
--   <tt>Segment</tt>, <tt>SegTree</tt>, <tt>Trail</tt>s...)
numSegs :: (Floating (Scalar v), Num c, Ord (Scalar v), InnerSpace v, Measured (SegMeasure v) a) => a -> c

-- | Compute the total offset of anything measured by <a>SegMeasure</a>.
offset :: (Floating (Scalar v), Ord (Scalar v), InnerSpace v, Measured (SegMeasure v) t) => t -> v

-- | A newtype wrapper around trails which exists solely for its
--   <a>Parametric</a>, <a>DomainBounds</a> and <a>EndValues</a> instances.
--   The idea is that if <tt>tr</tt> is a trail, you can write, <i>e.g.</i>
--   
--   <pre>
--   getSegment tr <a>atParam</a> 0.6
--   </pre>
--   
--   or
--   
--   <pre>
--   atStart (getSegment tr)
--   </pre>
--   
--   to get the segment at parameter 0.6 or the first segment in the trail,
--   respectively.
--   
--   The codomain for <a>GetSegment</a>, <i>i.e.</i> the result you get
--   from calling <a>atParam</a>, <a>atStart</a>, or <a>atEnd</a>, is
--   <tt>Maybe (v, Segment Closed v, AnIso' (Scalar v) (Scalar v))</tt>.
--   <tt>Nothing</tt> results if the trail is empty; otherwise, you get:
--   
--   <ul>
--   <li>the offset from the start of the trail to the beginning of the
--   segment,</li>
--   <li>the segment itself, and</li>
--   <li>a reparameterization isomorphism: in the forward direction, it
--   translates from parameters on the whole trail to a parameters on the
--   segment. Note that for technical reasons you have to call
--   <tt>cloneIso</tt> on the <tt>AnIso'</tt> value to get a real
--   isomorphism you can use.</li>
--   </ul>
newtype GetSegment t
GetSegment :: t -> GetSegment t

-- | Create a <a>GetSegment</a> wrapper around a trail, after which you can
--   call <a>atParam</a>, <a>atStart</a>, or <a>atEnd</a> to extract a
--   segment.
getSegment :: t -> GetSegment t
instance Show v => Show (Trail v)
instance Ord v => Ord (Trail' l v)
instance Eq v => Eq (Trail' l v)
instance Show v => Show (Trail' l v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Transformable (SegTree v)
instance (OrderedField (Scalar v), InnerSpace v) => Measured (SegMeasure v) (SegTree v)
instance (OrderedField (Scalar v), InnerSpace v) => Monoid (SegTree v)
instance Eq v => Eq (SegTree v)
instance Ord v => Ord (SegTree v)
instance Show v => Show (SegTree v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => HasArcLength (Trail v)
instance (InnerSpace v, RealFrac (Scalar v), Floating (Scalar v)) => Sectionable (Trail v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => EndValues (Trail v)
instance Num (Scalar v) => DomainBounds (Trail v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (Trail v)
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Trail v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Transformable (Trail v)
instance (OrderedField (Scalar v), InnerSpace v) => Monoid (Trail v)
instance (OrderedField (Scalar v), InnerSpace v) => Semigroup (Trail v)
instance Ord v => Ord (Trail v)
instance Eq v => Eq (Trail v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => EndValues (GetSegment (Trail v))
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => EndValues (GetSegment (Trail' Loop v))
instance (InnerSpace v, OrderedField (Scalar v)) => EndValues (GetSegment (Trail' Line v))
instance DomainBounds t => DomainBounds (GetSegment t)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (GetSegment (Trail v))
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (GetSegment (Trail' Loop v))
instance (InnerSpace v, OrderedField (Scalar v)) => Parametric (GetSegment (Trail' Line v))
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => HasArcLength (Trail' l v)
instance (InnerSpace v, RealFrac (Scalar v), Floating (Scalar v)) => Sectionable (Trail' Line v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => EndValues (Trail' l v)
instance Num (Scalar v) => DomainBounds (Trail' l v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (Trail' l v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Renderable (Trail' o v) NullBackend
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Trail' l v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Transformable (Trail' l v)
instance (OrderedField (Scalar v), InnerSpace v) => Monoid (Trail' Line v)
instance (OrderedField (Scalar v), InnerSpace v) => Semigroup (Trail' Line v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => HasArcLength (SegTree v)
instance (InnerSpace v, RealFrac (Scalar v), Floating (Scalar v)) => Sectionable (SegTree v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v), Num (Scalar v)) => EndValues (SegTree v)
instance Num (Scalar v) => DomainBounds (SegTree v)
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (SegTree v)
instance Rewrapped (SegTree v) (SegTree v')
instance Wrapped (SegTree v)
instance (HasLinearMap (V a), InnerSpace (V a), OrderedField (Scalar (V a)), Measured m a, Transformable a) => Transformable (FingerTree m a)


-- | Computing tangent and normal vectors for segments and trails.
module Diagrams.Tangent

-- | Compute the tangent vector to a segment or trail at a particular
--   parameter.
--   
--   Examples of more specific types this function can have include
--   
--   <ul>
--   <li><pre>Segment Closed R2 -&gt; Double -&gt; R2</pre></li>
--   <li><pre>Trail' Line R2 -&gt; Double -&gt; R2</pre></li>
--   <li><pre>Located (Trail R2) -&gt; Double -&gt; R2</pre></li>
--   </ul>
--   
--   See the instances listed for the <a>Tangent</a> newtype for more.
tangentAtParam :: Parametric (Tangent t) => t -> Scalar (V t) -> Codomain (Tangent t)

-- | Compute the tangent vector at the start of a segment or trail.
tangentAtStart :: EndValues (Tangent t) => t -> Codomain (Tangent t)

-- | Compute the tangent vector at the end of a segment or trail.
tangentAtEnd :: EndValues (Tangent t) => t -> Codomain (Tangent t)

-- | Compute the (unit) normal vector to a segment or trail at a particular
--   parameter.
--   
--   Examples of more specific types this function can have include
--   
--   <ul>
--   <li><pre>Segment Closed R2 -&gt; Double -&gt; R2</pre></li>
--   <li><pre>Trail' Line R2 -&gt; Double -&gt; R2</pre></li>
--   <li><pre>Located (Trail R2) -&gt; Double -&gt; P2</pre></li>
--   </ul>
--   
--   See the instances listed for the <a>Tangent</a> newtype for more.
normalAtParam :: (Codomain (Tangent t) ~ R2, Parametric (Tangent t)) => t -> Scalar (V t) -> R2

-- | Compute the normal vector at the start of a segment or trail.
normalAtStart :: (Codomain (Tangent t) ~ R2, EndValues (Tangent t)) => t -> R2

-- | Compute the normal vector at the end of a segment or trail.
normalAtEnd :: (Codomain (Tangent t) ~ R2, EndValues (Tangent t)) => t -> R2

-- | A newtype wrapper used to give different instances of
--   <a>Parametric</a> and <a>EndValues</a> that compute tangent vectors.
newtype Tangent t
Tangent :: t -> Tangent t
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => EndValues (Tangent (Trail v))
instance (InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (Tangent (Trail v))
instance (Parametric (GetSegment (Trail' c v)), EndValues (GetSegment (Trail' c v)), VectorSpace v, Num (Scalar v)) => EndValues (Tangent (Trail' c v))
instance (Parametric (GetSegment (Trail' c v)), VectorSpace v, Num (Scalar v)) => Parametric (Tangent (Trail' c v))
instance (VectorSpace v, Num (Scalar v)) => EndValues (Tangent (Segment Closed v))
instance (VectorSpace v, Num (Scalar v)) => Parametric (Tangent (Segment Closed v))
instance (DomainBounds t, EndValues (Tangent t)) => EndValues (Tangent (Located t))
instance Parametric (Tangent t) => Parametric (Tangent (Located t))
instance DomainBounds t => DomainBounds (Tangent t)


-- | Compute curvature for segments in two dimensions.
module Diagrams.TwoD.Curvature

-- | Curvature measures how curved the segment is at a point. One intuition
--   for the concept is how much you would turn the wheel when driving a
--   car along the curve. When the wheel is held straight there is zero
--   curvature. When turning a corner to the left we will have positive
--   curvature. When turning to the right we will have negative curvature.
--   
--   Another way to measure this idea is to find the largest circle that we
--   can push up against the curve and have it touch (locally) at exactly
--   the point and not cross the curve. This is a tangent circle. The
--   radius of that circle is the "Radius of Curvature" and it is the
--   reciprocal of curvature. Note that if the circle is on the "left" of
--   the curve, we have a positive radius, and if it is to the right we
--   have a negative radius. Straight segments have an infinite radius
--   which leads us to our representation. We result in a pair of numerator
--   and denominator so we can include infinity and zero for both the
--   radius and the curvature.
--   
--   Lets consider the following curve:
--   
--   
--   The curve starts with positive curvature,
--   
--   
--   approaches zero curvature
--   
--   
--   then has negative curvature
--   
--   
--   <pre>
--   {-# LANGUAGE GADTs #-}
--   
--   import Diagrams.TwoD.Curvature
--   import Data.Monoid.Inf
--   import Diagrams.Coordinates
--   
--   segmentA = Cubic (12 ^&amp; 0) (8 ^&amp; 10) (OffsetClosed (20 ^&amp; 8))
--   
--   curveA = lw thick . stroke . fromSegments $ [segmentA]
--   
--   diagramA = pad 1.1 . centerXY $ curveA
--   
--   diagramPos = diagramWithRadius 0.2
--   
--   diagramZero = diagramWithRadius 0.45
--   
--   diagramNeg = diagramWithRadius 0.8
--   
--   diagramWithRadius t = pad 1.1 . centerXY
--            $ curveA
--           &lt;&gt; showCurvature segmentA t
--            # withEnvelope (curveA :: D R2)
--            # lc red
--   
--   showCurvature bez@(Cubic b c (OffsetClosed d)) t
--     | v == (0,0) = mempty
--     | otherwise  = go (radiusOfCurvature bez t)
--     where
--       v@(x,y) = unr2 $ firstDerivative b c d t
--       vp = (-y) ^&amp; x
--   
--       firstDerivative b c d t = let tt = t*t in (3*(3*tt-4*t+1))*^b + (3*(2-3*t)*t)*^c + (3*tt)*^d
--   
--       go Infinity   = mempty
--       go (Finite r) = (circle (abs r) # translate vpr
--                    &lt;&gt; stroke (origin ~~ (origin .+^ vpr)))
--                     # moveTo (origin .+^ atParam bez t)
--         where
--           vpr = r2 (normalized vp ^* r)
--   </pre>
curvature :: Segment Closed R2 -> Double -> PosInf Double

-- | Reciprocal of <tt>curvature</tt>.
radiusOfCurvature :: Segment Closed R2 -> Double -> PosInf Double

-- | With <tt>squaredCurvature</tt> we can compute values in spaces that do
--   not support <a>sqrt</a> and it is just as useful for relative ordering
--   of curvatures or looking for zeros.
squaredCurvature :: Segment Closed R2 -> Double -> PosInf Double

-- | Reciprocal of <tt>squaredCurvature</tt>
squaredRadiusOfCurvature :: Segment Closed R2 -> Double -> PosInf Double


-- | The <a>TrailLike</a> class abstracts over anything which can be
--   constructed from a concretely located <a>Trail</a>, including lines,
--   loops, trails, paths, vertex lists, and diagrams.
module Diagrams.TrailLike

-- | A type class for trail-like things, <i>i.e.</i> things which can be
--   constructed from a concretely located <a>Trail</a>. Instances include
--   lines, loops, trails, paths, lists of vertices, two-dimensional
--   <a>Diagram</a>s, and <a>Located</a> variants of all the above.
--   
--   Usually, type variables with <a>TrailLike</a> constraints are used as
--   the <i>output</i> types of functions, like
--   
--   <pre>
--   foo :: (TrailLike t) =&gt; ... -&gt; t
--   </pre>
--   
--   Functions with such a type can be used to construct trails, paths,
--   diagrams, lists of points, and so on, depending on the context.
--   
--   To write a function with a signature like the above, you can of course
--   call <a>trailLike</a> directly; more typically, one would use one of
--   the provided functions like <a>fromOffsets</a>, <a>fromVertices</a>,
--   <a>fromSegments</a>, or <a>~~</a>.
class (InnerSpace (V t), OrderedField (Scalar (V t))) => TrailLike t
trailLike :: TrailLike t => Located (Trail (V t)) -> t

-- | Construct a trail-like thing from a list of segments, with the origin
--   as the location.
--   
--   
--   <pre>
--   fromSegmentsEx = fromSegments
--     [ straight (r2 (1,1))
--     , bézier3  (r2 (1,1)) unitX unit_Y
--     , straight unit_X
--     ]
--     # centerXY # pad 1.1
--   </pre>
fromSegments :: TrailLike t => [Segment Closed (V t)] -> t

-- | Construct a trail-like thing from a located list of segments.
fromLocSegments :: TrailLike t => Located [Segment Closed (V t)] -> t

-- | Construct a trail-like thing of linear segments from a list of
--   offsets, with the origin as the location.
--   
--   
--   <pre>
--   fromOffsetsEx = fromOffsets
--     [ unitX
--     , unitX # rotateBy (1/6)
--     , unitX # rotateBy (-1/6)
--     , unitX
--     ]
--     # centerXY # pad 1.1
--   </pre>
fromOffsets :: TrailLike t => [V t] -> t

-- | Construct a trail-like thing of linear segments from a located list of
--   offsets.
fromLocOffsets :: (V (V t) ~ V t, TrailLike t) => Located [V t] -> t

-- | Construct a trail-like thing connecting the given vertices with linear
--   segments, with the first vertex as the location. If no vertices are
--   given, the empty trail is used with the origin as the location.
--   
--   
--   <pre>
--   import Data.List (transpose)
--   
--   fromVerticesEx =
--     ( [ pentagon 1
--       , pentagon 1.3 # rotateBy (1/15)
--       , pentagon 1.5 # rotateBy (2/15)
--       ]
--       # transpose
--       # concat
--     )
--     # fromVertices
--     # closeTrail # strokeTrail
--     # centerXY # pad 1.1
--   </pre>
fromVertices :: TrailLike t => [Point (V t)] -> t

-- | Create a linear trail between two given points.
--   
--   
--   <pre>
--   twiddleEx
--     = mconcat ((~~) &lt;$&gt; hexagon 1 &lt;*&gt; hexagon 1)
--     # centerXY # pad 1.1
--   </pre>
(~~) :: TrailLike t => Point (V t) -> Point (V t) -> t

-- | Given a concretely located trail, "explode" it by turning each segment
--   into its own separate trail. Useful for (say) applying a different
--   style to each segment.
--   
--   
--   <pre>
--   explodeTrailEx
--     = pentagon 1
--     # explodeTrail  -- generate a list of diagrams
--     # zipWith lc [orange, green, yellow, red, blue]
--     # mconcat # centerXY # pad 1.1
--   </pre>
explodeTrail :: (VectorSpace (V t), TrailLike t) => Located (Trail (V t)) -> [t]
instance TrailLike t => TrailLike (Located t)
instance TrailLike t => TrailLike (TransInv t)
instance (InnerSpace v, OrderedField (Scalar v)) => TrailLike (Trail v)
instance (InnerSpace v, OrderedField (Scalar v)) => TrailLike (Trail' Loop v)
instance (InnerSpace v, OrderedField (Scalar v)) => TrailLike (Trail' Line v)
instance (InnerSpace v, OrderedField (Scalar v)) => TrailLike [Point v]


-- | A few utilities and class instances for <a>Active</a> (from the
--   <tt>active</tt> package). In particular, this module defines
--   
--   <ul>
--   <li>An instance of <a>V</a> for <a>Active</a>: <tt><a>V</a>
--   (<a>Active</a> a) = <a>V</a> a</tt></li>
--   <li><a>HasOrigin</a>, <a>Transformable</a>, and <a>HasStyle</a>
--   instances for <a>Active</a> which all work pointwise.</li>
--   <li>A <a>TrailLike</a> instance for <tt><a>Active</a> p</tt> where
--   <tt>p</tt> is also <a>TrailLike</a>, which simply lifts a pathlike
--   thing to a constant active value.</li>
--   <li>A <a>Juxtaposable</a> instance for <tt><a>Active</a> a</tt> where
--   <tt>a</tt> is also <a>Juxtaposable</a>. An active value can be
--   juxtaposed against another by doing the juxtaposition pointwise over
--   time. The era of <tt>juxtapose v a1 a2</tt> will be the same as the
--   era of <tt>a2</tt>, unless <tt>a2</tt> is constant, in which case it
--   will be the era of <tt>a1</tt>. (Note that <tt>juxtapose v a1 a2</tt>
--   and <tt>liftA2 (juxtapose v) a1 a2</tt> therefore have different
--   semantics: the second is an active value whose era is the
--   <i>combination</i> of the eras of <tt>a1</tt> and <tt>a2</tt>).</li>
--   <li>An <tt>Alignable</tt> instance for <tt><a>Active</a> a</tt> where
--   <tt>a</tt> is also <tt>Alignable</tt>; the active value is aligned
--   pointwise over time.</li>
--   </ul>
module Diagrams.Animation.Active
instance Juxtaposable a => Juxtaposable (Active a)
instance TrailLike t => TrailLike (Active t)
instance HasStyle a => HasStyle (Active a)
instance Transformable a => Transformable (Active a)
instance HasOrigin a => HasOrigin (Active a)


-- | A <i>cubic spline</i> is a smooth, connected sequence of cubic curves
--   passing through a given sequence of points. This module provides the
--   <a>cubicSpline</a> method, which can be used to create closed or open
--   cubic splines from a list of points. For access to the internals of
--   the spline generation algorithm (including in particular a solver for
--   cyclic tridiagonal systems of linear equations), see
--   <a>Diagrams.CubicSpline.Internal</a>.
module Diagrams.CubicSpline

-- | Construct a spline path-like thing of cubic segments from a list of
--   vertices, with the first vertex as the starting point. The first
--   argument specifies whether the path should be closed.
--   
--   
--   <pre>
--   pts = map p2 [(0,0), (2,3), (5,-2), (-4,1), (0,3)]
--   dot = circle 0.2 # fc blue # lw none
--   mkPath closed = position (zip pts (repeat dot))
--                &lt;&gt; cubicSpline closed pts
--   cubicSplineEx = (mkPath False ||| strutX 2 ||| mkPath True)
--                 # centerXY # pad 1.1
--   </pre>
--   
--   For more information, see
--   <a>http://mathworld.wolfram.com/CubicSpline.html</a>.
cubicSpline :: (TrailLike t, Fractional (V t)) => Bool -> [Point (V t)] -> t


-- | Two-dimensional arcs, approximated by cubic bezier curves.
module Diagrams.TwoD.Arc

-- | Given a start angle <tt>s</tt> and an end angle <tt>e</tt>,
--   <tt><a>arc</a> s e</tt> is the path of a radius one arc
--   counterclockwise between the two angles. The origin of the arc is its
--   center.
arc :: (TrailLike t, V t ~ R2) => Angle -> Angle -> t

-- | Given a radus <tt>r</tt>, a start angle <tt>s</tt> and an end angle
--   <tt>e</tt>, <tt><a>arc'</a> r s e</tt> is the path of a radius
--   <tt>(abs r)</tt> arc between the two angles. If a negative radius is
--   given, the arc will be clockwise, otherwise it will be
--   counterclockwise. The origin of the arc is its center.
--   
--   
--   <pre>
--   arc'Ex = mconcat [ arc' r (0 @@ turn) (1/4 @@ turn) | r &lt;- [0.5,-1,1.5] ]
--          # centerXY # pad 1.1
--   </pre>
arc' :: (TrailLike p, V p ~ R2) => Double -> Angle -> Angle -> p

-- | Like <a>arc</a> but clockwise.
arcCW :: (TrailLike t, V t ~ R2) => Angle -> Angle -> t

-- | Given a start angle <tt>s</tt> and an end angle <tt>e</tt>,
--   <tt><a>arcT</a> s e</tt> is the <a>Trail</a> of a radius one arc
--   counterclockwise between the two angles.
arcT :: Angle -> Angle -> Trail R2

-- | <tt>bezierFromSweep s</tt> constructs a series of <a>Cubic</a>
--   segments that start in the positive y direction and sweep counter
--   clockwise through the angle <tt>s</tt>. If <tt>s</tt> is negative, it
--   will start in the negative y direction and sweep clockwise. When
--   <tt>s</tt> is less than 0.0001 the empty list results. If the sweep is
--   greater than tau radians then it is truncated to one full revolution.
bezierFromSweep :: Angle -> [Segment Closed R2]

-- | Create a circular wedge of the given radius, beginning at the first
--   angle and extending counterclockwise to the second.
--   
--   
--   <pre>
--   wedgeEx = hcat' (with &amp; sep .~ 0.5)
--     [ wedge 1 (0 @@ turn) (1/4 @@ turn)
--     , wedge 1 (7/30 @@ turn) (11/30 @@ turn)
--     , wedge 1 (1/8 @@ turn) (7/8 @@ turn)
--     ]
--     # fc blue
--     # centerXY # pad 1.1
--   </pre>
wedge :: (TrailLike p, V p ~ R2) => Double -> Angle -> Angle -> p

-- | <tt>arcBetween p q height</tt> creates an arc beginning at <tt>p</tt>
--   and ending at <tt>q</tt>, with its midpoint at a distance of <tt>abs
--   height</tt> away from the straight line from <tt>p</tt> to <tt>q</tt>.
--   A positive value of <tt>height</tt> results in an arc to the left of
--   the line from <tt>p</tt> to <tt>q</tt>; a negative value yields one to
--   the right.
--   
--   
--   <pre>
--   arcBetweenEx = mconcat
--     [ arcBetween origin (p2 (2,1)) ht | ht &lt;- [-0.2, -0.1 .. 0.2] ]
--     # centerXY # pad 1.1
--   </pre>
arcBetween :: (TrailLike t, V t ~ R2) => P2 -> P2 -> Double -> t

-- | Create an annular wedge of the given radii, beginning at the first
--   angle and extending counterclockwise to the second. The radius of the
--   outer circle is given first.
--   
--   
--   <pre>
--   annularWedgeEx = hcat' (with &amp; sep .~ 0.50)
--     [ annularWedge 1 0.5 (0 @@ turn) (1/4 @@ turn)
--     , annularWedge 1 0.3 (7/30 @@ turn) (11/30 @@ turn)
--     , annularWedge 1 0.7 (1/8 @@ turn) (7/8 @@ turn)
--     ]
--     # fc blue
--     # centerXY # pad 1.1
--   </pre>
annularWedge :: (TrailLike p, V p ~ R2) => Double -> Double -> Angle -> Angle -> p


-- | Two-dimensional ellipses (and, as a special case, circles).
module Diagrams.TwoD.Ellipse

-- | A circle of radius 1, with center at the origin.
unitCircle :: (TrailLike t, V t ~ R2) => t

-- | A circle of the given radius, centered at the origin. As a path, it
--   begins at (r,0).
circle :: (TrailLike t, V t ~ R2, Transformable t) => Double -> t

-- | <tt>ellipse e</tt> constructs an ellipse with eccentricity <tt>e</tt>
--   by scaling the unit circle in the X direction. The eccentricity must
--   be within the interval [0,1).
ellipse :: (TrailLike t, V t ~ R2, Transformable t) => Double -> t

-- | <tt>ellipseXY x y</tt> creates an axis-aligned ellipse, centered at
--   the origin, with radius <tt>x</tt> along the x-axis and radius
--   <tt>y</tt> along the y-axis.
ellipseXY :: (TrailLike t, V t ~ R2, Transformable t) => Double -> Double -> t


-- | Segments in two dimensions are special since we may meaningfully
--   compute their point of intersection with a ray.
module Diagrams.TwoD.Segment
instance Traced (FixedSegment R2)
instance Traced (Segment Closed R2)


-- | The <i>alignment</i> of an object refers to the position of its local
--   origin with respect to its envelope. This module defines the
--   <a>Alignable</a> class for things which can be aligned, as well as a
--   default implementation in terms of <a>HasOrigin</a> and
--   <a>Enveloped</a>, along with several utility methods for alignment.
module Diagrams.Align

-- | Class of things which can be aligned.
class Alignable a where alignBy' = alignBy'Default alignBy = alignBy' defaultBoundary
alignBy' :: (Alignable a, HasOrigin a, AdditiveGroup (V a), Num (Scalar (V a)), Fractional (Scalar (V a))) => (V a -> a -> Point (V a)) -> V a -> Scalar (V a) -> a -> a
defaultBoundary :: Alignable a => V a -> a -> Point (V a)
alignBy :: (Alignable a, HasOrigin a, Num (Scalar (V a)), Fractional (Scalar (V a))) => V a -> Scalar (V a) -> a -> a

-- | Default implementation of <a>alignBy</a> for types with
--   <a>HasOrigin</a> and <a>AdditiveGroup</a> instances.
alignBy'Default :: (HasOrigin a, AdditiveGroup (V a), Num (Scalar (V a)), Fractional (Scalar (V a))) => (V a -> a -> Point (V a)) -> V a -> Scalar (V a) -> a -> a

-- | Some standard functions which can be used as the <tt>boundary</tt>
--   argument to <a>alignBy'</a>.
envelopeBoundary :: Enveloped a => V a -> a -> Point (V a)
traceBoundary :: Traced a => V a -> a -> Point (V a)

-- | <tt>align v</tt> aligns an enveloped object along the edge in the
--   direction of <tt>v</tt>. That is, it moves the local origin in the
--   direction of <tt>v</tt> until it is on the edge of the envelope. (Note
--   that if the local origin is outside the envelope to begin with, it may
--   have to move "backwards".)
align :: (Alignable a, HasOrigin a, Num (Scalar (V a)), Fractional (Scalar (V a))) => V a -> a -> a

-- | Like align but uses trace.
snug :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a) => V a -> a -> a

-- | <tt>centerV v</tt> centers an enveloped object along the direction of
--   <tt>v</tt>.
centerV :: (Alignable a, HasOrigin a, Num (Scalar (V a)), Fractional (Scalar (V a))) => V a -> a -> a

-- | <tt>center</tt> centers an enveloped object along all of its basis
--   vectors.
center :: (HasLinearMap (V a), Alignable a, HasOrigin a, Num (Scalar (V a)), Fractional (Scalar (V a))) => a -> a

-- | Version of <tt>alignBy</tt> specialized to use <tt>traceBoundary</tt>
snugBy :: (Alignable a, Traced a, HasOrigin a, Num (Scalar (V a)), Fractional (Scalar (V a))) => V a -> Scalar (V a) -> a -> a

-- | Like <tt>centerV</tt> using trace.
snugCenterV :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a) => V a -> a -> a

-- | Like <tt>center</tt> using trace.
snugCenter :: (HasLinearMap (V a), Alignable a, HasOrigin a, Num (Scalar (V a)), Fractional (Scalar (V a)), Traced a) => a -> a
instance (HasOrigin a, Alignable a) => Alignable (b -> a)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => Alignable (QDiagram b v m)
instance (InnerSpace (V b), Ord (Scalar (V b)), Alignable b) => Alignable (Map k b)
instance (InnerSpace (V b), Ord (Scalar (V b)), Alignable b) => Alignable (Set b)
instance (InnerSpace (V b), Ord (Scalar (V b)), Alignable b) => Alignable [b]
instance (InnerSpace v, OrderedField (Scalar v)) => Alignable (Trace v)
instance (InnerSpace v, OrderedField (Scalar v)) => Alignable (Envelope v)


-- | This module defines <i>paths</i>, which are collections of concretely
--   located <a>Trail</a>s. Many drawing systems (cairo, svg, ...) have a
--   similar notion of "path". Note that paths with multiple trails are
--   necessary for being able to draw <i>e.g.</i> filled objects with holes
--   in them.
module Diagrams.Path

-- | A <i>path</i> is a (possibly empty) list of <a>Located</a>
--   <a>Trail</a>s. Hence, unlike trails, paths are not translationally
--   invariant, and they form a monoid under <i>superposition</i> (placing
--   one path on top of another) rather than concatenation.
newtype Path v
Path :: [Located (Trail v)] -> Path v

-- | Extract the located trails making up a <a>Path</a>.
pathTrails :: Path v -> [Located (Trail v)]

-- | Convert a trail to a path beginning at the origin.
pathFromTrail :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> Path v

-- | Convert a trail to a path with a particular starting point.
pathFromTrailAt :: (InnerSpace v, OrderedField (Scalar v)) => Trail v -> Point v -> Path v

-- | Convert a located trail to a singleton path. This is equivalent to
--   <a>trailLike</a>, but provided with a more specific name and type for
--   convenience.
pathFromLocTrail :: (InnerSpace v, OrderedField (Scalar v)) => Located (Trail v) -> Path v

-- | Extract the vertices of a path, resulting in a separate list of
--   vertices for each component trail (see <a>trailVertices</a>).
pathVertices :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> [[Point v]]

-- | Compute the total offset of each trail comprising a path (see
--   <a>trailOffset</a>).
pathOffsets :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> [v]

-- | Compute the <i>centroid</i> of a path (<i>i.e.</i> the average
--   location of its vertices).
pathCentroid :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> Point v

-- | Convert a path into a list of lists of located segments.
pathLocSegments :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> [[Located (Segment Closed v)]]

-- | Convert a path into a list of lists of <a>FixedSegment</a>s.
fixPath :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> [[FixedSegment v]]

-- | Scale a path using its centroid (see <a>pathCentroid</a>) as the base
--   point for the scale.
scalePath :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Scalar v -> Path v -> Path v

-- | Reverse all the component trails of a path.
reversePath :: (InnerSpace v, OrderedField (Scalar v)) => Path v -> Path v

-- | "Explode" a path by exploding every component trail (see
--   <a>explodeTrail</a>).
explodePath :: (VectorSpace (V t), TrailLike t) => Path (V t) -> [[t]]

-- | Partition a path into two paths based on a predicate on trails: the
--   first containing all the trails for which the predicate returns
--   <tt>True</tt>, and the second containing the remaining trails.
partitionPath :: (Located (Trail v) -> Bool) -> Path v -> (Path v, Path v)
instance Typeable1 Path
instance Ord v => Ord (Path v)
instance Eq v => Eq (Path v)
instance Show v => Show (Path v)
instance Semigroup (Path v)
instance Monoid (Path v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Renderable (Path v) NullBackend
instance (InnerSpace v, OrderedField (Scalar v)) => Alignable (Path v)
instance (InnerSpace v, OrderedField (Scalar v)) => Juxtaposable (Path v)
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Path v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Transformable (Path v)
instance (InnerSpace v, OrderedField (Scalar v)) => TrailLike (Path v)
instance VectorSpace v => HasOrigin (Path v)
instance Rewrapped (Path v) (Path v')
instance Wrapped (Path v)


-- | Higher-level tools for combining diagrams.
module Diagrams.Combinators

-- | Use the envelope from some object as the envelope for a diagram, in
--   place of the diagram's default envelope.
--   
--   
--   <pre>
--   sqNewEnv =
--       circle 1 # fc green
--       |||
--       (    c # dashingG [0.1,0.1] 0 # lc white
--         &lt;&gt; square 2 # withEnvelope (c :: D R2) # fc blue
--       )
--   c = circle 0.8
--   withEnvelopeEx = sqNewEnv # centerXY # pad 1.5
--   </pre>
withEnvelope :: (HasLinearMap (V a), Enveloped a, Monoid' m) => a -> QDiagram b (V a) m -> QDiagram b (V a) m

-- | Use the trace from some object as the trace for a diagram, in place of
--   the diagram's default trace.
withTrace :: (HasLinearMap (V a), Traced a, OrderedField (Scalar (V a)), InnerSpace (V a), Monoid' m) => a -> QDiagram b (V a) m -> QDiagram b (V a) m

-- | <tt>phantom x</tt> produces a "phantom" diagram, which has the same
--   envelope and trace as <tt>x</tt> but produces no output.
phantom :: (Backend b (V a), Typeable (V a), Enveloped a, Traced a, Monoid' m) => a -> QDiagram b (V a) m

-- | <tt>strut v</tt> is a diagram which produces no output, but with
--   respect to alignment and envelope acts like a 1-dimensional segment
--   oriented along the vector <tt>v</tt>, with local origin at its center.
--   (Note, however, that it has an empty trace; for 2D struts with a
--   nonempty trace see <tt>strutR2</tt>, <tt>strutX</tt>, and
--   <tt>strutY</tt> from <a>Diagrams.TwoD.Combinators</a>.) Useful for
--   manually creating separation between two diagrams.
--   
--   
--   <pre>
--   strutEx = (circle 1 ||| strut unitX ||| circle 1) # centerXY # pad 1.1
--   </pre>
strut :: (Backend b v, Typeable v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => v -> QDiagram b v m

-- | <tt>pad s</tt> "pads" a diagram, expanding its envelope by a factor of
--   <tt>s</tt> (factors between 0 and 1 can be used to shrink the
--   envelope). Note that the envelope will expand with respect to the
--   local origin, so if the origin is not centered the padding may appear
--   "uneven". If this is not desired, the origin can be centered (using,
--   e.g., <tt>centerXY</tt> for 2D diagrams) before applying <tt>pad</tt>.
pad :: (Backend b v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => Scalar v -> QDiagram b v m -> QDiagram b v m

-- | <tt>frame s</tt> increases the envelope of a diagram by and absolute
--   amount <tt>s</tt>, s is in the local units of the diagram. This
--   function is similar to <tt>pad</tt>, only it takes an absolute
--   quantity and pre-centering should not be necessary.
frame :: (Backend b v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => Scalar v -> QDiagram b v m -> QDiagram b v m

-- | <tt>extrudeEnvelope v d</tt> asymmetrically "extrudes" the envelope of
--   a diagram in the given direction. All parts of the envelope within 90
--   degrees of this direction are modified, offset outwards by the
--   magnitude of the vector.
--   
--   This works by offsetting the envelope distance proportionally to the
--   cosine of the difference in angle, and leaving it unchanged when this
--   factor is negative.
extrudeEnvelope :: (Ord (Scalar v), Num (Scalar v), AdditiveGroup (Scalar v), Floating (Scalar v), HasLinearMap v, InnerSpace v, Monoid' m) => v -> QDiagram b v m -> QDiagram b v m

-- | <tt>intrudeEnvelope v d</tt> asymmetrically "intrudes" the envelope of
--   a diagram away from the given direction. All parts of the envelope
--   within 90 degrees of this direction are modified, offset inwards by
--   the magnitude of the vector.
--   
--   Note that this could create strange inverted envelopes, where <tt>
--   diameter v d &lt; 0 </tt>.
intrudeEnvelope :: (Ord (Scalar v), Num (Scalar v), AdditiveGroup (Scalar v), Floating (Scalar v), HasLinearMap v, InnerSpace v, Monoid' m) => v -> QDiagram b v m -> QDiagram b v m

-- | A convenient synonym for <a>mappend</a> on diagrams, designed to be
--   used infix (to help remember which diagram goes on top of which when
--   combining them, namely, the first on top of the second).
atop :: (HasLinearMap v, OrderedField (Scalar v), InnerSpace v, Semigroup m) => QDiagram b v m -> QDiagram b v m -> QDiagram b v m

-- | <tt>beneath</tt> is just a convenient synonym for <tt><a>flip</a>
--   <a>atop</a></tt>; that is, <tt>d1 `beneath` d2</tt> is the diagram
--   with <tt>d2</tt> superimposed on top of <tt>d1</tt>.
beneath :: (HasLinearMap v, OrderedField (Scalar v), InnerSpace v, Monoid' m) => QDiagram b v m -> QDiagram b v m -> QDiagram b v m

-- | Place two monoidal objects (<i>i.e.</i> diagrams, paths,
--   animations...) next to each other along the given vector. In
--   particular, place the second object so that the vector points from the
--   local origin of the first object to the local origin of the second
--   object, at a distance so that their envelopes are just tangent. The
--   local origin of the new, combined object is the local origin of the
--   first object (unless the first object is the identity element, in
--   which case the second object is returned unchanged).
--   
--   
--   <pre>
--   besideEx = beside (r2 (20,30))
--                     (circle 1 # fc orange)
--                     (circle 1.5 # fc purple)
--              # showOrigin
--              # centerXY # pad 1.1
--   </pre>
--   
--   Note that <tt>beside v</tt> is associative, so objects under
--   <tt>beside v</tt> form a semigroup for any given vector <tt>v</tt>. In
--   fact, they also form a monoid: <a>mempty</a> is clearly a right
--   identity (<tt>beside v d1 mempty === d1</tt>), and there should also
--   be a special case to make it a left identity, as described above.
--   
--   In older versions of diagrams, <tt>beside</tt> put the local origin of
--   the result at the point of tangency between the two inputs. That
--   semantics can easily be recovered by performing an alignment on the
--   first input before combining. That is, if <tt>beside'</tt> denotes the
--   old semantics,
--   
--   <pre>
--   beside' v x1 x2 = beside v (x1 # align v) x2
--   </pre>
--   
--   To get something like <tt>beside v x1 x2</tt> whose local origin is
--   identified with that of <tt>x2</tt> instead of <tt>x1</tt>, use
--   <tt>beside (negateV v) x2 x1</tt>.
beside :: (Juxtaposable a, Semigroup a) => V a -> a -> a -> a

-- | <tt>appends x ys</tt> appends each of the objects in <tt>ys</tt> to
--   the object <tt>x</tt> in the corresponding direction. Note that each
--   object in <tt>ys</tt> is positioned beside <tt>x</tt> <i>without</i>
--   reference to the other objects in <tt>ys</tt>, so this is not the same
--   as iterating <a>beside</a>.
--   
--   
--   <pre>
--   appendsEx = appends c (zip (iterateN 6 (rotateBy (1/6)) unitX) (repeat c))
--               # centerXY # pad 1.1
--     where c = circle 1
--   </pre>
appends :: (Juxtaposable a, Monoid' a) => a -> [(V a, a)] -> a

-- | Position things absolutely: combine a list of objects (e.g. diagrams
--   or paths) by assigning them absolute positions in the vector space of
--   the combined object.
--   
--   
--   <pre>
--   positionEx = position (zip (map mkPoint [-3, -2.8 .. 3]) (repeat dot))
--     where dot       = circle 0.2 # fc black
--           mkPoint x = p2 (x,x^2)
--   </pre>
position :: (HasOrigin a, Monoid' a) => [(Point (V a), a)] -> a

-- | Combine a list of diagrams (or paths) by using them to "decorate" a
--   trail, placing the local origin of one object at each successive
--   vertex of the trail. The first vertex of the trail is placed at the
--   origin. If the trail and list of objects have different lengths, the
--   extra tail of the longer one is ignored.
decorateTrail :: (InnerSpace (V a), OrderedField (Scalar (V a)), HasOrigin a, Monoid' a) => Trail (V a) -> [a] -> a

-- | Combine a list of diagrams (or paths) by using them to "decorate" a
--   concretely located trail, placing the local origin of one object at
--   each successive vertex of the trail. If the trail and list of objects
--   have different lengths, the extra tail of the longer one is ignored.
decorateLocatedTrail :: (InnerSpace (V a), OrderedField (Scalar (V a)), HasOrigin a, Monoid' a) => Located (Trail (V a)) -> [a] -> a

-- | Combine a list of diagrams (or paths) by using them to "decorate" a
--   path, placing the local origin of one object at each successive vertex
--   of the path. If the path and list of objects have different lengths,
--   the extra tail of the longer one is ignored.
decoratePath :: (InnerSpace (V a), OrderedField (Scalar (V a)), HasOrigin a, Monoid' a) => Path (V a) -> [a] -> a

-- | <tt>cat v</tt> positions a list of objects so that their local origins
--   lie along a line in the direction of <tt>v</tt>. Successive objects
--   will have their envelopes just touching. The local origin of the
--   result will be the same as the local origin of the first object.
--   
--   See also <a>cat'</a>, which takes an extra options record allowing
--   certain aspects of the operation to be tweaked.
cat :: (Juxtaposable a, Monoid' a, HasOrigin a, InnerSpace (V a), OrderedField (Scalar (V a))) => V a -> [a] -> a

-- | Like <a>cat</a>, but taking an extra <a>CatOpts</a> arguments allowing
--   the user to specify
--   
--   <ul>
--   <li>The spacing method: catenation (uniform spacing between envelopes)
--   or distribution (uniform spacing between local origins). The default
--   is catenation.</li>
--   <li>The amount of separation between successive diagram
--   envelopes/origins (depending on the spacing method). The default is
--   0.</li>
--   </ul>
--   
--   <a>CatOpts</a> is an instance of <a>Default</a>, so <a>with</a> may be
--   used for the second argument, as in <tt>cat' (1,2) (with &amp; sep .~
--   2)</tt>.
--   
--   Note that <tt>cat' v (with &amp; catMethod .~ Distrib) ===
--   mconcat</tt> (distributing with a separation of 0 is the same as
--   superimposing).
cat' :: (Juxtaposable a, Monoid' a, HasOrigin a, InnerSpace (V a), OrderedField (Scalar (V a))) => V a -> CatOpts (V a) -> [a] -> a

-- | Options for <a>cat'</a>.
data CatOpts v

-- | Which <a>CatMethod</a> should be used: normal catenation (default), or
--   distribution?
catMethod :: Lens' (CatOpts v) CatMethod

-- | How much separation should be used between successive diagrams
--   (default: 0)? When <tt>catMethod = Cat</tt>, this is the distance
--   between <i>envelopes</i>; when <tt>catMethod = Distrib</tt>, this is
--   the distance between <i>origins</i>.
sep :: Lens' (CatOpts v) (Scalar v)

-- | Methods for concatenating diagrams.
data CatMethod

-- | Normal catenation: simply put diagrams next to one another (possibly
--   with a certain distance in between each). The distance between
--   successive diagram <i>envelopes</i> will be consistent; the distance
--   between <i>origins</i> may vary if the diagrams are of different
--   sizes.
Cat :: CatMethod

-- | Distribution: place the local origins of diagrams at regular
--   intervals. With this method, the distance between successive
--   <i>origins</i> will be consistent but the distance between envelopes
--   may not be. Indeed, depending on the amount of separation, diagrams
--   may overlap.
Distrib :: CatMethod
instance Num (Scalar v) => Default (CatOpts v)


-- | "Envelopes", aka functional bounding regions. See
--   <a>Diagrams.Core.Envelope</a> for internal implementation details.
module Diagrams.Envelope

-- | Every diagram comes equipped with an <i>envelope</i>. What is an
--   envelope?
--   
--   Consider first the idea of a <i>bounding box</i>. A bounding box
--   expresses the distance to a bounding plane in every direction parallel
--   to an axis. That is, a bounding box can be thought of as the
--   intersection of a collection of half-planes, two perpendicular to each
--   axis.
--   
--   More generally, the intersection of half-planes in <i>every</i>
--   direction would give a tight "bounding region", or convex hull.
--   However, representing such a thing intensionally would be impossible;
--   hence bounding boxes are often used as an approximation.
--   
--   An envelope is an <i>extensional</i> representation of such a
--   "bounding region". Instead of storing some sort of direct
--   representation, we store a <i>function</i> which takes a direction as
--   input and gives a distance to a bounding half-plane as output. The
--   important point is that envelopes can be composed, and transformed by
--   any affine transformation.
--   
--   Formally, given a vector <tt>v</tt>, the envelope computes a scalar
--   <tt>s</tt> such that
--   
--   <ul>
--   <li>for every point <tt>u</tt> inside the diagram, if the projection
--   of <tt>(u - origin)</tt> onto <tt>v</tt> is <tt>s' *^ v</tt>, then
--   <tt>s' &lt;= s</tt>.</li>
--   <li><tt>s</tt> is the smallest such scalar.</li>
--   </ul>
--   
--   There is also a special "empty envelope".
--   
--   The idea for envelopes came from Sebastian Setzer; see
--   <a>http://byorgey.wordpress.com/2009/10/28/collecting-attributes/#comment-2030</a>.
--   See also Brent Yorgey, <i>Monoids: Theme and Variations</i>, published
--   in the 2012 Haskell Symposium:
--   <a>http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf</a>; video:
--   <a>http://www.youtube.com/watch?v=X-8NCkD2vOw</a>.
data Envelope v :: * -> *

-- | <tt>Enveloped</tt> abstracts over things which have an envelope.
class (InnerSpace (V a), OrderedField (Scalar (V a))) => Enveloped a

-- | Get the envelope of a diagram.
envelope :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Monoid' m) => Lens' (QDiagram b v m) (Envelope v)

-- | Replace the envelope of a diagram.
setEnvelope :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Monoid' m) => Envelope v -> QDiagram b v m -> QDiagram b v m

-- | Use the envelope from some object as the envelope for a diagram, in
--   place of the diagram's default envelope.
--   
--   
--   <pre>
--   sqNewEnv =
--       circle 1 # fc green
--       |||
--       (    c # dashingG [0.1,0.1] 0 # lc white
--         &lt;&gt; square 2 # withEnvelope (c :: D R2) # fc blue
--       )
--   c = circle 0.8
--   withEnvelopeEx = sqNewEnv # centerXY # pad 1.5
--   </pre>
withEnvelope :: (HasLinearMap (V a), Enveloped a, Monoid' m) => a -> QDiagram b (V a) m -> QDiagram b (V a) m

-- | <tt>phantom x</tt> produces a "phantom" diagram, which has the same
--   envelope and trace as <tt>x</tt> but produces no output.
phantom :: (Backend b (V a), Typeable (V a), Enveloped a, Traced a, Monoid' m) => a -> QDiagram b (V a) m

-- | <tt>pad s</tt> "pads" a diagram, expanding its envelope by a factor of
--   <tt>s</tt> (factors between 0 and 1 can be used to shrink the
--   envelope). Note that the envelope will expand with respect to the
--   local origin, so if the origin is not centered the padding may appear
--   "uneven". If this is not desired, the origin can be centered (using,
--   e.g., <tt>centerXY</tt> for 2D diagrams) before applying <tt>pad</tt>.
pad :: (Backend b v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => Scalar v -> QDiagram b v m -> QDiagram b v m

-- | <tt>extrudeEnvelope v d</tt> asymmetrically "extrudes" the envelope of
--   a diagram in the given direction. All parts of the envelope within 90
--   degrees of this direction are modified, offset outwards by the
--   magnitude of the vector.
--   
--   This works by offsetting the envelope distance proportionally to the
--   cosine of the difference in angle, and leaving it unchanged when this
--   factor is negative.
extrudeEnvelope :: (Ord (Scalar v), Num (Scalar v), AdditiveGroup (Scalar v), Floating (Scalar v), HasLinearMap v, InnerSpace v, Monoid' m) => v -> QDiagram b v m -> QDiagram b v m

-- | <tt>intrudeEnvelope v d</tt> asymmetrically "intrudes" the envelope of
--   a diagram away from the given direction. All parts of the envelope
--   within 90 degrees of this direction are modified, offset inwards by
--   the magnitude of the vector.
--   
--   Note that this could create strange inverted envelopes, where <tt>
--   diameter v d &lt; 0 </tt>.
intrudeEnvelope :: (Ord (Scalar v), Num (Scalar v), AdditiveGroup (Scalar v), Floating (Scalar v), HasLinearMap v, InnerSpace v, Monoid' m) => v -> QDiagram b v m -> QDiagram b v m

-- | Compute the vector from the local origin to a separating hyperplane in
--   the given direction, or <tt>Nothing</tt> for the empty envelope.
envelopeVMay :: Enveloped a => V a -> a -> Maybe (V a)

-- | Compute the vector from the local origin to a separating hyperplane in
--   the given direction. Returns the zero vector for the empty envelope.
envelopeV :: Enveloped a => V a -> a -> V a

-- | Compute the point on a separating hyperplane in the given direction,
--   or <tt>Nothing</tt> for the empty envelope.
envelopePMay :: Enveloped a => V a -> a -> Maybe (Point (V a))

-- | Compute the point on a separating hyperplane in the given direction.
--   Returns the origin for the empty envelope.
envelopeP :: Enveloped a => V a -> a -> Point (V a)

-- | Compute the diameter of a enveloped object along a particular vector.
--   Returns zero for the empty envelope.
diameter :: Enveloped a => V a -> a -> Scalar (V a)

-- | Compute the "radius" (1/2 the diameter) of an enveloped object along a
--   particular vector.
radius :: Enveloped a => V a -> a -> Scalar (V a)


-- | "Traces", aka embedded raytracers, for finding points on the edge of a
--   diagram. See <a>Diagrams.Core.Trace</a> for internal implementation
--   details.
module Diagrams.Trace

-- | Every diagram comes equipped with a <i>trace</i>. Intuitively, the
--   trace for a diagram is like a raytracer: given a line (represented as
--   a base point and a direction vector), the trace computes a sorted list
--   of signed distances from the base point to all intersections of the
--   line with the boundary of the diagram.
--   
--   Note that the outputs are not absolute distances, but multipliers
--   relative to the input vector. That is, if the base point is <tt>p</tt>
--   and direction vector is <tt>v</tt>, and one of the output scalars is
--   <tt>s</tt>, then there is an intersection at the point <tt>p .+^ (s *^
--   v)</tt>.
--   
data Trace v :: * -> *

-- | <tt>Traced</tt> abstracts over things which have a trace.
class (Ord (Scalar (V a)), VectorSpace (V a)) => Traced a

-- | Get the trace of a diagram.
trace :: (InnerSpace v, HasLinearMap v, OrderedField (Scalar v), Semigroup m) => Lens' (QDiagram b v m) (Trace v)

-- | Replace the trace of a diagram.
setTrace :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Semigroup m) => Trace v -> QDiagram b v m -> QDiagram b v m

-- | Use the trace from some object as the trace for a diagram, in place of
--   the diagram's default trace.
withTrace :: (HasLinearMap (V a), Traced a, OrderedField (Scalar (V a)), InnerSpace (V a), Monoid' m) => a -> QDiagram b (V a) m -> QDiagram b (V a) m

-- | Compute the vector from the given point <tt>p</tt> to the "smallest"
--   boundary intersection along the given vector <tt>v</tt>. The
--   "smallest" boundary intersection is defined as the one given by <tt>p
--   .+^ (s *^ v)</tt> for the smallest (most negative) value of
--   <tt>s</tt>. Return <tt>Nothing</tt> if there is no intersection. See
--   also <a>traceP</a>.
--   
--   See also <a>rayTraceV</a> which uses the smallest <i>positive</i>
--   intersection, which is often more intuitive behavior.
--   
traceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Compute the "smallest" boundary point along the line determined by the
--   given point <tt>p</tt> and vector <tt>v</tt>. The "smallest" boundary
--   point is defined as the one given by <tt>p .+^ (s *^ v)</tt> for the
--   smallest (most negative) value of <tt>s</tt>. Return <tt>Nothing</tt>
--   if there is no such boundary point. See also <a>traceV</a>.
--   
--   See also <a>rayTraceP</a> which uses the smallest <i>positive</i>
--   intersection, which is often more intuitive behavior.
--   
traceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Like <a>traceV</a>, but computes a vector to the "largest" boundary
--   point instead of the smallest. (Note, however, the "largest" boundary
--   point may still be in the opposite direction from the given vector, if
--   all the boundary points are, as in the third example shown below.)
--   
maxTraceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Like <a>traceP</a>, but computes the "largest" boundary point instead
--   of the smallest. (Note, however, the "largest" boundary point may
--   still be in the opposite direction from the given vector, if all the
--   boundary points are.)
--   
maxTraceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Compute the furthest point on the boundary of a subdiagram, beginning
--   from the location (local origin) of the subdiagram and moving in the
--   direction of the given vector. If there is no such point, the origin
--   is returned; see also <a>boundaryFromMay</a>.
boundaryFrom :: (HasLinearMap v, OrderedField (Scalar v), InnerSpace v, Semigroup m) => Subdiagram b v m -> v -> Point v

-- | Compute the furthest point on the boundary of a subdiagram, beginning
--   from the location (local origin) of the subdiagram and moving in the
--   direction of the given vector, or <tt>Nothing</tt> if there is no such
--   point.
boundaryFromMay :: (HasLinearMap v, OrderedField (Scalar v), Semigroup m, InnerSpace v) => Subdiagram b v m -> v -> Maybe (Point v)

module Diagrams.Deform

-- | <tt>Deformations</tt> are a superset of the affine transformations
--   represented by the <a>Transformation</a> type. In general they are not
--   invertable. <tt>Deformation</tt>s include projective transformations.
--   <tt>Deformation</tt> can represent other functions from points to
--   points which are <a>well-behaved</a>, in that they do not introduce
--   small wiggles.
data Deformation v
Deformation :: (Point v -> Point v) -> Deformation v
class Deformable a
deform' :: Deformable a => Scalar (V a) -> Deformation (V a) -> a -> a
deform :: Deformable a => Deformation (V a) -> a -> a

-- | <tt>asDeformation</tt> converts a <a>Transformation</a> to a
--   <a>Deformation</a> by discarding the inverse transform. This allows
--   reusing <tt>Transformation</tt>s in the construction of
--   <tt>Deformation</tt>s.
asDeformation :: (HasTrie (Basis v), HasBasis v) => Transformation v -> Deformation v
instance (VectorSpace v, InnerSpace v, s ~ Scalar v, Ord s, Fractional s, Floating s, Show s, Show v) => Deformable (Path v)
instance (VectorSpace v, InnerSpace v, s ~ Scalar v, Ord s, Fractional s, Floating s, Show s, Show v) => Deformable (Located (Trail v))
instance Deformable (Point v)
instance Monoid (Deformation v)
instance Semigroup (Deformation v)

module Diagrams.TwoD.Deform

-- | The parallel projection onto the line x=0
parallelX0 :: Deformation R2

-- | The perspective division onto the line x=1 along lines going through
--   the origin.
perspectiveX1 :: Deformation R2

-- | The parallel projection onto the line y=0
parallelY0 :: Deformation R2

-- | The perspective division onto the line y=1 along lines going through
--   the origin.
perspectiveY1 :: Deformation R2

-- | The viewing transform for a viewer facing along the positive X axis. X
--   coördinates stay fixed, while Y coördinates are compressed with
--   increasing distance. <tt>asDeformation (translation unitX) <a></a>
--   parallelX0 <a></a> frustrumX = perspectiveX1</tt>
facingX :: Deformation R2
facingY :: Deformation R2

module Diagrams.ThreeD.Deform

-- | The parallel projection onto the plane x=0
parallelX0 :: Deformation R3

-- | The perspective division onto the plane x=1 along lines going through
--   the origin.
perspectiveX1 :: Deformation R3

-- | The parallel projection onto the plane y=0
parallelY0 :: Deformation R3

-- | The perspective division onto the plane y=1 along lines going through
--   the origin.
perspectiveY1 :: Deformation R3

-- | The parallel projection onto the plane z=0
parallelZ0 :: Deformation R3

-- | The perspective division onto the plane z=1 along lines going through
--   the origin.
perspectiveZ1 :: Deformation R3

-- | The viewing transform for a viewer facing along the positive X axis. X
--   coördinates stay fixed, while Y coördinates are compressed with
--   increasing distance. <tt>asDeformation (translation unitX) <a></a>
--   parallelX0 <a></a> frustrumX = perspectiveX1</tt>
facingX :: Deformation R3
facingY :: Deformation R3
facingZ :: Deformation R3


-- | Paths in two dimensions are special since we may stroke them to create
--   a 2D diagram, and (eventually) perform operations such as intersection
--   and union. They also have a trace, whereas paths in higher dimensions
--   do not.
module Diagrams.TwoD.Path

-- | Convert a path into a diagram. The resulting diagram has the names 0,
--   1, ... assigned to each of the path's vertices.
--   
--   See also <a>stroke'</a>, which takes an extra options record allowing
--   its behavior to be customized.
--   
--   Note that a bug in GHC 7.0.1 causes a context stack overflow when
--   inferring the type of <tt>stroke</tt>. The solution is to give a type
--   signature to expressions involving <tt>stroke</tt>, or (recommended)
--   upgrade GHC (the bug is fixed in 7.0.2 onwards).
stroke :: Renderable (Path R2) b => Path R2 -> Diagram b R2

-- | A variant of <a>stroke</a> that takes an extra record of options to
--   customize its behavior. In particular:
--   
--   <ul>
--   <li>Names can be assigned to the path's vertices</li>
--   </ul>
--   
--   <a>StrokeOpts</a> is an instance of <a>Default</a>, so <tt>stroke'
--   (<tt>with</tt> &amp; ... )</tt> syntax may be used.
stroke' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Path R2 -> Diagram b R2

-- | A composition of <a>stroke</a> and <a>pathFromTrail</a> for
--   conveniently converting a trail directly into a diagram.
--   
--   Note that a bug in GHC 7.0.1 causes a context stack overflow when
--   inferring the type of <a>stroke</a> and hence of <tt>strokeTrail</tt>
--   as well. The solution is to give a type signature to expressions
--   involving <tt>strokeTrail</tt>, or (recommended) upgrade GHC (the bug
--   is fixed in 7.0.2 onwards).
strokeTrail :: Renderable (Path R2) b => Trail R2 -> Diagram b R2

-- | Deprecated synonym for <a>strokeTrail</a>.
strokeT :: Renderable (Path R2) b => Trail R2 -> Diagram b R2

-- | A composition of <a>stroke'</a> and <a>pathFromTrail</a> for
--   conveniently converting a trail directly into a diagram.
strokeTrail' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Trail R2 -> Diagram b R2

-- | Deprecated synonym for <a>strokeTrail'</a>.
strokeT' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Trail R2 -> Diagram b R2

-- | A composition of <a>strokeT</a> and <a>wrapLine</a> for conveniently
--   converting a line directly into a diagram.
strokeLine :: Renderable (Path R2) b => Trail' Line R2 -> Diagram b R2

-- | A composition of <a>strokeT</a> and <a>wrapLoop</a> for conveniently
--   converting a loop directly into a diagram.
strokeLoop :: Renderable (Path R2) b => Trail' Loop R2 -> Diagram b R2

-- | A convenience function for converting a <tt>Located Trail</tt>
--   directly into a diagram; <tt>strokeLocTrail = stroke . trailLike</tt>.
strokeLocTrail :: Renderable (Path R2) b => Located (Trail R2) -> Diagram b R2

-- | Deprecated synonym for <a>strokeLocTrail</a>.
strokeLocT :: Renderable (Path R2) b => Located (Trail R2) -> Diagram b R2

-- | A convenience function for converting a <tt>Located</tt> line directly
--   into a diagram; <tt>strokeLocLine = stroke . trailLike . mapLoc
--   wrapLine</tt>.
strokeLocLine :: Renderable (Path R2) b => Located (Trail' Line R2) -> Diagram b R2

-- | A convenience function for converting a <tt>Located</tt> loop directly
--   into a diagram; <tt>strokeLocLoop = stroke . trailLike . mapLoc
--   wrapLoop</tt>.
strokeLocLoop :: Renderable (Path R2) b => Located (Trail' Loop R2) -> Diagram b R2

-- | Enumeration of algorithms or "rules" for determining which points lie
--   in the interior of a (possibly self-intersecting) closed path.
data FillRule

-- | Interior points are those with a nonzero <i>winding</i> <i>number</i>.
--   See <a>http://en.wikipedia.org/wiki/Nonzero-rule</a>.
Winding :: FillRule

-- | Interior points are those where a ray extended infinitely in a
--   particular direction crosses the path an odd number of times. See
--   <a>http://en.wikipedia.org/wiki/Even-odd_rule</a>.
EvenOdd :: FillRule
newtype FillRuleA
FillRuleA :: (Last FillRule) -> FillRuleA

-- | Extract the fill rule from a <a>FillRuleA</a> attribute.
getFillRule :: FillRuleA -> FillRule

-- | Specify the fill rule that should be used for determining which points
--   are inside a path.
fillRule :: HasStyle a => FillRule -> a -> a

-- | A record of options that control how a path is stroked.
--   <tt>StrokeOpts</tt> is an instance of <a>Default</a>, so a
--   <tt>StrokeOpts</tt> records can be created using <tt><tt>with</tt> {
--   ... }</tt> notation.
data StrokeOpts a
StrokeOpts :: [[a]] -> FillRule -> StrokeOpts a
_vertexNames :: StrokeOpts a -> [[a]]
_queryFillRule :: StrokeOpts a -> FillRule

-- | Atomic names that should be assigned to the vertices of the path so
--   that they can be referenced later. If there are not enough names, the
--   extra vertices are not assigned names; if there are too many, the
--   extra names are ignored. Note that this is a <i>list of lists</i> of
--   names, since paths can consist of multiple trails. The first list of
--   names are assigned to the vertices of the first trail, the second list
--   to the second trail, and so on.
--   
--   The default value is the empty list.
vertexNames :: Lens (StrokeOpts a) (StrokeOpts a') [[a]] [[a']]

-- | The fill rule used for determining which points are inside the path.
--   The default is <a>Winding</a>. NOTE: for now, this only affects the
--   resulting diagram's <a>Query</a>, <i>not</i> how it will be drawn! To
--   set the fill rule determining how it is to be drawn, use the
--   <a>fillRule</a> function.
queryFillRule :: Lens' (StrokeOpts a) FillRule

-- | Test whether the given point is inside the given (closed) path, by
--   testing whether the point's <i>winding number</i> is nonzero. Note
--   that <tt>False</tt> is <i>always</i> returned for <i>open</i> paths,
--   regardless of the winding number.
isInsideWinding :: P2 -> Path R2 -> Bool

-- | Test whether the given point is inside the given (closed) path, by
--   testing whether a ray extending from the point in the positive x
--   direction crosses the path an even (outside) or odd (inside) number of
--   times. Note that <tt>False</tt> is <i>always</i> returned for
--   <i>open</i> paths, regardless of the number of crossings.
isInsideEvenOdd :: P2 -> Path R2 -> Bool

-- | <tt>Clip</tt> tracks the accumulated clipping paths applied to a
--   diagram. Note that the semigroup structure on <tt>Clip</tt> is list
--   concatenation, so applying multiple clipping paths is sensible. The
--   clipping region is the intersection of all the applied clipping paths.
newtype Clip
Clip :: [Path R2] -> Clip

-- | Clip a diagram by the given path:
--   
--   <ul>
--   <li>Only the parts of the diagram which lie in the interior of the
--   path will be drawn.</li>
--   <li>The envelope of the diagram is unaffected.</li>
--   </ul>
clipBy :: (HasStyle a, V a ~ R2) => Path R2 -> a -> a

-- | Clip a diagram to the given path setting its envelope to the pointwise
--   minimum of the envelopes of the diagram and path. The trace consists
--   of those parts of the original diagram's trace which fall within the
--   clipping path, or parts of the path's trace within the original
--   diagram.
clipTo :: Renderable (Path R2) b => Path R2 -> Diagram b R2 -> Diagram b R2

-- | Clip a diagram to the clip path taking the envelope and trace of the
--   clip path.
clipped :: Renderable (Path R2) b => Path R2 -> Diagram b R2 -> Diagram b R2
instance Transformable Clip
instance AttributeClass Clip
instance Wrapped Clip
instance Clip ~ t0 => Rewrapped Clip t0
instance Typeable FillRuleA
instance Typeable Clip
instance Semigroup FillRuleA
instance Show FillRuleA
instance Semigroup Clip
instance Default FillRuleA
instance AttributeClass FillRuleA
instance Renderable (Path R2) b => TrailLike (QDiagram b R2 Any)
instance Default (StrokeOpts a)
instance Eq FillRule
instance Show FillRule
instance Default FillRule
instance Traced (Path R2)
instance Traced (Trail R2)


-- | This module defines a general API for creating various types of
--   polygons.
module Diagrams.TwoD.Polygons

-- | Method used to determine the vertices of a polygon.
data PolyType

-- | A "polar" polygon.
--   
--   <ul>
--   <li>The first argument is a list of <i>central</i> <i>angles</i> from
--   each vertex to the next.</li>
--   <li>The second argument is a list of <i>radii</i> from the origin to
--   each successive vertex.</li>
--   </ul>
--   
--   To construct an <i>n</i>-gon, use a list of <i>n-1</i> angles and
--   <i>n</i> radii. Extra angles or radii are ignored.
--   
--   Cyclic polygons (with all vertices lying on a circle) can be
--   constructed using a second argument of <tt>(repeat r)</tt>.
PolyPolar :: [Angle] -> [Double] -> PolyType

-- | A polygon determined by the distance between successive vertices and
--   the angles formed by each three successive vertices. In other words, a
--   polygon specified by "turtle graphics": go straight ahead x1 units;
--   turn by angle a1; go straght ahead x2 units; turn by angle a2; etc.
--   The polygon will be centered at the <i>centroid</i> of its vertices.
--   
--   <ul>
--   <li>The first argument is a list of <i>vertex</i> <i>angles</i>,
--   giving the angle at each vertex from the previous vertex to the next.
--   The first angle in the list is the angle at the <i>second</i> vertex;
--   the first edge always starts out heading in the positive y direction
--   from the first vertex.</li>
--   <li>The second argument is a list of distances between successive
--   vertices.</li>
--   </ul>
--   
--   To construct an <i>n</i>-gon, use a list of <i>n-2</i> angles and
--   <i>n-1</i> edge lengths. Extra angles or lengths are ignored.
PolySides :: [Angle] -> [Double] -> PolyType

-- | A regular polygon with the given number of sides (first argument) and
--   the given radius (second argument).
PolyRegular :: Int -> Double -> PolyType

-- | Determine how a polygon should be oriented.
data PolyOrientation

-- | No special orientation; the first vertex will be at (1,0). This is the
--   default.
NoOrient :: PolyOrientation

-- | Orient <i>horizontally</i>, so the bottommost edge is parallel to the
--   x-axis.
OrientH :: PolyOrientation

-- | Orient <i>vertically</i>, so the leftmost edge is parallel to the
--   y-axis.
OrientV :: PolyOrientation

-- | Orient so some edge is <i>facing</i> <i>in</i> <i>the</i>
--   <i>direction</i> <i>of</i>, that is, perpendicular to, the given
--   vector.
OrientTo :: R2 -> PolyOrientation

-- | Options for specifying a polygon.
data PolygonOpts
PolygonOpts :: PolyType -> PolyOrientation -> P2 -> PolygonOpts
_polyType :: PolygonOpts -> PolyType
_polyOrient :: PolygonOpts -> PolyOrientation
_polyCenter :: PolygonOpts -> P2

-- | Specification for the polygon's vertices.
polyType :: Lens' PolygonOpts PolyType

-- | Should a rotation be applied to the polygon in order to orient it in a
--   particular way?
polyOrient :: Lens' PolygonOpts PolyOrientation

-- | Should a translation be applied to the polygon in order to place the
--   center at a particular location?
polyCenter :: Lens' PolygonOpts P2

-- | Generate the polygon described by the given options.
polygon :: (TrailLike t, V t ~ R2) => PolygonOpts -> t

-- | Generate a polygon. See <a>PolygonOpts</a> for more information.
polyTrail :: PolygonOpts -> Located (Trail R2)

-- | Generate the located trail of a polygon specified by polar data
--   (central angles and radii). See <a>PolyPolar</a>.
polyPolarTrail :: [Angle] -> [Double] -> Located (Trail R2)

-- | Generate the vertices of a polygon specified by side length and
--   angles, and a starting point for the trail such that the origin is at
--   the centroid of the vertices. See <a>PolySides</a>.
polySidesTrail :: [Angle] -> [Double] -> Located (Trail R2)

-- | Generate the vertices of a regular polygon. See <a>PolyRegular</a>.
polyRegularTrail :: Int -> Double -> Located (Trail R2)

-- | Generate a transformation to orient a trail. <tt>orient v t</tt>
--   generates the smallest rotation such that one of the segments adjacent
--   to the vertex furthest in the direction of <tt>v</tt> is perpendicular
--   to <tt>v</tt>.
orient :: R2 -> Located (Trail R2) -> T2

-- | Options for creating "star" polygons, where the edges connect possibly
--   non-adjacent vertices.
data StarOpts

-- | Specify the order in which the vertices should be connected by a
--   function that maps each vertex index to the index of the vertex that
--   should come next. Indexing of vertices begins at 0.
StarFun :: (Int -> Int) -> StarOpts

-- | Specify a star polygon by a "skip". A skip of 1 indicates a normal
--   polygon, where edges go between successive vertices. A skip of 2 means
--   that edges will connect every second vertex, skipping one in between.
--   Generally, a skip of <i>n</i> means that edges will connect every
--   <i>n</i>th vertex.
StarSkip :: Int -> StarOpts

-- | Create a generalized <i>star</i> <i>polygon</i>. The <a>StarOpts</a>
--   are used to determine in which order the given vertices should be
--   connected. The intention is that the second argument of type
--   <tt>[P2]</tt> could be generated by a call to <a>polygon</a>,
--   <tt>regPoly</tt>, or the like, since a list of vertices is
--   <a>TrailLike</a>. But of course the list can be generated any way you
--   like. A <tt><a>Path</a> <a>R2</a></tt> is returned (instead of any
--   <a>TrailLike</a>) because the resulting path may have more than one
--   component, for example if the vertices are to be connected in several
--   disjoint cycles.
star :: StarOpts -> [P2] -> Path R2

-- | Pieces of a function graph can either be cycles or "hairs".
data GraphPart a
Cycle :: [a] -> GraphPart a
Hair :: [a] -> GraphPart a

-- | <tt>orbits f n</tt> computes the graph of <tt>f</tt> on the integers
--   mod <tt>n</tt>.
orbits :: (Int -> Int) -> Int -> [GraphPart Int]

-- | Generate a function graph from the given function and labels.
mkGraph :: (Int -> Int) -> [a] -> [GraphPart a]
instance Show a => Show (GraphPart a)
instance Functor GraphPart
instance Default PolygonOpts
instance Eq PolyOrientation
instance Ord PolyOrientation
instance Show PolyOrientation
instance Read PolyOrientation


-- | Various two-dimensional shapes.
module Diagrams.TwoD.Shapes

-- | Create a centered horizontal (L-R) line of the given length.
--   
--   
--   <pre>
--   hruleEx = vcat' (with &amp; sep .~ 0.2) (map hrule [1..5])
--           # centerXY # pad 1.1
--   </pre>
hrule :: (TrailLike t, V t ~ R2) => Double -> t

-- | Create a centered vertical (T-B) line of the given length.
--   
--   
--   <pre>
--   vruleEx = hcat' (with &amp; sep .~ 0.2) (map vrule [1, 1.2 .. 2])
--           # centerXY # pad 1.1
--   </pre>
vrule :: (TrailLike t, V t ~ R2) => Double -> t

-- | Create a regular polygon. The first argument is the number of sides,
--   and the second is the <i>length</i> of the sides. (Compare to the
--   <a>polygon</a> function with a <a>PolyRegular</a> option, which
--   produces polygons of a given <i>radius</i>).
--   
--   The polygon will be oriented with one edge parallel to the x-axis.
regPoly :: (TrailLike t, V t ~ R2) => Int -> Double -> t

-- | An equilateral triangle, with sides of the given length and base
--   parallel to the x-axis.
--   
triangle :: (TrailLike t, V t ~ R2) => Double -> t

-- | A synonym for <a>triangle</a>, provided for backwards compatibility.
eqTriangle :: (TrailLike t, V t ~ R2) => Double -> t

-- | A square with its center at the origin and sides of the given length,
--   oriented parallel to the axes.
--   
square :: (TrailLike t, Transformable t, V t ~ R2) => Double -> t

-- | A regular pentagon, with sides of the given length and base parallel
--   to the x-axis.
--   
pentagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular hexagon, with sides of the given length and base parallel to
--   the x-axis.
--   
hexagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular heptagon, with sides of the given length and base parallel
--   to the x-axis.
--   
heptagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A synonym for <a>heptagon</a>. It is, however, completely inferior,
--   being a base admixture of the Latin <i>septum</i> (seven) and the
--   Greek γωνία (angl
septagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular octagon, with sides of the given length and base parallel to
--   the x-axis.
--   
octagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular nonagon, with sides of the given length and base parallel to
--   the x-axis.
--   
nonagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular decagon, with sides of the given length and base parallel to
--   the x-axis.
--   
decagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular hendecagon, with sides of the given length and base parallel
--   to the x-axis.
--   
hendecagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular dodecagon, with sides of the given length and base parallel
--   to the x-axis.
--   
dodecagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A square with its center at the origin and sides of length 1, oriented
--   parallel to the axes.
--   
unitSquare :: (TrailLike t, V t ~ R2) => t

-- | <tt>rect w h</tt> is an axis-aligned rectangle of width <tt>w</tt> and
--   height <tt>h</tt>, centered at the origin.
--   
rect :: (TrailLike t, Transformable t, V t ~ R2) => Double -> Double -> t

-- | <tt>roundedRect w h r</tt> generates a closed trail, or closed path
--   centered at the origin, of an axis-aligned rectangle with width
--   <tt>w</tt>, height <tt>h</tt>, and circular rounded corners of radius
--   <tt>r</tt>. If <tt>r</tt> is negative the corner will be cut out in a
--   reverse arc. If the size of <tt>r</tt> is larger than half the smaller
--   dimension of <tt>w</tt> and <tt>h</tt>, then it will be reduced to fit
--   in that range, to prevent the corners from overlapping. The trail or
--   path begins with the right edge and proceeds counterclockwise. If you
--   need to specify a different radius for each corner individually, use
--   <a>roundedRect'</a> instead.
--   
--   
--   <pre>
--   roundedRectEx = pad 1.1 . centerXY $ hcat' (with &amp; sep .~ 0.2)
--     [ roundedRect  0.5 0.4 0.1
--     , roundedRect  0.5 0.4 (-0.1)
--     , roundedRect' 0.7 0.4 (with &amp; radiusTL .~ 0.2
--                                  &amp; radiusTR .~ -0.2
--                                  &amp; radiusBR .~ 0.1)
--     ]
--   </pre>
roundedRect :: (TrailLike t, V t ~ R2) => Double -> Double -> Double -> t
data RoundedRectOpts
RoundedRectOpts :: Double -> Double -> Double -> Double -> RoundedRectOpts
_radiusTL :: RoundedRectOpts -> Double
_radiusTR :: RoundedRectOpts -> Double
_radiusBL :: RoundedRectOpts -> Double
_radiusBR :: RoundedRectOpts -> Double
radiusTL :: Lens' RoundedRectOpts Double
radiusTR :: Lens' RoundedRectOpts Double
radiusBL :: Lens' RoundedRectOpts Double
radiusBR :: Lens' RoundedRectOpts Double

-- | <tt>roundedRect'</tt> works like <tt>roundedRect</tt> but allows you
--   to set the radius of each corner indivually, using
--   <tt>RoundedRectOpts</tt>. The default corner radius is 0. Each radius
--   can also be negative, which results in the curves being reversed to be
--   inward instead of outward.
roundedRect' :: (TrailLike t, V t ~ R2) => Double -> Double -> RoundedRectOpts -> t
instance Default RoundedRectOpts


-- | An animation is a time-varying diagram, together with start and end
--   times. Most of the tools for working with animations can actually be
--   found in the <tt>active</tt> package, which defines the <a>Active</a>
--   type.
--   
--   XXX more documentation and examples should go here
module Diagrams.Animation

-- | A value of type <tt>QAnimation b v m</tt> is an animation (a
--   time-varying diagram with start and end times) that can be rendered by
--   backspace <tt>b</tt>, with vector space <tt>v</tt> and monoidal
--   annotations of type <tt>m</tt>.
type QAnimation b v m = Active (QDiagram b v m)

-- | A value of type <tt>Animation b v</tt> is an animation (a time-varying
--   diagram with start and end times) in vector space <tt>v</tt> that can
--   be rendered by backspace <tt>b</tt>.
--   
--   Note that <tt>Animation</tt> is actually a synonym for
--   <tt>QAnimation</tt> where the type of the monoidal annotations has
--   been fixed to <a>Any</a> (the default).
type Animation b v = QAnimation b v Any

-- | Automatically assign fixed a envelope to the entirety of an animation
--   by sampling the envelope at a number of points in time and taking the
--   union of all the sampled envelopes to form the "hull". This hull is
--   then used uniformly throughout the animation.
--   
--   This is useful when you have an animation that grows and shrinks in
--   size or shape over time, but you want it to take up a fixed amount of
--   space, <i>e.g.</i> so that the final rendered movie does not zoom in
--   and out, or so that it occupies a fixed location with respect to
--   another animation, when combining animations with something like
--   <tt>|||</tt>.
--   
--   By default, 30 samples per time unit are used; to adjust this number
--   see <a>animEnvelope'</a>.
--   
--   See also <a>animRect</a> for help constructing a background to go
--   behind an animation.
animEnvelope :: (Backend b v, OrderedField (Scalar v), InnerSpace v, Monoid' m) => QAnimation b v m -> QAnimation b v m

-- | Like <a>animEnvelope</a>, but with an adjustible sample rate. The
--   first parameter is the number of samples per time unit to use. Lower
--   rates will be faster but less accurate; higher rates are more accurate
--   but slower.
animEnvelope' :: (Backend b v, OrderedField (Scalar v), InnerSpace v, Monoid' m) => Rational -> QAnimation b v m -> QAnimation b v m

-- | <tt>animRect</tt> works similarly to <a>animEnvelope</a> for 2D
--   diagrams, but instead of adjusting the envelope, simply returns the
--   smallest bounding rectangle which encloses the entire animation.
--   Useful for <i>e.g.</i> creating a background to go behind an
--   animation.
--   
--   Uses 30 samples per time unit by default; to adjust this number see
--   <a>animRect'</a>.
animRect :: (TrailLike t, Enveloped t, Transformable t, Monoid t, V t ~ R2, Monoid' m) => QAnimation b R2 m -> t

-- | Like <a>animRect</a>, but with an adjustible sample rate. The first
--   parameter is the number of samples per time unit to use. Lower rates
--   will be faster but less accurate; higher rates are more accurate but
--   slower.
animRect' :: (TrailLike t, Enveloped t, Transformable t, Monoid t, V t ~ R2, Monoid' m) => Rational -> QAnimation b R2 m -> t


-- | Alignment combinators specialized for two dimensions. See
--   <a>Diagrams.Align</a> for more general alignment combinators.
--   
--   The basic idea is that alignment is achieved by moving diagrams' local
--   origins relative to their envelopes or traces (or some other sort of
--   boundary). For example, to align several diagrams along their tops, we
--   first move their local origins to the upper edge of their boundary
--   (using e.g. <tt>map <tt>alignTop</tt></tt>), and then put them
--   together with their local origins along a horizontal line (using e.g.
--   <tt>hcat</tt> from <a>Diagrams.TwoD.Combinators</a>).
module Diagrams.TwoD.Align

-- | Align along the left edge, i.e. translate the diagram in a horizontal
--   direction so that the local origin is on the left edge of the
--   envelope.
alignL :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Align along the right edge.
alignR :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Align along the top edge.
alignT :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Align along the bottom edge.
alignB :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignTL :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignTR :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignBL :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignBR :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
snugL :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugR :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugT :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugB :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugTL :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugTR :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugBL :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugBR :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a

-- | <tt>alignX</tt> and <tt>snugX</tt> move the local origin horizontally
--   as follows:
--   
--   <ul>
--   <li><tt>alignX (-1)</tt> moves the local origin to the left edge of
--   the boundary;</li>
--   <li><tt>align 1</tt> moves the local origin to the right edge;</li>
--   <li>any other argument interpolates linearly between these. For
--   example, <tt>alignX 0</tt> centers, <tt>alignX 2</tt> moves the origin
--   one "radius" to the right of the right edge, and so on.</li>
--   <li><tt>snugX</tt> works the same way.</li>
--   </ul>
alignX :: (Alignable a, HasOrigin a, V a ~ R2) => Double -> a -> a

-- | See the documentation for <a>alignX</a>.
snugX :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => Double -> a -> a

-- | Like <a>alignX</a>, but moving the local origin vertically, with an
--   argument of <tt>1</tt> corresponding to the top edge and <tt>(-1)</tt>
--   corresponding to the bottom edge.
alignY :: (Alignable a, HasOrigin a, V a ~ R2) => Double -> a -> a
snugY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => Double -> a -> a

-- | Center the local origin along the X-axis.
centerX :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Center the local origin along the Y-axis.
centerY :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Center along both the X- and Y-axes.
centerXY :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
snugCenterX :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugCenterY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugCenterXY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a


-- | Standard arrowheads and tails. Each arrowhead or tail is designed to
--   be drawn filled, with a line width of 0, and is normalized to fit
--   inside a circle of diameter 1.
module Diagrams.TwoD.Arrowheads

tri :: ArrowHT

dart :: ArrowHT

spike :: ArrowHT

thorn :: ArrowHT

-- | A line the same width as the shaft.
lineHead :: ArrowHT
noHead :: ArrowHT

-- | Isoceles triangle style. The above example specifies an angle of `2/5
--   Turn`.
--   
arrowheadTriangle :: Angle -> ArrowHT

-- | Isoceles triangle with linear concave base. Inkscape type 1 - dart
--   like.
arrowheadDart :: Angle -> ArrowHT

-- | Isoceles triangle with curved concave base. Inkscape type 2.
arrowheadSpike :: Angle -> ArrowHT

-- | Curved sides, linear concave base. Illustrator CS5 #3
arrowheadThorn :: Angle -> ArrowHT

tri' :: ArrowHT

dart' :: ArrowHT

spike' :: ArrowHT

thorn' :: ArrowHT

-- | A line the same width as the shaft.
lineTail :: ArrowHT
noTail :: ArrowHT

quill :: ArrowHT

block :: ArrowHT

-- | The angle is where the top left corner intersects the circle.
arrowtailQuill :: Angle -> ArrowHT
arrowtailBlock :: Angle -> ArrowHT
type ArrowHT = Double -> Double -> (Path R2, Path R2)


-- | Alignment combinators specialized for three dimensions. See
--   <a>Diagrams.Align</a> for more general alignment combinators.
--   
--   The basic idea is that alignment is achieved by moving diagrams' local
--   origins relative to their envelopes or traces (or some other sort of
--   boundary). For example, to align several diagrams along their tops, we
--   first move their local origins to the upper edge of their boundary
--   (using e.g. <tt>map <a>alignZMax</a></tt>), and then put them together
--   with their local origins along a line (using e.g. <tt>cat</tt> from
--   <a>Diagrams.Combinators</a>).
module Diagrams.ThreeD.Align

-- | Translate the diagram along unitX so that all points have positive
--   x-values.
alignXMin :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Translate the diagram along unitX so that all points have negative
--   x-values.
alignXMax :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Translate the diagram along unitY so that all points have positive
--   y-values.
alignYMin :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Translate the diagram along unitY so that all points have negative
--   y-values.
alignYMax :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Translate the diagram along unitZ so that all points have positive
--   z-values.
alignZMin :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Translate the diagram along unitZ so that all points have negative
--   z-values.
alignZMax :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a
snugXMin :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugXMax :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugYMin :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a

-- | Move the origin along unitY until it touches the edge of the diagram.
snugYMax :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a

-- | Move the origin along unit_Z until it touches the edge of the diagram.
snugZMin :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a

-- | Move the origin along unitZ until it touches the edge of the diagram.
snugZMax :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a

-- | <tt>alignX</tt> and <tt>snugX</tt> move the local origin along unitX
--   as follows:
--   
--   <ul>
--   <li><tt>alignX (-1)</tt> moves the local origin to the low-x of the
--   boundary;</li>
--   <li><tt>align 1</tt> moves the local origin to the high-x edge;</li>
--   <li>any other argument interpolates linearly between these. For
--   example, <tt>alignX 0</tt> centers, <tt>alignX 2</tt> moves the origin
--   one "radius" to the right of the right edge, and so on.</li>
--   <li><tt>snugX</tt> works the same way.</li>
--   </ul>
alignX :: (Alignable a, HasOrigin a, V a ~ R3) => Double -> a -> a

-- | See the documentation for <a>alignX</a>.
snugX :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => Double -> a -> a

-- | Like <a>alignX</a>, but moving the local origin vertically, with an
--   argument of <tt>1</tt> corresponding to the top edge and <tt>(-1)</tt>
--   corresponding to the bottom edge.
alignY :: (Alignable a, HasOrigin a, V a ~ R3) => Double -> a -> a
snugY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => Double -> a -> a

-- | Like <a>alignX</a>, but moving the local origin in the Z direction,
--   with an argument of <tt>1</tt> corresponding to the top edge and
--   <tt>(-1)</tt> corresponding to the bottom edge.
alignZ :: (Alignable a, HasOrigin a, V a ~ R3) => Double -> a -> a
snugZ :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => Double -> a -> a

-- | Center the local origin along the X-axis.
centerX :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Center the local origin along the Y-axis.
centerY :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Center the local origin along the Z-axis.
centerZ :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Center along both the X- and Y-axes.
centerXY :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Center along both the X- and Z-axes.
centerXZ :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Center along both the Y- and Z-axes.
centerYZ :: (Alignable a, HasOrigin a, V a ~ R3) => a -> a

-- | Center an object in three dimensions.
centerXYZ :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugCenterX :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugCenterY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugCenterZ :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugCenterXY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugCenterXZ :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugCenterYZ :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a
snugCenterXYZ :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R3) => a -> a


-- | This module defines the three-dimensional vector space R^3,
--   three-dimensional transformations, and various predefined
--   three-dimensional shapes. This module re-exports useful functionality
--   from a group of more specific modules:
--   
--   <ul>
--   <li><a>Diagrams.ThreeD.Types</a> defines basic types for
--   two-dimensional diagrams, including types representing the 3D
--   Euclidean vector space and various systems of representing
--   directions.</li>
--   <li><a>Diagrams.ThreeD.Transform</a> defines R^3-specific
--   transformations such as rotation by an angle, and scaling,
--   translation, and reflection in the X, Y, and Z directions.</li>
--   <li><a>Diagrams.ThreeD.Shapes</a> defines three-dimensional solids,
--   e.g. spheres and cubes.</li>
--   <li><a>Diagrams.ThreeD.Vector</a> defines some special 3D vectors and
--   functions for converting between vectors and directions.</li>
--   <li><a>Diagrams.ThreeD.Light</a> and <a>Diagrams.ThreeD.Camera</a>
--   define types needed for rendering 3D geometry to (2D) images.</li>
--   </ul>
module Diagrams.ThreeD


-- | Diagrams may have <i>attributes</i> which affect the way they are
--   rendered. This module defines some common attributes; particular
--   backends may also define more backend-specific attributes.
--   
--   Every attribute type must have a <i>semigroup</i> structure, that is,
--   an associative binary operation for combining two attributes into one.
--   Unless otherwise noted, all the attributes defined here use the
--   <a>Last</a> structure, that is, combining two attributes simply keeps
--   the second one and throws away the first. This means that child
--   attributes always override parent attributes.
module Diagrams.Attributes

-- | The <a>Color</a> type class encompasses color representations which
--   can be used by the Diagrams library. Instances are provided for both
--   the <a>Colour</a> and <a>AlphaColour</a> types from the
--   <a>Data.Colour</a> library.
class Color c
toAlphaColour :: Color c => c -> AlphaColour Double
fromAlphaColour :: Color c => AlphaColour Double -> c

-- | An existential wrapper for instances of the <a>Color</a> class.
data SomeColor
SomeColor :: c -> SomeColor
someToAlpha :: SomeColor -> AlphaColour Double

-- | Although the individual colors in a diagram can have transparency, the
--   opacity/transparency of a diagram as a whole can be specified with the
--   <tt>Opacity</tt> attribute. The opacity is a value between 1
--   (completely opaque, the default) and 0 (completely transparent).
--   Opacity is multiplicative, that is, <tt><a>opacity</a> o1 .
--   <a>opacity</a> o2 === <a>opacity</a> (o1 * o2)</tt>. In other words,
--   for example, <tt>opacity 0.8</tt> means "decrease this diagram's
--   opacity to 80% of its previous opacity".
data Opacity
getOpacity :: Opacity -> Double

-- | Multiply the opacity (see <a>Opacity</a>) by the given value. For
--   example, <tt>opacity 0.8</tt> means "decrease this diagram's opacity
--   to 80% of its previous opacity".
opacity :: HasStyle a => Double -> a -> a

-- | Convert to sRGBA.
colorToSRGBA :: Color c => c -> (Double, Double, Double, Double)

-- | Convert to sRGBA.

-- | <i>Deprecated: Renamed to colorToSRGBA. </i>
colorToRGBA :: Color c => c -> (Double, Double, Double, Double)

-- | What sort of shape should be placed at the endpoints of lines?
data LineCap

-- | Lines end precisely at their endpoints.
LineCapButt :: LineCap

-- | Lines are capped with semicircles centered on endpoints.
LineCapRound :: LineCap

-- | Lines are capped with a squares centered on endpoints.
LineCapSquare :: LineCap
data LineCapA
getLineCap :: LineCapA -> LineCap

-- | Set the line end cap attribute.
lineCap :: HasStyle a => LineCap -> a -> a

-- | How should the join points between line segments be drawn?
data LineJoin

-- | Use a "miter" shape (whatever that is).
LineJoinMiter :: LineJoin

-- | Use rounded join points.
LineJoinRound :: LineJoin

-- | Use a "bevel" shape (whatever that is). Are these... carpentry terms?
LineJoinBevel :: LineJoin
data LineJoinA
getLineJoin :: LineJoinA -> LineJoin

-- | Set the segment join style.
lineJoin :: HasStyle a => LineJoin -> a -> a

-- | Miter limit attribute affecting the <a>LineJoinMiter</a> joins. For
--   some backends this value may have additional effects.
newtype LineMiterLimit
LineMiterLimit :: (Last Double) -> LineMiterLimit
getLineMiterLimit :: LineMiterLimit -> Double

-- | Set the miter limit for joins with <a>LineJoinMiter</a>.
lineMiterLimit :: HasStyle a => Double -> a -> a

-- | Apply a <a>LineMiterLimit</a> attribute.
lineMiterLimitA :: HasStyle a => LineMiterLimit -> a -> a
instance Typeable SomeColor
instance Typeable Opacity
instance Typeable LineCap
instance Typeable LineCapA
instance Typeable LineJoin
instance Typeable LineJoinA
instance Typeable LineMiterLimit
instance Semigroup Opacity
instance Eq LineCap
instance Show LineCap
instance Semigroup LineCapA
instance Eq LineCapA
instance Eq LineJoin
instance Show LineJoin
instance Semigroup LineJoinA
instance Eq LineJoinA
instance Semigroup LineMiterLimit
instance Default LineMiterLimit
instance AttributeClass LineMiterLimit
instance Default LineJoin
instance AttributeClass LineJoinA
instance Default LineCap
instance AttributeClass LineCapA
instance AttributeClass Opacity
instance Color SomeColor
instance (Floating a, Real a) => Color (AlphaColour a)
instance (Floating a, Real a) => Color (Colour a)


-- | A module to re-export most of the functionality of the diagrams core
--   and standard library, including 3D types and functions.
module Diagrams.Prelude.ThreeD

-- | Passes the result of the left side to the function on the right side
--   (forward pipe operator).
--   
--   This is the flipped version of (<a>$</a>), which is more common in
--   languages like F# as (<tt>|&gt;</tt>) where it is needed for
--   inference. Here it is supplied for notational convenience and given a
--   precedence that allows it to be nested inside uses of (<a>$</a>).
--   
--   <pre>
--   &gt;&gt;&gt; a &amp; f
--   f a
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; "hello" &amp; length &amp; succ
--   6
--   </pre>
--   
--   This combinator is commonly used when applying multiple <a>Lens</a>
--   operations in sequence.
--   
--   <pre>
--   &gt;&gt;&gt; ("hello","world") &amp; _1.element 0 .~ 'j' &amp; _1.element 4 .~ 'y'
--   ("jelly","world")
--   </pre>
--   
--   This reads somewhat similar to:
--   
--   <pre>
--   &gt;&gt;&gt; flip execState ("hello","world") $ do _1.element 0 .= 'j'; _1.element 4 .= 'y'
--   ("jelly","world")
--   </pre>
(&) :: a -> (a -> b) -> b

-- | Replace the target of a <a>Lens</a> or all of the targets of a
--   <a>Setter</a> or <a>Traversal</a> with a constant value.
--   
--   This is an infix version of <a>set</a>, provided for consistency with
--   (<a>.=</a>).
--   
--   <pre>
--   f <a>&lt;$</a> a ≡ <a>mapped</a> <a>.~</a> f <a>$</a> a
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b,c,d) &amp; _4 .~ e
--   (a,b,c,e)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (42,"world") &amp; _1 .~ "hello"
--   ("hello","world")
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b) &amp; both .~ c
--   (c,c)
--   </pre>
--   
--   <pre>
--   (<a>.~</a>) :: <a>Setter</a> s t a b    -&gt; b -&gt; s -&gt; t
--   (<a>.~</a>) :: <a>Iso</a> s t a b       -&gt; b -&gt; s -&gt; t
--   (<a>.~</a>) :: <a>Lens</a> s t a b      -&gt; b -&gt; s -&gt; t
--   (<a>.~</a>) :: <a>Traversal</a> s t a b -&gt; b -&gt; s -&gt; t
--   </pre>
(.~) :: ASetter s t a b -> b -> s -> t

-- | Modifies the target of a <a>Lens</a> or all of the targets of a
--   <a>Setter</a> or <a>Traversal</a> with a user supplied function.
--   
--   This is an infix version of <a>over</a>.
--   
--   <pre>
--   <a>fmap</a> f ≡ <a>mapped</a> <a>%~</a> f
--   <a>fmapDefault</a> f ≡ <a>traverse</a> <a>%~</a> f
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b,c) &amp; _3 %~ f
--   (a,b,f c)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b) &amp; both %~ f
--   (f a,f b)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; _2 %~ length $ (1,"hello")
--   (1,5)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; traverse %~ f $ [a,b,c]
--   [f a,f b,f c]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; traverse %~ even $ [1,2,3]
--   [False,True,False]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; traverse.traverse %~ length $ [["hello","world"],["!!!"]]
--   [[5,5],[3]]
--   </pre>
--   
--   <pre>
--   (<a>%~</a>) :: <a>Setter</a> s t a b    -&gt; (a -&gt; b) -&gt; s -&gt; t
--   (<a>%~</a>) :: <a>Iso</a> s t a b       -&gt; (a -&gt; b) -&gt; s -&gt; t
--   (<a>%~</a>) :: <a>Lens</a> s t a b      -&gt; (a -&gt; b) -&gt; s -&gt; t
--   (<a>%~</a>) :: <a>Traversal</a> s t a b -&gt; (a -&gt; b) -&gt; s -&gt; t
--   </pre>
(%~) :: Profunctor p => Setting p s t a b -> p a b -> s -> t

-- | A functor with application, providing operations to
--   
--   <ul>
--   <li>embed pure expressions (<a>pure</a>), and</li>
--   <li>sequence computations and combine their results
--   (<a>&lt;*&gt;</a>).</li>
--   </ul>
--   
--   A minimal complete definition must include implementations of these
--   functions satisfying the following laws:
--   
--   <ul>
--   <li><i><i>identity</i></i> <tt><a>pure</a> <a>id</a> <a>&lt;*&gt;</a>
--   v = v</tt></li>
--   <li><i><i>composition</i></i> <tt><a>pure</a> (.) <a>&lt;*&gt;</a> u
--   <a>&lt;*&gt;</a> v <a>&lt;*&gt;</a> w = u <a>&lt;*&gt;</a> (v
--   <a>&lt;*&gt;</a> w)</tt></li>
--   <li><i><i>homomorphism</i></i> <tt><a>pure</a> f <a>&lt;*&gt;</a>
--   <a>pure</a> x = <a>pure</a> (f x)</tt></li>
--   <li><i><i>interchange</i></i> <tt>u <a>&lt;*&gt;</a> <a>pure</a> y =
--   <a>pure</a> (<a>$</a> y) <a>&lt;*&gt;</a> u</tt></li>
--   </ul>
--   
--   The other methods have the following default definitions, which may be
--   overridden with equivalent specialized implementations:
--   
--   <pre>
--   u <a>*&gt;</a> v = <a>pure</a> (<a>const</a> <a>id</a>) <a>&lt;*&gt;</a> u <a>&lt;*&gt;</a> v
--   u <a>&lt;*</a> v = <a>pure</a> <a>const</a> <a>&lt;*&gt;</a> u <a>&lt;*&gt;</a> v
--   </pre>
--   
--   As a consequence of these laws, the <a>Functor</a> instance for
--   <tt>f</tt> will satisfy
--   
--   <pre>
--   <a>fmap</a> f x = <a>pure</a> f <a>&lt;*&gt;</a> x
--   </pre>
--   
--   If <tt>f</tt> is also a <a>Monad</a>, it should satisfy
--   <tt><a>pure</a> = <a>return</a></tt> and <tt>(<a>&lt;*&gt;</a>) =
--   <a>ap</a></tt> (which implies that <a>pure</a> and <a>&lt;*&gt;</a>
--   satisfy the applicative functor laws).
class Functor f => Applicative (f :: * -> *)
pure :: Applicative f => a -> f a
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(*>) :: Applicative f => f a -> f b -> f b
(<*) :: Applicative f => f a -> f b -> f a

-- | Sequence actions, discarding the value of the first argument.
(*>) :: Applicative f => forall a b. f a -> f b -> f b

-- | Sequence actions, discarding the value of the second argument.
(<*) :: Applicative f => forall a b. f a -> f b -> f a

-- | An infix synonym for <a>fmap</a>.
(<$>) :: Functor f => (a -> b) -> f a -> f b

-- | Replace all locations in the input with the same value. The default
--   definition is <tt><a>fmap</a> . <a>const</a></tt>, but this may be
--   overridden with a more efficient version.
(<$) :: Functor f => forall a b. a -> f b -> f a

-- | Lift a function to actions. This function may be used as a value for
--   <a>fmap</a> in a <a>Functor</a> instance.
liftA :: Applicative f => (a -> b) -> f a -> f b

-- | Lift a binary function to actions.
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

-- | Lift a ternary function to actions.
liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d


-- | Diagrams may have <i>attributes</i> which affect the way they are
--   rendered. This module defines <i>Textures</i> (Gradients and Colors)
--   in two dimensions. Like the attriubtes defined in the
--   Diagrams.Attributes module, all attributes defined here use the
--   <a>Last</a> or <a>Recommend</a> <i>semigroup</i> structure.
--   <tt>FillColor</tt> and <tt>LineColor</tt> attributes are provided so
--   that backends that don't support gradients need not be concerned with
--   using textures. Backends should only implement color attributes or
--   textures attributes, not both.
module Diagrams.TwoD.Attributes

-- | Line widths specified on child nodes always override line widths
--   specified at parent nodes.
data LineWidth
getLineWidth :: LineWidth -> Measure R2

-- | Set the line (stroke) width.
lineWidth :: (HasStyle a, V a ~ R2) => Measure R2 -> a -> a

-- | Apply a <a>LineWidth</a> attribute.
lineWidthA :: (HasStyle a, V a ~ R2) => LineWidth -> a -> a

-- | Default for <a>lineWidth</a>.
lw :: (HasStyle a, V a ~ R2) => Measure R2 -> a -> a

-- | A convenient synonym for 'lineWidth (Normalized w)'.
lwN :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'lineWidth (Output w)'.
lwO :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient sysnonym for 'lineWidth (Local w)'.
lwL :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'lineWidth (Global w)'.
lwG :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | Standard <tt>Measures</tt>.
ultraThin :: Measure R2

-- | Standard <tt>Measures</tt>.
veryThin :: Measure R2

-- | Standard <tt>Measures</tt>.
thin :: Measure R2

-- | Standard <tt>Measures</tt>.
medium :: Measure R2

-- | Standard <tt>Measures</tt>.
thick :: Measure R2

-- | Standard <tt>Measures</tt>.
veryThick :: Measure R2

-- | Standard <tt>Measures</tt>.
ultraThick :: Measure R2

-- | Standard <tt>Measures</tt>.
none :: Measure R2

-- | Standard <tt>Measures</tt>.
tiny :: Measure R2

-- | Standard <tt>Measures</tt>.
verySmall :: Measure R2

-- | Standard <tt>Measures</tt>.
small :: Measure R2

-- | Standard <tt>Measures</tt>.
normal :: Measure R2

-- | Standard <tt>Measures</tt>.
large :: Measure R2

-- | Standard <tt>Measures</tt>.
veryLarge :: Measure R2

-- | Standard <tt>Measures</tt>.
huge :: Measure R2

-- | Create lines that are dashing... er, dashed.
data Dashing
Dashing :: [Measure R2] -> (Measure R2) -> Dashing
data DashingA
getDashing :: DashingA -> Dashing

-- | Set the line dashing style.
dashing :: (HasStyle a, V a ~ R2) => [Measure R2] -> Measure R2 -> a -> a

-- | A convenient synonym for 'dashing (Normalized w)'.
dashingN :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | A convenient synonym for 'dashing (Output w)'.
dashingO :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | A convenient sysnonym for 'dashing (Local w)'.
dashingL :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | A convenient synonym for 'dashing (Global w)'.
dashingG :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | A Texture is either a color <a>SC</a>, linear gradient <a>LG</a>, or
--   radial gradient <a>RG</a>. An object can have only one texture which
--   is determined by the <a>Last</a> semigroup structure.
data Texture
SC :: SomeColor -> Texture
LG :: LGradient -> Texture
RG :: RGradient -> Texture

-- | Convert a solid colour into a texture.
solid :: Color a => a -> Texture
_SC :: Prism' Texture SomeColor
_LG :: Prism' Texture LGradient
_RG :: Prism' Texture RGradient

-- | A default is provided so that linear gradients can easily be created
--   using lenses. For example, <tt>lg = defaultLG &amp; lGradStart .~
--   (0.25 ^&amp; 0.33)</tt>. Note that no default value is provided for
--   <tt>lGradStops</tt>, this must be set before the gradient value is
--   used, otherwise the object will appear transparent.
defaultLG :: Texture

-- | A default is provided so that radial gradients can easily be created
--   using lenses. For example, <tt>rg = defaultRG &amp; rGradRadius1 .~
--   0.25</tt>. Note that no default value is provided for
--   <tt>rGradStops</tt>, this must be set before the gradient value is
--   used, otherwise the object will appear transparent.
defaultRG :: Texture

-- | A gradient stop contains a color and fraction (usually between 0 and
--   1)
data GradientStop
GradientStop :: SomeColor -> Double -> GradientStop
_stopColor :: GradientStop -> SomeColor
_stopFraction :: GradientStop -> Double

-- | A color for the stop.
stopColor :: Lens' GradientStop SomeColor

-- | The fraction for stop.
stopFraction :: Lens' GradientStop Double

-- | A convenient function for making gradient stops from a list of
--   triples. (An opaque color, a stop fraction, an opacity).
mkStops :: [(Colour Double, Double, Double)] -> [GradientStop]

-- | The <a>SpreadMethod</a> determines what happens before
--   <a>lGradStart</a> and after <a>lGradEnd</a>. <a>GradPad</a> fills the
--   space before the start of the gradient with the color of the first
--   stop and the color after end of the gradient with the color of the
--   last stop. <a>GradRepeat</a> restarts the gradient and
--   <a>GradReflect</a> restarts the gradient with the stops in reverse
--   order.
data SpreadMethod
GradPad :: SpreadMethod
GradReflect :: SpreadMethod
GradRepeat :: SpreadMethod

-- | Apply a linear gradient.
lineLGradient :: (HasStyle a, V a ~ R2) => LGradient -> a -> a

-- | Apply a radial gradient.
lineRGradient :: (HasStyle a, V a ~ R2) => RGradient -> a -> a

-- | Linear Gradient
data LGradient
LGradient :: [GradientStop] -> P2 -> P2 -> T2 -> SpreadMethod -> LGradient
_lGradStops :: LGradient -> [GradientStop]
_lGradStart :: LGradient -> P2
_lGradEnd :: LGradient -> P2
_lGradTrans :: LGradient -> T2
_lGradSpreadMethod :: LGradient -> SpreadMethod

-- | A list of stops (colors and fractions).
lGradStops :: Lens' LGradient [GradientStop]

-- | A transformation to be applied to the gradient. Usually this field
--   will start as the identity transform and capture the transforms that
--   are applied to the gradient.
lGradTrans :: Lens' LGradient T2

-- | The starting point for the first gradient stop. The coordinates are in
--   <a>Local</a> units and the default is (-0.5, 0).
lGradStart :: Lens' LGradient P2

-- | The ending point for the last gradient stop.The coordinates are in
--   <a>Local</a> units and the default is (0.5, 0).
lGradEnd :: Lens' LGradient P2

-- | For setting the spread method.
lGradSpreadMethod :: Lens' LGradient SpreadMethod

-- | Make a linear gradient texture from a stop list, start point, end
--   point, and <a>SpreadMethod</a>. The <a>lGradTrans</a> field is set to
--   the identity transfrom, to change it use the <a>lGradTrans</a> lens.
mkLinearGradient :: [GradientStop] -> P2 -> P2 -> SpreadMethod -> Texture

-- | Radial Gradient
data RGradient
RGradient :: [GradientStop] -> P2 -> Double -> P2 -> Double -> T2 -> SpreadMethod -> RGradient
_rGradStops :: RGradient -> [GradientStop]
_rGradCenter0 :: RGradient -> P2
_rGradRadius0 :: RGradient -> Double
_rGradCenter1 :: RGradient -> P2
_rGradRadius1 :: RGradient -> Double
_rGradTrans :: RGradient -> T2
_rGradSpreadMethod :: RGradient -> SpreadMethod

-- | A list of stops (colors and fractions).
rGradStops :: Lens' RGradient [GradientStop]

-- | A transformation to be applied to the gradient. Usually this field
--   will start as the identity transform and capture the transforms that
--   are applied to the gradient.
rGradTrans :: Lens' RGradient T2

-- | The center point of the inner circle.
rGradCenter0 :: Lens' RGradient P2

-- | The radius of the inner cirlce in <a>Local</a> coordinates.
rGradRadius0 :: Lens' RGradient Double

-- | The center of the outer circle.
rGradCenter1 :: Lens' RGradient P2

-- | The radius of the outer circle in <a>Local</a> coordinates.
rGradRadius1 :: Lens' RGradient Double

-- | For setting the spread method.
rGradSpreadMethod :: Lens' RGradient SpreadMethod

-- | Make a radial gradient texture from a stop list, radius, start point,
--   end point, and <a>SpreadMethod</a>. The <a>rGradTrans</a> field is set
--   to the identity transfrom, to change it use the <a>rGradTrans</a>
--   lens.
mkRadialGradient :: [GradientStop] -> P2 -> Double -> P2 -> Double -> SpreadMethod -> Texture

-- | The texture with which lines are drawn. Note that child textures
--   always override parent textures. More precisely, the semigroup
--   structure on line texture attributes is that of <a>Last</a>.
newtype LineTexture
LineTexture :: (Last Texture) -> LineTexture
getLineTexture :: LineTexture -> Texture
lineTexture :: (HasStyle a, V a ~ R2) => Texture -> a -> a
lineTextureA :: (HasStyle a, V a ~ R2) => LineTexture -> a -> a
mkLineTexture :: Texture -> LineTexture
styleLineTexture :: Setter' (Style v) Texture

-- | Set the line (stroke) color. This function is polymorphic in the color
--   type (so it can be used with either <a>Colour</a> or
--   <a>AlphaColour</a>), but this can sometimes create problems for type
--   inference, so the <a>lc</a> and <a>lcA</a> variants are provided with
--   more concrete types.
lineColor :: (Color c, HasStyle a, V a ~ R2) => c -> a -> a

-- | A synonym for <a>lineColor</a>, specialized to <tt><a>Colour</a>
--   Double</tt> (i.e. opaque colors). See comment in <a>lineColor</a>
--   about backends.
lc :: (HasStyle a, V a ~ R2) => Colour Double -> a -> a

-- | A synonym for <a>lineColor</a>, specialized to <tt><a>AlphaColour</a>
--   Double</tt> (i.e. colors with transparency). See comment in
--   <a>lineColor</a> about backends.
lcA :: (HasStyle a, V a ~ R2) => AlphaColour Double -> a -> a

-- | The texture with which objects are filled. The semigroup structure on
--   fill texture attributes is that of 'Recommed . Last'.
newtype FillTexture
FillTexture :: (Recommend (Last Texture)) -> FillTexture
getFillTexture :: FillTexture -> Texture
fillTexture :: (HasStyle a, V a ~ R2) => Texture -> a -> a
mkFillTexture :: Texture -> FillTexture
styleFillTexture :: Setter' (Style v) Texture

-- | Set the fill color. This function is polymorphic in the color type (so
--   it can be used with either <a>Colour</a> or <a>AlphaColour</a>), but
--   this can sometimes create problems for type inference, so the
--   <a>fc</a> and <a>fcA</a> variants are provided with more concrete
--   types.
fillColor :: (Color c, HasStyle a, V a ~ R2) => c -> a -> a

-- | A synonym for <a>fillColor</a>, specialized to <tt><a>Colour</a>
--   Double</tt> (i.e. opaque colors). See comment after <a>fillColor</a>
--   about backends.
fc :: (HasStyle a, V a ~ R2) => Colour Double -> a -> a

-- | A synonym for <a>fillColor</a>, specialized to <tt><a>AlphaColour</a>
--   Double</tt> (i.e. colors with transparency). See comment after
--   <a>fillColor</a> about backends.
fcA :: (HasStyle a, V a ~ R2) => AlphaColour Double -> a -> a

-- | Set a "recommended" fill color, to be used only if no explicit calls
--   to <a>fillColor</a> (or <a>fc</a>, or <a>fcA</a>) are used. See
--   comment after <a>fillColor</a> about backends.
recommendFillColor :: (Color c, HasStyle a, V a ~ R2) => c -> a -> a

-- | Push fill attributes down until they are at the root of subtrees
--   containing only loops. This makes life much easier for backends, which
--   typically have a semantics where fill attributes are applied to
--   lines<i>non-closed paths as well as loops</i>closed paths, whereas in
--   the semantics of diagrams, fill attributes only apply to loops.
splitTextureFills :: Typeable v => RTree b v a -> RTree b v a
instance Typeable LineTexture
instance Typeable FillTexture
instance Semigroup LineTexture
instance Semigroup FillTexture
instance Typeable v => SplitAttribute (FillTextureLoops v)
instance Default FillTexture
instance Transformable FillTexture
instance AttributeClass FillTexture
instance Default LineTexture
instance Transformable LineTexture
instance AttributeClass LineTexture
instance Typeable Texture
instance Typeable LineWidth
instance Typeable Dashing
instance Typeable DashingA
instance Data LineWidth
instance Semigroup LineWidth
instance Data Dashing
instance Eq Dashing
instance Data DashingA
instance Semigroup DashingA
instance Eq DashingA
instance Transformable DashingA
instance AttributeClass DashingA
instance Default LineWidth
instance Transformable LineWidth
instance AttributeClass LineWidth


-- | Drawing arrows in two dimensions. For a tutorial on drawing arrows
--   using this module, see the diagrams website:
--   <a>http://projects.haskell.org/diagrams/doc/arrow.html</a>.
module Diagrams.TwoD.Arrow

-- | <tt>arrowV v</tt> creates an arrow with the direction and magnitude of
--   the vector <tt>v</tt> (with its tail at the origin), using default
--   parameters.
arrowV :: Renderable (Path R2) b => R2 -> Diagram b R2

-- | <tt>arrowV' v</tt> creates an arrow with the direction and magnitude
--   of the vector <tt>v</tt> (with its tail at the origin).
arrowV' :: Renderable (Path R2) b => ArrowOpts -> R2 -> Diagram b R2

-- | Create an arrow starting at s with length and direction determined by
--   the vector v.
arrowAt :: Renderable (Path R2) b => P2 -> R2 -> Diagram b R2
arrowAt' :: Renderable (Path R2) b => ArrowOpts -> P2 -> R2 -> Diagram b R2

-- | <tt>arrowBetween s e</tt> creates an arrow pointing from <tt>s</tt> to
--   <tt>e</tt> with default parameters.
arrowBetween :: Renderable (Path R2) b => P2 -> P2 -> Diagram b R2

-- | <tt>arrowBetween' opts s e</tt> creates an arrow pointing from
--   <tt>s</tt> to <tt>e</tt> using the given options. In particular, it
--   scales and rotates <tt>arrowShaft</tt> to go between <tt>s</tt> and
--   <tt>e</tt>, taking head, tail, and gaps into account.
arrowBetween' :: Renderable (Path R2) b => ArrowOpts -> P2 -> P2 -> Diagram b R2

-- | Connect two diagrams with a straight arrow.
connect :: (Renderable (Path R2) b, IsName n1, IsName n2) => n1 -> n2 -> (Diagram b R2 -> Diagram b R2)

-- | Connect two diagrams with an arbitrary arrow.
connect' :: (Renderable (Path R2) b, IsName n1, IsName n2) => ArrowOpts -> n1 -> n2 -> (Diagram b R2 -> Diagram b R2)

-- | Connect two diagrams at point on the perimeter of the diagrams,
--   choosen by angle.
connectPerim :: (Renderable (Path R2) b, IsName n1, IsName n2) => n1 -> n2 -> Angle -> Angle -> (Diagram b R2 -> Diagram b R2)
connectPerim' :: (Renderable (Path R2) b, IsName n1, IsName n2) => ArrowOpts -> n1 -> n2 -> Angle -> Angle -> (Diagram b R2 -> Diagram b R2)

-- | Draw an arrow from diagram named <a>n1</a> to diagram named <a>n2</a>.
--   The arrow lies on the line between the centres of the diagrams, but is
--   drawn so that it stops at the boundaries of the diagrams, using traces
--   to find the intersection points.
connectOutside :: (Renderable (Path R2) b, IsName n1, IsName n2) => n1 -> n2 -> (Diagram b R2 -> Diagram b R2)
connectOutside' :: (Renderable (Path R2) b, IsName n1, IsName n2) => ArrowOpts -> n1 -> n2 -> (Diagram b R2 -> Diagram b R2)

-- | <tt>arrow len</tt> creates an arrow of length <tt>len</tt> with
--   default parameters, starting at the origin and ending at the point
--   <tt>(len,0)</tt>.
arrow :: Renderable (Path R2) b => Double -> Diagram b R2

-- | <tt>arrow' opts len</tt> creates an arrow of length <tt>len</tt> using
--   the given options, starting at the origin and ending at the point
--   <tt>(len,0)</tt>. In particular, it scales the given <a>arrowShaft</a>
--   so that the entire arrow has length <tt>len</tt>.
arrow' :: Renderable (Path R2) b => ArrowOpts -> Double -> Diagram b R2
data ArrowOpts
ArrowOpts :: ArrowHT -> ArrowHT -> Trail R2 -> Measure R2 -> Measure R2 -> Style R2 -> Measure R2 -> Style R2 -> Measure R2 -> Style R2 -> ArrowOpts
_arrowHead :: ArrowOpts -> ArrowHT
_arrowTail :: ArrowOpts -> ArrowHT
_arrowShaft :: ArrowOpts -> Trail R2
_headGap :: ArrowOpts -> Measure R2
_tailGap :: ArrowOpts -> Measure R2
_headStyle :: ArrowOpts -> Style R2
_headLength :: ArrowOpts -> Measure R2
_tailStyle :: ArrowOpts -> Style R2
_tailLength :: ArrowOpts -> Measure R2
_shaftStyle :: ArrowOpts -> Style R2

-- | A shape to place at the head of the arrow.
arrowHead :: Lens' ArrowOpts ArrowHT

-- | A shape to place at the tail of the arrow.
arrowTail :: Lens' ArrowOpts ArrowHT

-- | The trail to use for the arrow shaft.
arrowShaft :: Lens' ArrowOpts (Trail R2)

-- | Distance to leave between the head and the target point.
headGap :: Lens' ArrowOpts (Measure R2)

-- | Distance to leave between the starting point and the tail.
tailGap :: Lens' ArrowOpts (Measure R2)

-- | Set both the <tt>headGap</tt> and <tt>tailGap</tt> simultaneously.
gaps :: Traversal' ArrowOpts (Measure R2)

-- | Same as gaps, provided for backward compatiiblity.
gap :: Traversal' ArrowOpts (Measure R2)

-- | A lens for setting or modifying the texture of an arrowhead. For
--   example, one may write <tt>... (with &amp; headTexture .~ grad)</tt>
--   to get an arrow with a head filled with a gradient, assuming grad has
--   been defined. Or <tt>... (with &amp; headTexture .~ solid blue</tt> to
--   set the head color to blue. For more general control over the style of
--   arrowheads, see <a>headStyle</a>.
headTexture :: Setter' ArrowOpts Texture

-- | Style to apply to the head. <tt>headStyle</tt> is modified by using
--   the lens combinator <tt>%~</tt> to change the current style. For
--   example, to change an opaque black arrowhead to translucent orange:
--   <tt>(with &amp; headStyle %~ fc orange . opacity 0.75)</tt>.
headStyle :: Lens' ArrowOpts (Style R2)

-- | The length from the start of the joint to the tip of the head.
headLength :: Lens' ArrowOpts (Measure R2)

-- | A lens for setting or modifying the texture of an arrow tail.
tailTexture :: Setter' ArrowOpts Texture

-- | Style to apply to the tail. See <a>headStyle</a>.
tailStyle :: Lens' ArrowOpts (Style R2)

-- | The length of the tail plus its joint.
tailLength :: Lens' ArrowOpts (Measure R2)

-- | Set both the <tt>headLength</tt> and <tt>tailLength</tt>
--   simultaneously.
lengths :: Traversal' ArrowOpts (Measure R2)

-- | A lens for setting or modifying the texture of an arrow shaft.
shaftTexture :: Setter' ArrowOpts Texture

-- | Style to apply to the shaft. See <a>headStyle</a>.
shaftStyle :: Lens' ArrowOpts (Style R2)

-- | Straight line arrow shaft.
straightShaft :: Trail R2
instance Default ArrowOpts


-- | Diagram combinators specialized to two dimensions. For more general
--   combinators, see <a>Diagrams.Combinators</a>.
module Diagrams.TwoD.Combinators

-- | Place two diagrams (or other objects) vertically adjacent to one
--   another, with the first diagram above the second. Since Haskell
--   ignores whitespace in expressions, one can thus write
--   
--   <pre>
--    c
--   ===
--    d
--   </pre>
--   
--   to place <tt>c</tt> above <tt>d</tt>. The local origin of the
--   resulting combined diagram is the same as the local origin of the
--   first. <tt>(===)</tt> is associative and has <a>mempty</a> as an
--   identity. See the documentation of <a>beside</a> for more information.
(===) :: (Juxtaposable a, V a ~ R2, Semigroup a) => a -> a -> a

-- | Place two diagrams (or other juxtaposable objects) horizontally
--   adjacent to one another, with the first diagram to the left of the
--   second. The local origin of the resulting combined diagram is the same
--   as the local origin of the first. <tt>(|||)</tt> is associative and
--   has <a>mempty</a> as an identity. See the documentation of
--   <a>beside</a> for more information.
(|||) :: (Juxtaposable a, V a ~ R2, Semigroup a) => a -> a -> a

-- | Place two diagrams (or other juxtaposable objects) adjacent to one
--   another, with the second diagram placed along a line at angle
--   <tt>th</tt> from the first. The local origin of the resulting combined
--   diagram is the same as the local origin of the first. See the
--   documentation of <a>beside</a> for more information.
atAngle :: (Juxtaposable a, V a ~ R2, Semigroup a) => Angle -> a -> a -> a

-- | Lay out a list of juxtaposable objects in a row from left to right, so
--   that their local origins lie along a single horizontal line, with
--   successive envelopes tangent to one another.
--   
--   <ul>
--   <li>For more control over the spacing, see <a>hcat'</a>.</li>
--   <li>To align the diagrams vertically (or otherwise), use alignment
--   combinators (such as <a>alignT</a> or <a>alignB</a>) from
--   <a>Diagrams.TwoD.Align</a> before applying <a>hcat</a>.</li>
--   <li>For non-axis-aligned layout, see <a>cat</a>.</li>
--   </ul>
hcat :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => [a] -> a

-- | A variant of <a>hcat</a> taking an extra <a>CatOpts</a> record to
--   control the spacing. See the <a>cat'</a> documentation for a
--   description of the possibilities.
hcat' :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => CatOpts R2 -> [a] -> a

-- | Lay out a list of juxtaposable objects in a column from top to bottom,
--   so that their local origins lie along a single vertical line, with
--   successive envelopes tangent to one another.
--   
--   <ul>
--   <li>For more control over the spacing, see <a>vcat'</a>.</li>
--   <li>To align the diagrams horizontally (or otherwise), use alignment
--   combinators (such as <a>alignL</a> or <a>alignR</a>) from
--   <a>Diagrams.TwoD.Align</a> before applying <a>vcat</a>.</li>
--   <li>For non-axis-aligned layout, see <a>cat</a>.</li>
--   </ul>
vcat :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => [a] -> a

-- | A variant of <a>vcat</a> taking an extra <a>CatOpts</a> record to
--   control the spacing. See the <a>cat'</a> documentation for a
--   description of the possibilities.
vcat' :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => CatOpts R2 -> [a] -> a

-- | <tt>strutR2 v</tt> is a two-dimensional diagram which produces no
--   output, but with respect to alignment, envelope, <i>and trace</i> acts
--   like a 1-dimensional segment oriented along the vector <tt>v</tt>,
--   with local origin at its center. If you don't care about the trace
--   then there's no difference between <tt>strutR2</tt> and the more
--   general <a>strut</a>.
strutR2 :: (Backend b R2, Monoid' m) => R2 -> QDiagram b R2 m

-- | <tt>strutX w</tt> is an empty diagram with width <tt>w</tt>, height 0,
--   and a centered local origin. Note that <tt>strutX (-w)</tt> behaves
--   the same as <tt>strutX w</tt>.
strutX :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m

-- | <tt>strutY h</tt> is an empty diagram with height <tt>h</tt>, width 0,
--   and a centered local origin. Note that <tt>strutY (-h)</tt> behaves
--   the same as <tt>strutY h</tt>.
strutY :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m

-- | <tt>padX s</tt> "pads" a diagram in the x-direction, expanding its
--   envelope horizontally by a factor of <tt>s</tt> (factors between 0 and
--   1 can be used to shrink the envelope). Note that the envelope will
--   expand with respect to the local origin, so if the origin is not
--   centered horizontally the padding may appear "uneven". If this is not
--   desired, the origin can be centered (using <a>centerX</a>) before
--   applying <tt>padX</tt>.
padX :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>padY s</tt> "pads" a diagram in the y-direction, expanding its
--   envelope vertically by a factor of <tt>s</tt> (factors between 0 and 1
--   can be used to shrink the envelope). Note that the envelope will
--   expand with respect to the local origin, so if the origin is not
--   centered vertically the padding may appear "uneven". If this is not
--   desired, the origin can be centered (using <a>centerY</a>) before
--   applying <tt>padY</tt>.
padY :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeLeft s</tt> "extrudes" a diagram in the negative
--   x-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeLeft :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeRight s</tt> "extrudes" a diagram in the positive
--   x-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeRight :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeBottom s</tt> "extrudes" a diagram in the negative
--   y-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeBottom :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeTop s</tt> "extrudes" a diagram in the positive
--   y-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeTop :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>view p v</tt> sets the envelope of a diagram to a rectangle whose
--   lower-left corner is at <tt>p</tt> and whose upper-right corner is at
--   <tt>p .+^ v</tt>. Useful for selecting the rectangular portion of a
--   diagram which should actually be "viewed" in the final render, if you
--   don't want to see the entire diagram.
view :: (Backend b R2, Monoid' m) => P2 -> R2 -> QDiagram b R2 m -> QDiagram b R2 m

-- | Construct a bounding rectangle for an enveloped object, that is, the
--   smallest axis-aligned rectangle which encloses the object.
boundingRect :: (Enveloped t, Transformable t, TrailLike t, Monoid t, V t ~ R2, Enveloped a, V a ~ R2) => a -> t

-- | "Set the background color" of a diagram. That is, place a diagram atop
--   a bounding rectangle of the given color.
bg :: Renderable (Path R2) b => Colour Double -> Diagram b R2 -> Diagram b R2


-- | Very basic text primitives along with associated attributes.
module Diagrams.TwoD.Text

-- | A text primitive consists of the string contents and alignment
--   specification, along with two transformations: the first accumulates
--   all transformations which have been applied to the text; the second
--   accumulates normalized, <a>anti-scaled</a> versions of the
--   transformations which have had their average scaling component
--   removed.
data Text
Text :: T2 -> T2 -> TextAlignment -> String -> Text

-- | <tt>TextAlignment</tt> specifies the alignment of the text's origin.
data TextAlignment
BaselineText :: TextAlignment
BoxAlignedText :: Double -> Double -> TextAlignment

-- | Create a primitive text diagram from the given string, with center
--   alignment, equivalent to <tt><a>alignedText</a> 0.5 0.5</tt>.
--   
--   Note that it <i>takes up no space</i>, as text size information is not
--   available.
text :: Renderable Text b => String -> Diagram b R2

-- | Create a primitive text diagram from the given string, origin at the
--   top left corner of the text's bounding box, equivalent to
--   <tt><a>alignedText</a> 0 1</tt>.
--   
--   Note that it <i>takes up no space</i>.
topLeftText :: Renderable Text b => String -> Diagram b R2

-- | Create a primitive text diagram from the given string, with the origin
--   set to a point interpolated within the bounding box. The first
--   parameter varies from 0 (left) to 1 (right), and the second parameter
--   from 0 (bottom) to 1 (top).
--   
--   The height of this box is determined by the font's potential ascent
--   and descent, rather than the height of the particular string.
--   
--   Note that it <i>takes up no space</i>.
alignedText :: Renderable Text b => Double -> Double -> String -> Diagram b R2

-- | Create a primitive text diagram from the given string, with the origin
--   set to be on the baseline, at the beginning (although not bounding).
--   This is the reference point of showText in the Cairo graphics library.
--   
--   Note that it <i>takes up no space</i>.
baselineText :: Renderable Text b => String -> Diagram b R2

-- | The <tt>Font</tt> attribute specifies the name of a font family. Inner
--   <tt>Font</tt> attributes override outer ones.
newtype Font
Font :: (Last String) -> Font

-- | Extract the font family name from a <tt>Font</tt> attribute.
getFont :: Font -> String

-- | Specify a font family to be used for all text within a diagram.
font :: HasStyle a => String -> a -> a

-- | The <tt>FontSize</tt> attribute specifies the size of a font's
--   em-square. Inner <tt>FontSize</tt> attributes override outer ones.
newtype FontSize
FontSize :: (Last (Measure R2, Bool)) -> FontSize

-- | Extract the size from a <tt>FontSize</tt> attribute.
getFontSize :: FontSize -> Measure R2

-- | Determine whether a <tt>FontSize</tt> attribute began its life
--   measured in <a>Local</a> units.
getFontSizeIsLocal :: FontSize -> Bool

-- | Apply a <a>FontSize</a> attribute.
fontSizeA :: (HasStyle a, V a ~ R2) => FontSize -> a -> a

-- | Set the font size, that is, the size of the font's em-square as
--   measured within the current local vector space. The default size is
--   <tt>1</tt>.
fontSize :: (HasStyle a, V a ~ R2) => Measure R2 -> a -> a

-- | A convenient synonym for 'fontSize (Normalized w)'.
fontSizeN :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'fontSize (Output w)'.
fontSizeO :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient sysnonym for 'fontSize (Local w)'.
fontSizeL :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'fontSize (Global w)'.
fontSizeG :: (HasStyle a, V a ~ R2) => Double -> a -> a
data FontSlant
FontSlantNormal :: FontSlant
FontSlantItalic :: FontSlant
FontSlantOblique :: FontSlant

-- | The <tt>FontSlantA</tt> attribute specifies the slant (normal, italic,
--   or oblique) that should be used for all text within a diagram. Inner
--   <tt>FontSlantA</tt> attributes override outer ones.
data FontSlantA

-- | Extract the font slant from a <a>FontSlantA</a> attribute.
getFontSlant :: FontSlantA -> FontSlant

-- | Specify the slant (normal, italic, or oblique) that should be used for
--   all text within a diagram. See also <a>italic</a> and <a>oblique</a>
--   for useful special cases.
fontSlant :: HasStyle a => FontSlant -> a -> a

-- | Set all text in italics.
italic :: HasStyle a => a -> a

-- | Set all text using an oblique slant.
oblique :: HasStyle a => a -> a
data FontWeight
FontWeightNormal :: FontWeight
FontWeightBold :: FontWeight

-- | The <tt>FontWeightA</tt> attribute specifies the weight (normal or
--   bold) that should be used for all text within a diagram. Inner
--   <tt>FontWeightA</tt> attributes override outer ones.
data FontWeightA

-- | Extract the font weight from a <a>FontWeightA</a> attribute.
getFontWeight :: FontWeightA -> FontWeight

-- | Specify the weight (normal or bold) that should be used for all text
--   within a diagram. See also <a>bold</a> for a useful special case.
fontWeight :: HasStyle a => FontWeight -> a -> a

-- | Set all text using a bold font weight.
bold :: HasStyle a => a -> a
instance Typeable Text
instance Typeable Font
instance Typeable FontSize
instance Typeable FontSlantA
instance Typeable FontWeightA
instance Semigroup Font
instance Eq Font
instance Data FontSize
instance Semigroup FontSize
instance Eq FontSlant
instance Semigroup FontSlantA
instance Eq FontSlantA
instance Eq FontWeight
instance Semigroup FontWeightA
instance Eq FontWeightA
instance AttributeClass FontWeightA
instance AttributeClass FontSlantA
instance Transformable FontSize
instance Default FontSize
instance AttributeClass FontSize
instance AttributeClass Font
instance Renderable Text NullBackend
instance HasOrigin Text
instance Transformable Text


-- | Tools for visualizing diagrams' internal model: local origins,
--   envelopes, <i>etc.</i>
module Diagrams.TwoD.Model

-- | Mark the origin of a diagram by placing a red dot 1/50th its size.
showOrigin :: (Renderable (Path R2) b, Backend b R2, Monoid' m) => QDiagram b R2 m -> QDiagram b R2 m

-- | Mark the origin of a diagram, with control over colour and scale of
--   marker dot.
showOrigin' :: (Renderable (Path R2) b, Backend b R2, Monoid' m) => OriginOpts -> QDiagram b R2 m -> QDiagram b R2 m
data OriginOpts
OriginOpts :: Colour Double -> Double -> Double -> OriginOpts
_oColor :: OriginOpts -> Colour Double
_oScale :: OriginOpts -> Double
_oMinSize :: OriginOpts -> Double
oColor :: Lens' OriginOpts (Colour Double)
oScale :: Lens' OriginOpts Double
oMinSize :: Lens' OriginOpts Double
showLabels :: (Renderable Text b, Backend b R2, Semigroup m) => QDiagram b R2 m -> QDiagram b R2 Any
instance Default OriginOpts


-- | Importing external images into diagrams. Usage: To create a diagram
--   from an embedded image with width 1 and height set according to the
--   aspect ratio: 'image img # scaleUToX 1` where <tt>img</tt> is a
--   'DImage Embedded'
module Diagrams.TwoD.Image

-- | An image primitive, the two ints are width followed by height. Will
--   typically be created by <tt>loadImageEmb</tt> or <tt>loadImageExt</tt>
--   which, will handle setting the width and heigh to the actual width and
--   height of the image.
data DImage :: * -> *
DImage :: ImageData t -> Int -> Int -> T2 -> DImage t

-- | <a>ImageData</a> is either a JuicyPixels <tt>DynamicImage</tt> tagged
--   as <a>Embedded</a> or a reference tagged as <a>External</a>.
data ImageData :: * -> *
ImageRaster :: DynamicImage -> ImageData Embedded
ImageRef :: FilePath -> ImageData External
data Embedded
data External

-- | Make a <a>DImage</a> into a <a>Diagram</a>.
image :: (Typeable a, Renderable (DImage a) b) => DImage a -> Diagram b R2

-- | Use JuicyPixels to read an image in any format and wrap it in a
--   <a>DImage</a>. The width and height of the image are set to their
--   actual values.
loadImageEmb :: FilePath -> IO (Either String (DImage Embedded))

-- | Check that a file exists, and use JuicyPixels to figure out the right
--   size, but save a reference to the image instead of the raster data
loadImageExt :: FilePath -> IO (Either String (DImage External))

-- | Make an <a>unchecked</a> image reference; have to specify a width and
--   height. Unless the aspect ratio of the external image is the w :: h,
--   then the image will be distorted.
uncheckedImageRef :: FilePath -> Int -> Int -> DImage External

-- | Create an image <a>from scratch</a> by specifying the pixel data
raster :: (Int -> Int -> AlphaColour Double) -> Int -> Int -> DImage Embedded

-- | Crate a diagram from raw raster data.
rasterDia :: Renderable (DImage Embedded) b => (Int -> Int -> AlphaColour Double) -> Int -> Int -> Diagram b R2
instance Typeable Embedded
instance Typeable External
instance Typeable1 DImage
instance Renderable (DImage a) NullBackend
instance HasOrigin (DImage a)
instance Transformable (DImage a)


-- | This module defines the two-dimensional vector space R^2,
--   two-dimensional transformations, and various predefined
--   two-dimensional shapes. This module re-exports useful functionality
--   from a group of more specific modules:
--   
--   <ul>
--   <li><a>Diagrams.TwoD.Types</a> defines basic types for two-dimensional
--   diagrams, including types representing the 2D Euclidean vector space
--   and various systems of angle measurement.</li>
--   <li><a>Diagrams.TwoD.Align</a> defines alignment combinators
--   specialized to two dimensions (see <a>Diagrams.Align</a> for more
--   general alignment).</li>
--   <li><a>Diagrams.TwoD.Combinators</a> defines ways of combining
--   diagrams specialized to two dimensions (see also
--   <a>Diagrams.Combinators</a> for more general combining).</li>
--   <li><a>Diagrams.TwoD.Transform</a> defines R^2-specific
--   transformations such as rotation by an angle, and scaling,
--   translation, and reflection in the X and Y directions.</li>
--   <li><a>Diagrams.TwoD.Ellipse</a> defines circles and ellipses.</li>
--   <li><a>Diagrams.TwoD.Arc</a> defines circular arcs.</li>
--   <li><a>Diagrams.TwoD.Path</a> exports various operations on
--   two-dimensional paths when viewed as regions of the plane.</li>
--   <li><a>Diagrams.TwoD.Polygons</a> defines general algorithms for
--   drawing various types of polygons.</li>
--   <li><a>Diagrams.TwoD.Shapes</a> defines other two-dimensional shapes,
--   e.g. various polygons.</li>
--   <li><a>Diagrams.TwoD.Arrow</a> contains tools for drawing arrows
--   between things.</li>
--   <li><a>Diagrams.TwoD.Text</a> defines primitive text diagrams.</li>
--   <li><a>Diagrams.TwoD.Image</a> allows importing external images into
--   diagrams.</li>
--   <li><a>Diagrams.TwoD.Vector</a> defines some special 2D vectors and
--   functions for converting between vectors and angles.</li>
--   <li><a>Diagrams.TwoD.Size</a> defines functions for working with the
--   size of 2D objects.</li>
--   <li><a>Diagrams.TwoD.Model</a> defines some aids for visualizing
--   diagrams' internal model (local origins, envelopes, etc.)</li>
--   </ul>
module Diagrams.TwoD

-- | The two-dimensional Euclidean vector space R^2. This type is
--   intentionally abstract.
--   
--   <ul>
--   <li>To construct a vector, use <a>r2</a>, or <a>^&amp;</a> (from
--   <a>Diagrams.Coordinates</a>):</li>
--   </ul>
--   
--   <pre>
--   r2 (3,4) :: R2
--   3 ^&amp; 4    :: R2
--   </pre>
--   
--   Note that <a>Diagrams.Coordinates</a> is not re-exported by
--   <a>Diagrams.Prelude</a> and must be explicitly imported.
--   
--   <ul>
--   <li>To construct the vector from the origin to a point <tt>p</tt>, use
--   <tt>p <a>.-.</a> <a>origin</a></tt>.</li>
--   <li>To convert a vector <tt>v</tt> into the point obtained by
--   following <tt>v</tt> from the origin, use <tt><a>origin</a> <a>.+^</a>
--   v</tt>.</li>
--   <li>To convert a vector back into a pair of components, use
--   <tt>unv2</tt> or <a>coords</a> (from <a>Diagrams.Coordinates</a>).
--   These are typically used in conjunction with the <tt>ViewPatterns</tt>
--   extension:</li>
--   </ul>
--   
--   <pre>
--   foo (unr2 -&gt; (x,y)) = ...
--   foo (coords -&gt; x :&amp; y) = ...
--   </pre>
data R2

-- | Construct a 2D vector from a pair of components. See also
--   <tt>&amp;</tt>.
r2 :: (Double, Double) -> R2

-- | Convert a 2D vector back into a pair of components. See also
--   <a>coords</a>.
unr2 :: R2 -> (Double, Double)

-- | Curried form of <a>r2</a>.
mkR2 :: Double -> Double -> R2

-- | Points in R^2. This type is intentionally abstract.
--   
--   <ul>
--   <li>To construct a point, use <a>p2</a>, or <a>^&amp;</a> (see
--   <a>Diagrams.Coordinates</a>):</li>
--   </ul>
--   
--   <pre>
--   p2 (3,4)  :: P2
--   3 ^&amp; 4    :: P2
--   </pre>
--   
--   <ul>
--   <li>To construct a point from a vector <tt>v</tt>, use
--   <tt><a>origin</a> <a>.+^</a> v</tt>.</li>
--   <li>To convert a point <tt>p</tt> into the vector from the origin to
--   <tt>p</tt>, use <tt>p <a>.-.</a> <a>origin</a></tt>.</li>
--   <li>To convert a point back into a pair of coordinates, use
--   <a>unp2</a>, or <a>coords</a> (from <a>Diagrams.Coordinates</a>). It's
--   common to use these in conjunction with the <tt>ViewPatterns</tt>
--   extension:</li>
--   </ul>
--   
--   <pre>
--   foo (unp2 -&gt; (x,y)) = ...
--   foo (coords -&gt; x :&amp; y) = ...
--   </pre>
type P2 = Point R2

-- | Construct a 2D point from a pair of coordinates. See also
--   <a>^&amp;</a>.
p2 :: (Double, Double) -> P2

-- | Convert a 2D point back into a pair of coordinates. See also
--   <a>coords</a>.
unp2 :: P2 -> (Double, Double)

-- | Curried form of <a>p2</a>.
mkP2 :: Double -> Double -> P2

-- | Transformations in R^2.
type T2 = Transformation R2

-- | The unit vector in the positive X direction.
unitX :: R2

-- | The unit vector in the positive Y direction.
unitY :: R2

-- | The unit vector in the negative X direction.
unit_X :: R2

-- | The unit vector in the negative Y direction.
unit_Y :: R2

-- | Compute the direction of a vector, measured counterclockwise from the
--   positive x-axis as a fraction of a full turn. The zero vector is
--   arbitrarily assigned the direction 0.
direction :: R2 -> Angle

-- | Convert an angle into a unit vector pointing in that direction.
fromDirection :: Angle -> R2

-- | The circle constant, the ratio of a circle's circumference to its
--   <i>radius</i>. Note that <tt>pi = tau/2</tt>.
--   
--   For more information and a well-reasoned argument why we should all be
--   using tau instead of pi, see <i>The Tau Manifesto</i>,
--   <a>http://tauday.com/</a>.
--   
--   To hear what it sounds like (and to easily memorize the first 30
--   digits or so), try <a>http://youtu.be/3174T-3-59Q</a>.
tau :: Floating a => a

-- | Convert a path into a diagram. The resulting diagram has the names 0,
--   1, ... assigned to each of the path's vertices.
--   
--   See also <a>stroke'</a>, which takes an extra options record allowing
--   its behavior to be customized.
--   
--   Note that a bug in GHC 7.0.1 causes a context stack overflow when
--   inferring the type of <tt>stroke</tt>. The solution is to give a type
--   signature to expressions involving <tt>stroke</tt>, or (recommended)
--   upgrade GHC (the bug is fixed in 7.0.2 onwards).
stroke :: Renderable (Path R2) b => Path R2 -> Diagram b R2

-- | A variant of <a>stroke</a> that takes an extra record of options to
--   customize its behavior. In particular:
--   
--   <ul>
--   <li>Names can be assigned to the path's vertices</li>
--   </ul>
--   
--   <a>StrokeOpts</a> is an instance of <a>Default</a>, so <tt>stroke'
--   (<tt>with</tt> &amp; ... )</tt> syntax may be used.
stroke' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Path R2 -> Diagram b R2

-- | A composition of <a>stroke</a> and <a>pathFromTrail</a> for
--   conveniently converting a trail directly into a diagram.
--   
--   Note that a bug in GHC 7.0.1 causes a context stack overflow when
--   inferring the type of <a>stroke</a> and hence of <tt>strokeTrail</tt>
--   as well. The solution is to give a type signature to expressions
--   involving <tt>strokeTrail</tt>, or (recommended) upgrade GHC (the bug
--   is fixed in 7.0.2 onwards).
strokeTrail :: Renderable (Path R2) b => Trail R2 -> Diagram b R2

-- | Deprecated synonym for <a>strokeTrail</a>.
strokeT :: Renderable (Path R2) b => Trail R2 -> Diagram b R2

-- | A composition of <a>stroke'</a> and <a>pathFromTrail</a> for
--   conveniently converting a trail directly into a diagram.
strokeTrail' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Trail R2 -> Diagram b R2

-- | Deprecated synonym for <a>strokeTrail'</a>.
strokeT' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Trail R2 -> Diagram b R2

-- | A composition of <a>strokeT</a> and <a>wrapLine</a> for conveniently
--   converting a line directly into a diagram.
strokeLine :: Renderable (Path R2) b => Trail' Line R2 -> Diagram b R2

-- | A composition of <a>strokeT</a> and <a>wrapLoop</a> for conveniently
--   converting a loop directly into a diagram.
strokeLoop :: Renderable (Path R2) b => Trail' Loop R2 -> Diagram b R2

-- | A convenience function for converting a <tt>Located Trail</tt>
--   directly into a diagram; <tt>strokeLocTrail = stroke . trailLike</tt>.
strokeLocTrail :: Renderable (Path R2) b => Located (Trail R2) -> Diagram b R2

-- | Deprecated synonym for <a>strokeLocTrail</a>.
strokeLocT :: Renderable (Path R2) b => Located (Trail R2) -> Diagram b R2

-- | A convenience function for converting a <tt>Located</tt> line directly
--   into a diagram; <tt>strokeLocLine = stroke . trailLike . mapLoc
--   wrapLine</tt>.
strokeLocLine :: Renderable (Path R2) b => Located (Trail' Line R2) -> Diagram b R2

-- | A convenience function for converting a <tt>Located</tt> loop directly
--   into a diagram; <tt>strokeLocLoop = stroke . trailLike . mapLoc
--   wrapLoop</tt>.
strokeLocLoop :: Renderable (Path R2) b => Located (Trail' Loop R2) -> Diagram b R2

-- | Enumeration of algorithms or "rules" for determining which points lie
--   in the interior of a (possibly self-intersecting) closed path.
data FillRule

-- | Interior points are those with a nonzero <i>winding</i> <i>number</i>.
--   See <a>http://en.wikipedia.org/wiki/Nonzero-rule</a>.
Winding :: FillRule

-- | Interior points are those where a ray extended infinitely in a
--   particular direction crosses the path an odd number of times. See
--   <a>http://en.wikipedia.org/wiki/Even-odd_rule</a>.
EvenOdd :: FillRule

-- | Specify the fill rule that should be used for determining which points
--   are inside a path.
fillRule :: HasStyle a => FillRule -> a -> a

-- | A record of options that control how a path is stroked.
--   <tt>StrokeOpts</tt> is an instance of <a>Default</a>, so a
--   <tt>StrokeOpts</tt> records can be created using <tt><tt>with</tt> {
--   ... }</tt> notation.
data StrokeOpts a
StrokeOpts :: [[a]] -> FillRule -> StrokeOpts a
_vertexNames :: StrokeOpts a -> [[a]]
_queryFillRule :: StrokeOpts a -> FillRule

-- | Atomic names that should be assigned to the vertices of the path so
--   that they can be referenced later. If there are not enough names, the
--   extra vertices are not assigned names; if there are too many, the
--   extra names are ignored. Note that this is a <i>list of lists</i> of
--   names, since paths can consist of multiple trails. The first list of
--   names are assigned to the vertices of the first trail, the second list
--   to the second trail, and so on.
--   
--   The default value is the empty list.
vertexNames :: Lens (StrokeOpts a) (StrokeOpts a') [[a]] [[a']]

-- | The fill rule used for determining which points are inside the path.
--   The default is <a>Winding</a>. NOTE: for now, this only affects the
--   resulting diagram's <a>Query</a>, <i>not</i> how it will be drawn! To
--   set the fill rule determining how it is to be drawn, use the
--   <a>fillRule</a> function.
queryFillRule :: Lens' (StrokeOpts a) FillRule

-- | Clip a diagram by the given path:
--   
--   <ul>
--   <li>Only the parts of the diagram which lie in the interior of the
--   path will be drawn.</li>
--   <li>The envelope of the diagram is unaffected.</li>
--   </ul>
clipBy :: (HasStyle a, V a ~ R2) => Path R2 -> a -> a

-- | Clip a diagram to the given path setting its envelope to the pointwise
--   minimum of the envelopes of the diagram and path. The trace consists
--   of those parts of the original diagram's trace which fall within the
--   clipping path, or parts of the path's trace within the original
--   diagram.
clipTo :: Renderable (Path R2) b => Path R2 -> Diagram b R2 -> Diagram b R2

-- | Clip a diagram to the clip path taking the envelope and trace of the
--   clip path.
clipped :: Renderable (Path R2) b => Path R2 -> Diagram b R2 -> Diagram b R2

-- | Create a centered horizontal (L-R) line of the given length.
--   
--   
--   <pre>
--   hruleEx = vcat' (with &amp; sep .~ 0.2) (map hrule [1..5])
--           # centerXY # pad 1.1
--   </pre>
hrule :: (TrailLike t, V t ~ R2) => Double -> t

-- | Create a centered vertical (T-B) line of the given length.
--   
--   
--   <pre>
--   vruleEx = hcat' (with &amp; sep .~ 0.2) (map vrule [1, 1.2 .. 2])
--           # centerXY # pad 1.1
--   </pre>
vrule :: (TrailLike t, V t ~ R2) => Double -> t

-- | A circle of radius 1, with center at the origin.
unitCircle :: (TrailLike t, V t ~ R2) => t

-- | A circle of the given radius, centered at the origin. As a path, it
--   begins at (r,0).
circle :: (TrailLike t, V t ~ R2, Transformable t) => Double -> t

-- | <tt>ellipse e</tt> constructs an ellipse with eccentricity <tt>e</tt>
--   by scaling the unit circle in the X direction. The eccentricity must
--   be within the interval [0,1).
ellipse :: (TrailLike t, V t ~ R2, Transformable t) => Double -> t

-- | <tt>ellipseXY x y</tt> creates an axis-aligned ellipse, centered at
--   the origin, with radius <tt>x</tt> along the x-axis and radius
--   <tt>y</tt> along the y-axis.
ellipseXY :: (TrailLike t, V t ~ R2, Transformable t) => Double -> Double -> t

-- | Given a start angle <tt>s</tt> and an end angle <tt>e</tt>,
--   <tt><a>arc</a> s e</tt> is the path of a radius one arc
--   counterclockwise between the two angles. The origin of the arc is its
--   center.
arc :: (TrailLike t, V t ~ R2) => Angle -> Angle -> t

-- | Given a radus <tt>r</tt>, a start angle <tt>s</tt> and an end angle
--   <tt>e</tt>, <tt><a>arc'</a> r s e</tt> is the path of a radius
--   <tt>(abs r)</tt> arc between the two angles. If a negative radius is
--   given, the arc will be clockwise, otherwise it will be
--   counterclockwise. The origin of the arc is its center.
--   
--   
--   <pre>
--   arc'Ex = mconcat [ arc' r (0 @@ turn) (1/4 @@ turn) | r &lt;- [0.5,-1,1.5] ]
--          # centerXY # pad 1.1
--   </pre>
arc' :: (TrailLike p, V p ~ R2) => Double -> Angle -> Angle -> p

-- | Like <a>arc</a> but clockwise.
arcCW :: (TrailLike t, V t ~ R2) => Angle -> Angle -> t

-- | Create a circular wedge of the given radius, beginning at the first
--   angle and extending counterclockwise to the second.
--   
--   
--   <pre>
--   wedgeEx = hcat' (with &amp; sep .~ 0.5)
--     [ wedge 1 (0 @@ turn) (1/4 @@ turn)
--     , wedge 1 (7/30 @@ turn) (11/30 @@ turn)
--     , wedge 1 (1/8 @@ turn) (7/8 @@ turn)
--     ]
--     # fc blue
--     # centerXY # pad 1.1
--   </pre>
wedge :: (TrailLike p, V p ~ R2) => Double -> Angle -> Angle -> p

-- | <tt>arcBetween p q height</tt> creates an arc beginning at <tt>p</tt>
--   and ending at <tt>q</tt>, with its midpoint at a distance of <tt>abs
--   height</tt> away from the straight line from <tt>p</tt> to <tt>q</tt>.
--   A positive value of <tt>height</tt> results in an arc to the left of
--   the line from <tt>p</tt> to <tt>q</tt>; a negative value yields one to
--   the right.
--   
--   
--   <pre>
--   arcBetweenEx = mconcat
--     [ arcBetween origin (p2 (2,1)) ht | ht &lt;- [-0.2, -0.1 .. 0.2] ]
--     # centerXY # pad 1.1
--   </pre>
arcBetween :: (TrailLike t, V t ~ R2) => P2 -> P2 -> Double -> t

-- | Create an annular wedge of the given radii, beginning at the first
--   angle and extending counterclockwise to the second. The radius of the
--   outer circle is given first.
--   
--   
--   <pre>
--   annularWedgeEx = hcat' (with &amp; sep .~ 0.50)
--     [ annularWedge 1 0.5 (0 @@ turn) (1/4 @@ turn)
--     , annularWedge 1 0.3 (7/30 @@ turn) (11/30 @@ turn)
--     , annularWedge 1 0.7 (1/8 @@ turn) (7/8 @@ turn)
--     ]
--     # fc blue
--     # centerXY # pad 1.1
--   </pre>
annularWedge :: (TrailLike p, V p ~ R2) => Double -> Double -> Angle -> Angle -> p

-- | Generate the polygon described by the given options.
polygon :: (TrailLike t, V t ~ R2) => PolygonOpts -> t

-- | Generate a polygon. See <a>PolygonOpts</a> for more information.
polyTrail :: PolygonOpts -> Located (Trail R2)

-- | Options for specifying a polygon.
data PolygonOpts
PolygonOpts :: PolyType -> PolyOrientation -> P2 -> PolygonOpts
_polyType :: PolygonOpts -> PolyType
_polyOrient :: PolygonOpts -> PolyOrientation
_polyCenter :: PolygonOpts -> P2

-- | Specification for the polygon's vertices.
polyType :: Lens' PolygonOpts PolyType

-- | Should a rotation be applied to the polygon in order to orient it in a
--   particular way?
polyOrient :: Lens' PolygonOpts PolyOrientation

-- | Should a translation be applied to the polygon in order to place the
--   center at a particular location?
polyCenter :: Lens' PolygonOpts P2

-- | Method used to determine the vertices of a polygon.
data PolyType

-- | A "polar" polygon.
--   
--   <ul>
--   <li>The first argument is a list of <i>central</i> <i>angles</i> from
--   each vertex to the next.</li>
--   <li>The second argument is a list of <i>radii</i> from the origin to
--   each successive vertex.</li>
--   </ul>
--   
--   To construct an <i>n</i>-gon, use a list of <i>n-1</i> angles and
--   <i>n</i> radii. Extra angles or radii are ignored.
--   
--   Cyclic polygons (with all vertices lying on a circle) can be
--   constructed using a second argument of <tt>(repeat r)</tt>.
PolyPolar :: [Angle] -> [Double] -> PolyType

-- | A polygon determined by the distance between successive vertices and
--   the angles formed by each three successive vertices. In other words, a
--   polygon specified by "turtle graphics": go straight ahead x1 units;
--   turn by angle a1; go straght ahead x2 units; turn by angle a2; etc.
--   The polygon will be centered at the <i>centroid</i> of its vertices.
--   
--   <ul>
--   <li>The first argument is a list of <i>vertex</i> <i>angles</i>,
--   giving the angle at each vertex from the previous vertex to the next.
--   The first angle in the list is the angle at the <i>second</i> vertex;
--   the first edge always starts out heading in the positive y direction
--   from the first vertex.</li>
--   <li>The second argument is a list of distances between successive
--   vertices.</li>
--   </ul>
--   
--   To construct an <i>n</i>-gon, use a list of <i>n-2</i> angles and
--   <i>n-1</i> edge lengths. Extra angles or lengths are ignored.
PolySides :: [Angle] -> [Double] -> PolyType

-- | A regular polygon with the given number of sides (first argument) and
--   the given radius (second argument).
PolyRegular :: Int -> Double -> PolyType

-- | Determine how a polygon should be oriented.
data PolyOrientation

-- | No special orientation; the first vertex will be at (1,0). This is the
--   default.
NoOrient :: PolyOrientation

-- | Orient <i>horizontally</i>, so the bottommost edge is parallel to the
--   x-axis.
OrientH :: PolyOrientation

-- | Orient <i>vertically</i>, so the leftmost edge is parallel to the
--   y-axis.
OrientV :: PolyOrientation

-- | Orient so some edge is <i>facing</i> <i>in</i> <i>the</i>
--   <i>direction</i> <i>of</i>, that is, perpendicular to, the given
--   vector.
OrientTo :: R2 -> PolyOrientation

-- | Options for creating "star" polygons, where the edges connect possibly
--   non-adjacent vertices.
data StarOpts

-- | Specify the order in which the vertices should be connected by a
--   function that maps each vertex index to the index of the vertex that
--   should come next. Indexing of vertices begins at 0.
StarFun :: (Int -> Int) -> StarOpts

-- | Specify a star polygon by a "skip". A skip of 1 indicates a normal
--   polygon, where edges go between successive vertices. A skip of 2 means
--   that edges will connect every second vertex, skipping one in between.
--   Generally, a skip of <i>n</i> means that edges will connect every
--   <i>n</i>th vertex.
StarSkip :: Int -> StarOpts

-- | Create a generalized <i>star</i> <i>polygon</i>. The <a>StarOpts</a>
--   are used to determine in which order the given vertices should be
--   connected. The intention is that the second argument of type
--   <tt>[P2]</tt> could be generated by a call to <a>polygon</a>,
--   <tt>regPoly</tt>, or the like, since a list of vertices is
--   <a>TrailLike</a>. But of course the list can be generated any way you
--   like. A <tt><a>Path</a> <a>R2</a></tt> is returned (instead of any
--   <a>TrailLike</a>) because the resulting path may have more than one
--   component, for example if the vertices are to be connected in several
--   disjoint cycles.
star :: StarOpts -> [P2] -> Path R2

-- | Create a regular polygon. The first argument is the number of sides,
--   and the second is the <i>length</i> of the sides. (Compare to the
--   <a>polygon</a> function with a <a>PolyRegular</a> option, which
--   produces polygons of a given <i>radius</i>).
--   
--   The polygon will be oriented with one edge parallel to the x-axis.
regPoly :: (TrailLike t, V t ~ R2) => Int -> Double -> t

-- | An equilateral triangle, with sides of the given length and base
--   parallel to the x-axis.
--   
triangle :: (TrailLike t, V t ~ R2) => Double -> t

-- | A synonym for <a>triangle</a>, provided for backwards compatibility.
eqTriangle :: (TrailLike t, V t ~ R2) => Double -> t

-- | A square with its center at the origin and sides of the given length,
--   oriented parallel to the axes.
--   
square :: (TrailLike t, Transformable t, V t ~ R2) => Double -> t

-- | A regular pentagon, with sides of the given length and base parallel
--   to the x-axis.
--   
pentagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular hexagon, with sides of the given length and base parallel to
--   the x-axis.
--   
hexagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular heptagon, with sides of the given length and base parallel
--   to the x-axis.
--   
heptagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A synonym for <a>heptagon</a>. It is, however, completely inferior,
--   being a base admixture of the Latin <i>septum</i> (seven) and the
--   Greek γωνία (angl
septagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular octagon, with sides of the given length and base parallel to
--   the x-axis.
--   
octagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular nonagon, with sides of the given length and base parallel to
--   the x-axis.
--   
nonagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular decagon, with sides of the given length and base parallel to
--   the x-axis.
--   
decagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular hendecagon, with sides of the given length and base parallel
--   to the x-axis.
--   
hendecagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A regular dodecagon, with sides of the given length and base parallel
--   to the x-axis.
--   
dodecagon :: (TrailLike t, V t ~ R2) => Double -> t

-- | A square with its center at the origin and sides of length 1, oriented
--   parallel to the axes.
--   
unitSquare :: (TrailLike t, V t ~ R2) => t

-- | <tt>rect w h</tt> is an axis-aligned rectangle of width <tt>w</tt> and
--   height <tt>h</tt>, centered at the origin.
--   
rect :: (TrailLike t, Transformable t, V t ~ R2) => Double -> Double -> t

-- | <tt>roundedRect w h r</tt> generates a closed trail, or closed path
--   centered at the origin, of an axis-aligned rectangle with width
--   <tt>w</tt>, height <tt>h</tt>, and circular rounded corners of radius
--   <tt>r</tt>. If <tt>r</tt> is negative the corner will be cut out in a
--   reverse arc. If the size of <tt>r</tt> is larger than half the smaller
--   dimension of <tt>w</tt> and <tt>h</tt>, then it will be reduced to fit
--   in that range, to prevent the corners from overlapping. The trail or
--   path begins with the right edge and proceeds counterclockwise. If you
--   need to specify a different radius for each corner individually, use
--   <a>roundedRect'</a> instead.
--   
--   
--   <pre>
--   roundedRectEx = pad 1.1 . centerXY $ hcat' (with &amp; sep .~ 0.2)
--     [ roundedRect  0.5 0.4 0.1
--     , roundedRect  0.5 0.4 (-0.1)
--     , roundedRect' 0.7 0.4 (with &amp; radiusTL .~ 0.2
--                                  &amp; radiusTR .~ -0.2
--                                  &amp; radiusBR .~ 0.1)
--     ]
--   </pre>
roundedRect :: (TrailLike t, V t ~ R2) => Double -> Double -> Double -> t

-- | <tt>roundedRect'</tt> works like <tt>roundedRect</tt> but allows you
--   to set the radius of each corner indivually, using
--   <tt>RoundedRectOpts</tt>. The default corner radius is 0. Each radius
--   can also be negative, which results in the curves being reversed to be
--   inward instead of outward.
roundedRect' :: (TrailLike t, V t ~ R2) => Double -> Double -> RoundedRectOpts -> t
data RoundedRectOpts
RoundedRectOpts :: Double -> Double -> Double -> Double -> RoundedRectOpts
_radiusTL :: RoundedRectOpts -> Double
_radiusTR :: RoundedRectOpts -> Double
_radiusBL :: RoundedRectOpts -> Double
_radiusBR :: RoundedRectOpts -> Double
radiusTL :: Lens' RoundedRectOpts Double
radiusTR :: Lens' RoundedRectOpts Double
radiusBL :: Lens' RoundedRectOpts Double
radiusBR :: Lens' RoundedRectOpts Double

-- | <tt>arrowV v</tt> creates an arrow with the direction and magnitude of
--   the vector <tt>v</tt> (with its tail at the origin), using default
--   parameters.
arrowV :: Renderable (Path R2) b => R2 -> Diagram b R2

-- | <tt>arrowV' v</tt> creates an arrow with the direction and magnitude
--   of the vector <tt>v</tt> (with its tail at the origin).
arrowV' :: Renderable (Path R2) b => ArrowOpts -> R2 -> Diagram b R2

-- | Create an arrow starting at s with length and direction determined by
--   the vector v.
arrowAt :: Renderable (Path R2) b => P2 -> R2 -> Diagram b R2
arrowAt' :: Renderable (Path R2) b => ArrowOpts -> P2 -> R2 -> Diagram b R2

-- | <tt>arrowBetween s e</tt> creates an arrow pointing from <tt>s</tt> to
--   <tt>e</tt> with default parameters.
arrowBetween :: Renderable (Path R2) b => P2 -> P2 -> Diagram b R2

-- | <tt>arrowBetween' opts s e</tt> creates an arrow pointing from
--   <tt>s</tt> to <tt>e</tt> using the given options. In particular, it
--   scales and rotates <tt>arrowShaft</tt> to go between <tt>s</tt> and
--   <tt>e</tt>, taking head, tail, and gaps into account.
arrowBetween' :: Renderable (Path R2) b => ArrowOpts -> P2 -> P2 -> Diagram b R2

-- | Connect two diagrams with a straight arrow.
connect :: (Renderable (Path R2) b, IsName n1, IsName n2) => n1 -> n2 -> (Diagram b R2 -> Diagram b R2)

-- | Connect two diagrams with an arbitrary arrow.
connect' :: (Renderable (Path R2) b, IsName n1, IsName n2) => ArrowOpts -> n1 -> n2 -> (Diagram b R2 -> Diagram b R2)

-- | Connect two diagrams at point on the perimeter of the diagrams,
--   choosen by angle.
connectPerim :: (Renderable (Path R2) b, IsName n1, IsName n2) => n1 -> n2 -> Angle -> Angle -> (Diagram b R2 -> Diagram b R2)
connectPerim' :: (Renderable (Path R2) b, IsName n1, IsName n2) => ArrowOpts -> n1 -> n2 -> Angle -> Angle -> (Diagram b R2 -> Diagram b R2)

-- | Draw an arrow from diagram named <a>n1</a> to diagram named <a>n2</a>.
--   The arrow lies on the line between the centres of the diagrams, but is
--   drawn so that it stops at the boundaries of the diagrams, using traces
--   to find the intersection points.
connectOutside :: (Renderable (Path R2) b, IsName n1, IsName n2) => n1 -> n2 -> (Diagram b R2 -> Diagram b R2)
connectOutside' :: (Renderable (Path R2) b, IsName n1, IsName n2) => ArrowOpts -> n1 -> n2 -> (Diagram b R2 -> Diagram b R2)

-- | <tt>arrow len</tt> creates an arrow of length <tt>len</tt> with
--   default parameters, starting at the origin and ending at the point
--   <tt>(len,0)</tt>.
arrow :: Renderable (Path R2) b => Double -> Diagram b R2

-- | <tt>arrow' opts len</tt> creates an arrow of length <tt>len</tt> using
--   the given options, starting at the origin and ending at the point
--   <tt>(len,0)</tt>. In particular, it scales the given <a>arrowShaft</a>
--   so that the entire arrow has length <tt>len</tt>.
arrow' :: Renderable (Path R2) b => ArrowOpts -> Double -> Diagram b R2

-- | Straight line arrow shaft.
straightShaft :: Trail R2
data ArrowOpts
ArrowOpts :: ArrowHT -> ArrowHT -> Trail R2 -> Measure R2 -> Measure R2 -> Style R2 -> Measure R2 -> Style R2 -> Measure R2 -> Style R2 -> ArrowOpts
_arrowHead :: ArrowOpts -> ArrowHT
_arrowTail :: ArrowOpts -> ArrowHT
_arrowShaft :: ArrowOpts -> Trail R2
_headGap :: ArrowOpts -> Measure R2
_tailGap :: ArrowOpts -> Measure R2
_headStyle :: ArrowOpts -> Style R2
_headLength :: ArrowOpts -> Measure R2
_tailStyle :: ArrowOpts -> Style R2
_tailLength :: ArrowOpts -> Measure R2
_shaftStyle :: ArrowOpts -> Style R2

-- | A shape to place at the head of the arrow.
arrowHead :: Lens' ArrowOpts ArrowHT

-- | A shape to place at the tail of the arrow.
arrowTail :: Lens' ArrowOpts ArrowHT

-- | The trail to use for the arrow shaft.
arrowShaft :: Lens' ArrowOpts (Trail R2)

-- | Distance to leave between the head and the target point.
headGap :: Lens' ArrowOpts (Measure R2)

-- | Distance to leave between the starting point and the tail.
tailGap :: Lens' ArrowOpts (Measure R2)

-- | Set both the <tt>headGap</tt> and <tt>tailGap</tt> simultaneously.
gaps :: Traversal' ArrowOpts (Measure R2)

-- | Same as gaps, provided for backward compatiiblity.
gap :: Traversal' ArrowOpts (Measure R2)

-- | A lens for setting or modifying the texture of an arrowhead. For
--   example, one may write <tt>... (with &amp; headTexture .~ grad)</tt>
--   to get an arrow with a head filled with a gradient, assuming grad has
--   been defined. Or <tt>... (with &amp; headTexture .~ solid blue</tt> to
--   set the head color to blue. For more general control over the style of
--   arrowheads, see <a>headStyle</a>.
headTexture :: Setter' ArrowOpts Texture

-- | Style to apply to the head. <tt>headStyle</tt> is modified by using
--   the lens combinator <tt>%~</tt> to change the current style. For
--   example, to change an opaque black arrowhead to translucent orange:
--   <tt>(with &amp; headStyle %~ fc orange . opacity 0.75)</tt>.
headStyle :: Lens' ArrowOpts (Style R2)

-- | A lens for setting or modifying the texture of an arrow tail.
tailTexture :: Setter' ArrowOpts Texture

-- | Style to apply to the tail. See <a>headStyle</a>.
tailStyle :: Lens' ArrowOpts (Style R2)

-- | A lens for setting or modifying the texture of an arrow shaft.
shaftTexture :: Setter' ArrowOpts Texture

-- | Style to apply to the shaft. See <a>headStyle</a>.
shaftStyle :: Lens' ArrowOpts (Style R2)

-- | The length from the start of the joint to the tip of the head.
headLength :: Lens' ArrowOpts (Measure R2)

-- | The length of the tail plus its joint.
tailLength :: Lens' ArrowOpts (Measure R2)

-- | Set both the <tt>headLength</tt> and <tt>tailLength</tt>
--   simultaneously.
lengths :: Traversal' ArrowOpts (Measure R2)

-- | Create a primitive text diagram from the given string, with center
--   alignment, equivalent to <tt><a>alignedText</a> 0.5 0.5</tt>.
--   
--   Note that it <i>takes up no space</i>, as text size information is not
--   available.
text :: Renderable Text b => String -> Diagram b R2

-- | Create a primitive text diagram from the given string, origin at the
--   top left corner of the text's bounding box, equivalent to
--   <tt><a>alignedText</a> 0 1</tt>.
--   
--   Note that it <i>takes up no space</i>.
topLeftText :: Renderable Text b => String -> Diagram b R2

-- | Create a primitive text diagram from the given string, with the origin
--   set to a point interpolated within the bounding box. The first
--   parameter varies from 0 (left) to 1 (right), and the second parameter
--   from 0 (bottom) to 1 (top).
--   
--   The height of this box is determined by the font's potential ascent
--   and descent, rather than the height of the particular string.
--   
--   Note that it <i>takes up no space</i>.
alignedText :: Renderable Text b => Double -> Double -> String -> Diagram b R2

-- | Create a primitive text diagram from the given string, with the origin
--   set to be on the baseline, at the beginning (although not bounding).
--   This is the reference point of showText in the Cairo graphics library.
--   
--   Note that it <i>takes up no space</i>.
baselineText :: Renderable Text b => String -> Diagram b R2

-- | Specify a font family to be used for all text within a diagram.
font :: HasStyle a => String -> a -> a

-- | Set all text in italics.
italic :: HasStyle a => a -> a

-- | Set all text using an oblique slant.
oblique :: HasStyle a => a -> a

-- | Set all text using a bold font weight.
bold :: HasStyle a => a -> a

-- | Set the font size, that is, the size of the font's em-square as
--   measured within the current local vector space. The default size is
--   <tt>1</tt>.
fontSize :: (HasStyle a, V a ~ R2) => Measure R2 -> a -> a

-- | A convenient synonym for 'fontSize (Output w)'.
fontSizeO :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient sysnonym for 'fontSize (Local w)'.
fontSizeL :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'fontSize (Normalized w)'.
fontSizeN :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'fontSize (Global w)'.
fontSizeG :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | An image primitive, the two ints are width followed by height. Will
--   typically be created by <tt>loadImageEmb</tt> or <tt>loadImageExt</tt>
--   which, will handle setting the width and heigh to the actual width and
--   height of the image.
data DImage :: * -> *
DImage :: ImageData t -> Int -> Int -> T2 -> DImage t

-- | <a>ImageData</a> is either a JuicyPixels <tt>DynamicImage</tt> tagged
--   as <a>Embedded</a> or a reference tagged as <a>External</a>.
data ImageData :: * -> *
ImageRaster :: DynamicImage -> ImageData Embedded
ImageRef :: FilePath -> ImageData External
data Embedded
data External

-- | Make a <a>DImage</a> into a <a>Diagram</a>.
image :: (Typeable a, Renderable (DImage a) b) => DImage a -> Diagram b R2

-- | Use JuicyPixels to read an image in any format and wrap it in a
--   <a>DImage</a>. The width and height of the image are set to their
--   actual values.
loadImageEmb :: FilePath -> IO (Either String (DImage Embedded))

-- | Check that a file exists, and use JuicyPixels to figure out the right
--   size, but save a reference to the image instead of the raster data
loadImageExt :: FilePath -> IO (Either String (DImage External))

-- | Make an <a>unchecked</a> image reference; have to specify a width and
--   height. Unless the aspect ratio of the external image is the w :: h,
--   then the image will be distorted.
uncheckedImageRef :: FilePath -> Int -> Int -> DImage External

-- | Create an image <a>from scratch</a> by specifying the pixel data
raster :: (Int -> Int -> AlphaColour Double) -> Int -> Int -> DImage Embedded

-- | Crate a diagram from raw raster data.
rasterDia :: Renderable (DImage Embedded) b => (Int -> Int -> AlphaColour Double) -> Int -> Int -> Diagram b R2

-- | Create a transformation which performs a rotation about the local
--   origin by the given angle. See also <a>rotate</a>.
rotation :: Angle -> T2

-- | Rotate about the local origin by the given angle. Positive angles
--   correspond to counterclockwise rotation, negative to clockwise. The
--   angle can be expressed using any of the <tt>Iso</tt>s on <a>Angle</a>.
--   For example, <tt>rotate (1/4 @@ <a>turn</a>)</tt>, <tt>rotate (tau/4
--   @@ rad)</tt>, and <tt>rotate (90 @@ deg)</tt> all represent the same
--   transformation, namely, a counterclockwise rotation by a right angle.
--   To rotate about some point other than the local origin, see
--   <a>rotateAbout</a>.
--   
--   Note that writing <tt>rotate (1/4)</tt>, with no <a>Angle</a>
--   constructor, will yield an error since GHC cannot figure out which
--   sort of angle you want to use. In this common situation you can use
--   <a>rotateBy</a>, which interprets its argument as a number of turns.
rotate :: (Transformable t, V t ~ R2) => Angle -> t -> t

-- | A synonym for <a>rotate</a>, interpreting its argument in units of
--   turns; it can be more convenient to write <tt>rotateBy (1/4)</tt> than
--   <tt><a>rotate</a> (1/4 @@ <a>turn</a>)</tt>.
rotateBy :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>rotationAbout p</tt> is a rotation about the point <tt>p</tt>
--   (instead of around the local origin).
rotationAbout :: P2 -> Angle -> T2

-- | <tt>rotateAbout p</tt> is like <a>rotate</a>, except it rotates around
--   the point <tt>p</tt> instead of around the local origin.
rotateAbout :: (Transformable t, V t ~ R2) => P2 -> Angle -> t -> t

-- | Construct a transformation which scales by the given factor in the x
--   (horizontal) direction.
scalingX :: Double -> T2

-- | Scale a diagram by the given factor in the x (horizontal) direction.
--   To scale uniformly, use <a>scale</a>.
scaleX :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Construct a transformation which scales by the given factor in the y
--   (vertical) direction.
scalingY :: Double -> T2

-- | Scale a diagram by the given factor in the y (vertical) direction. To
--   scale uniformly, use <a>scale</a>.
scaleY :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Create a uniform scaling transformation.
scaling :: (HasLinearMap v, Fractional (Scalar v)) => Scalar v -> Transformation v

-- | Scale uniformly in every dimension by the given scalar.
scale :: (Transformable t, Fractional (Scalar (V t)), Eq (Scalar (V t))) => Scalar (V t) -> t -> t

-- | <tt>scaleToX w</tt> scales a diagram in the x (horizontal) direction
--   by whatever factor required to make its width <tt>w</tt>.
--   <tt>scaleToX</tt> should not be applied to diagrams with a width of 0,
--   such as <tt>vrule</tt>.
scaleToX :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>scaleToY h</tt> scales a diagram in the y (vertical) direction by
--   whatever factor required to make its height <tt>h</tt>.
--   <tt>scaleToY</tt> should not be applied to diagrams with a height of
--   0, such as <tt>hrule</tt>.
scaleToY :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>scaleUToX w</tt> scales a diagram <i>uniformly</i> by whatever
--   factor required to make its width <tt>w</tt>. <tt>scaleUToX</tt>
--   should not be applied to diagrams with a width of 0, such as
--   <tt>vrule</tt>.
scaleUToX :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>scaleUToY h</tt> scales a diagram <i>uniformly</i> by whatever
--   factor required to make its height <tt>h</tt>. <tt>scaleUToY</tt>
--   should not be applied to diagrams with a height of 0, such as
--   <tt>hrule</tt>.
scaleUToY :: (Enveloped t, Transformable t, V t ~ R2) => Double -> t -> t

-- | Construct a transformation which translates by the given distance in
--   the x (horizontal) direction.
translationX :: Double -> T2

-- | Translate a diagram by the given distance in the x (horizontal)
--   direction.
translateX :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Construct a transformation which translates by the given distance in
--   the y (vertical) direction.
translationY :: Double -> T2

-- | Translate a diagram by the given distance in the y (vertical)
--   direction.
translateY :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | Create a translation.
translation :: HasLinearMap v => v -> Transformation v

-- | Translate by a vector.
translate :: (Transformable t, HasLinearMap (V t)) => V t -> t -> t

-- | Construct a transformation which flips a diagram from left to right,
--   i.e. sends the point (x,y) to (-x,y).
reflectionX :: T2

-- | Flip a diagram from left to right, i.e. send the point (x,y) to
--   (-x,y).
reflectX :: (Transformable t, V t ~ R2) => t -> t

-- | Construct a transformation which flips a diagram from top to bottom,
--   i.e. sends the point (x,y) to (x,-y).
reflectionY :: T2

-- | Flip a diagram from top to bottom, i.e. send the point (x,y) to
--   (x,-y).
reflectY :: (Transformable t, V t ~ R2) => t -> t

-- | <tt>reflectionAbout p v</tt> is a reflection in the line determined by
--   the point <tt>p</tt> and vector <tt>v</tt>.
reflectionAbout :: P2 -> R2 -> T2

-- | <tt>reflectAbout p v</tt> reflects a diagram in the line determined by
--   the point <tt>p</tt> and the vector <tt>v</tt>.
reflectAbout :: (Transformable t, V t ~ R2) => P2 -> R2 -> t -> t

-- | <tt>shearingX d</tt> is the linear transformation which is the
--   identity on y coordinates and sends <tt>(0,1)</tt> to <tt>(d,1)</tt>.
shearingX :: Double -> T2

-- | <tt>shearX d</tt> performs a shear in the x-direction which sends
--   <tt>(0,1)</tt> to <tt>(d,1)</tt>.
shearX :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | <tt>shearingY d</tt> is the linear transformation which is the
--   identity on x coordinates and sends <tt>(1,0)</tt> to <tt>(1,d)</tt>.
shearingY :: Double -> T2

-- | <tt>shearY d</tt> performs a shear in the y-direction which sends
--   <tt>(1,0)</tt> to <tt>(1,d)</tt>.
shearY :: (Transformable t, V t ~ R2) => Double -> t -> t

-- | The parallel projection onto the line x=0
parallelX0 :: Deformation R2

-- | The perspective division onto the line x=1 along lines going through
--   the origin.
perspectiveX1 :: Deformation R2

-- | The parallel projection onto the line y=0
parallelY0 :: Deformation R2

-- | The perspective division onto the line y=1 along lines going through
--   the origin.
perspectiveY1 :: Deformation R2

-- | The viewing transform for a viewer facing along the positive X axis. X
--   coördinates stay fixed, while Y coördinates are compressed with
--   increasing distance. <tt>asDeformation (translation unitX) <a></a>
--   parallelX0 <a></a> frustrumX = perspectiveX1</tt>
facingX :: Deformation R2
facingY :: Deformation R2

-- | Place two diagrams (or other objects) vertically adjacent to one
--   another, with the first diagram above the second. Since Haskell
--   ignores whitespace in expressions, one can thus write
--   
--   <pre>
--    c
--   ===
--    d
--   </pre>
--   
--   to place <tt>c</tt> above <tt>d</tt>. The local origin of the
--   resulting combined diagram is the same as the local origin of the
--   first. <tt>(===)</tt> is associative and has <a>mempty</a> as an
--   identity. See the documentation of <a>beside</a> for more information.
(===) :: (Juxtaposable a, V a ~ R2, Semigroup a) => a -> a -> a

-- | Place two diagrams (or other juxtaposable objects) horizontally
--   adjacent to one another, with the first diagram to the left of the
--   second. The local origin of the resulting combined diagram is the same
--   as the local origin of the first. <tt>(|||)</tt> is associative and
--   has <a>mempty</a> as an identity. See the documentation of
--   <a>beside</a> for more information.
(|||) :: (Juxtaposable a, V a ~ R2, Semigroup a) => a -> a -> a

-- | Place two diagrams (or other juxtaposable objects) adjacent to one
--   another, with the second diagram placed along a line at angle
--   <tt>th</tt> from the first. The local origin of the resulting combined
--   diagram is the same as the local origin of the first. See the
--   documentation of <a>beside</a> for more information.
atAngle :: (Juxtaposable a, V a ~ R2, Semigroup a) => Angle -> a -> a -> a

-- | Lay out a list of juxtaposable objects in a row from left to right, so
--   that their local origins lie along a single horizontal line, with
--   successive envelopes tangent to one another.
--   
--   <ul>
--   <li>For more control over the spacing, see <a>hcat'</a>.</li>
--   <li>To align the diagrams vertically (or otherwise), use alignment
--   combinators (such as <a>alignT</a> or <a>alignB</a>) from
--   <a>Diagrams.TwoD.Align</a> before applying <a>hcat</a>.</li>
--   <li>For non-axis-aligned layout, see <a>cat</a>.</li>
--   </ul>
hcat :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => [a] -> a

-- | A variant of <a>hcat</a> taking an extra <a>CatOpts</a> record to
--   control the spacing. See the <a>cat'</a> documentation for a
--   description of the possibilities.
hcat' :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => CatOpts R2 -> [a] -> a

-- | Lay out a list of juxtaposable objects in a column from top to bottom,
--   so that their local origins lie along a single vertical line, with
--   successive envelopes tangent to one another.
--   
--   <ul>
--   <li>For more control over the spacing, see <a>vcat'</a>.</li>
--   <li>To align the diagrams horizontally (or otherwise), use alignment
--   combinators (such as <a>alignL</a> or <a>alignR</a>) from
--   <a>Diagrams.TwoD.Align</a> before applying <a>vcat</a>.</li>
--   <li>For non-axis-aligned layout, see <a>cat</a>.</li>
--   </ul>
vcat :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => [a] -> a

-- | A variant of <a>vcat</a> taking an extra <a>CatOpts</a> record to
--   control the spacing. See the <a>cat'</a> documentation for a
--   description of the possibilities.
vcat' :: (Juxtaposable a, HasOrigin a, Monoid' a, V a ~ R2) => CatOpts R2 -> [a] -> a

-- | <tt>strutX w</tt> is an empty diagram with width <tt>w</tt>, height 0,
--   and a centered local origin. Note that <tt>strutX (-w)</tt> behaves
--   the same as <tt>strutX w</tt>.
strutX :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m

-- | <tt>strutY h</tt> is an empty diagram with height <tt>h</tt>, width 0,
--   and a centered local origin. Note that <tt>strutY (-h)</tt> behaves
--   the same as <tt>strutY h</tt>.
strutY :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m

-- | <tt>padX s</tt> "pads" a diagram in the x-direction, expanding its
--   envelope horizontally by a factor of <tt>s</tt> (factors between 0 and
--   1 can be used to shrink the envelope). Note that the envelope will
--   expand with respect to the local origin, so if the origin is not
--   centered horizontally the padding may appear "uneven". If this is not
--   desired, the origin can be centered (using <a>centerX</a>) before
--   applying <tt>padX</tt>.
padX :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>padY s</tt> "pads" a diagram in the y-direction, expanding its
--   envelope vertically by a factor of <tt>s</tt> (factors between 0 and 1
--   can be used to shrink the envelope). Note that the envelope will
--   expand with respect to the local origin, so if the origin is not
--   centered vertically the padding may appear "uneven". If this is not
--   desired, the origin can be centered (using <a>centerY</a>) before
--   applying <tt>padY</tt>.
padY :: (Backend b R2, Monoid' m) => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeLeft s</tt> "extrudes" a diagram in the negative
--   x-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeLeft :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeRight s</tt> "extrudes" a diagram in the positive
--   x-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeRight :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeBottom s</tt> "extrudes" a diagram in the negative
--   y-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeBottom :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>extrudeTop s</tt> "extrudes" a diagram in the positive
--   y-direction, offsetting its envelope by the provided distance. When
--   <tt> s &lt; 0 </tt>, the envelope is inset instead.
--   
--   See the documentation for <a>extrudeEnvelope</a> for more information.
extrudeTop :: Monoid' m => Double -> QDiagram b R2 m -> QDiagram b R2 m

-- | <tt>view p v</tt> sets the envelope of a diagram to a rectangle whose
--   lower-left corner is at <tt>p</tt> and whose upper-right corner is at
--   <tt>p .+^ v</tt>. Useful for selecting the rectangular portion of a
--   diagram which should actually be "viewed" in the final render, if you
--   don't want to see the entire diagram.
view :: (Backend b R2, Monoid' m) => P2 -> R2 -> QDiagram b R2 m -> QDiagram b R2 m

-- | Construct a bounding rectangle for an enveloped object, that is, the
--   smallest axis-aligned rectangle which encloses the object.
boundingRect :: (Enveloped t, Transformable t, TrailLike t, Monoid t, V t ~ R2, Enveloped a, V a ~ R2) => a -> t

-- | "Set the background color" of a diagram. That is, place a diagram atop
--   a bounding rectangle of the given color.
bg :: Renderable (Path R2) b => Colour Double -> Diagram b R2 -> Diagram b R2

-- | Align along the left edge, i.e. translate the diagram in a horizontal
--   direction so that the local origin is on the left edge of the
--   envelope.
alignL :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Align along the right edge.
alignR :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Align along the top edge.
alignT :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Align along the bottom edge.
alignB :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignTL :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignTR :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignBL :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
alignBR :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | <tt>alignX</tt> and <tt>snugX</tt> move the local origin horizontally
--   as follows:
--   
--   <ul>
--   <li><tt>alignX (-1)</tt> moves the local origin to the left edge of
--   the boundary;</li>
--   <li><tt>align 1</tt> moves the local origin to the right edge;</li>
--   <li>any other argument interpolates linearly between these. For
--   example, <tt>alignX 0</tt> centers, <tt>alignX 2</tt> moves the origin
--   one "radius" to the right of the right edge, and so on.</li>
--   <li><tt>snugX</tt> works the same way.</li>
--   </ul>
alignX :: (Alignable a, HasOrigin a, V a ~ R2) => Double -> a -> a

-- | Like <a>alignX</a>, but moving the local origin vertically, with an
--   argument of <tt>1</tt> corresponding to the top edge and <tt>(-1)</tt>
--   corresponding to the bottom edge.
alignY :: (Alignable a, HasOrigin a, V a ~ R2) => Double -> a -> a

-- | Center the local origin along the X-axis.
centerX :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Center the local origin along the Y-axis.
centerY :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a

-- | Center along both the X- and Y-axes.
centerXY :: (Alignable a, HasOrigin a, V a ~ R2) => a -> a
snugL :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugR :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugT :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugB :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugTL :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugTR :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugBL :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugBR :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a

-- | See the documentation for <a>alignX</a>.
snugX :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => Double -> a -> a
snugY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => Double -> a -> a
snugCenterX :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugCenterY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a
snugCenterXY :: (Fractional (Scalar (V a)), Alignable a, Traced a, HasOrigin a, V a ~ R2) => a -> a

-- | Compute the width of an enveloped object.
width :: (Enveloped a, V a ~ R2) => a -> Double

-- | Compute the height of an enveloped object.
height :: (Enveloped a, V a ~ R2) => a -> Double

-- | Compute the width and height of an enveloped object.
size2D :: (Enveloped a, V a ~ R2) => a -> (Double, Double)

-- | Compute the size of an enveloped object as a <a>SizeSpec2D</a> value.
sizeSpec2D :: (Enveloped a, V a ~ R2) => a -> SizeSpec2D

-- | Compute the absolute x-coordinate range of an enveloped object in R2,
--   in the form (lo,hi). Return <tt>Nothing</tt> for objects with an empty
--   envelope.
extentX :: (Enveloped a, V a ~ R2) => a -> Maybe (Double, Double)

-- | Compute the absolute y-coordinate range of an enveloped object in R2,
--   in the form (lo,hi).
extentY :: (Enveloped a, V a ~ R2) => a -> Maybe (Double, Double)

-- | Compute the point at the center (in the x- and y-directions) of a
--   enveloped object. Return the origin for objects with an empty
--   envelope.
center2D :: (Enveloped a, V a ~ R2) => a -> P2

-- | A specification of a (requested) rectangular size.
data SizeSpec2D

-- | Specify an explicit width. The height should be determined
--   automatically (so as to preserve aspect ratio).
Width :: !Double -> SizeSpec2D

-- | Specify an explicit height. The width should be determined
--   automatically (so as to preserve aspect ratio).
Height :: !Double -> SizeSpec2D

-- | An explicit specification of a width and height.
Dims :: !Double -> !Double -> SizeSpec2D

-- | Absolute size: use whatever size an object already has; do not
--   rescale.
Absolute :: SizeSpec2D

-- | Create a size specification from a possibly-specified width and
--   height.
mkSizeSpec :: Maybe Double -> Maybe Double -> SizeSpec2D

-- | Uniformly scale any enveloped object so that it fits within the given
--   size.
sized :: (Transformable a, Enveloped a, V a ~ R2) => SizeSpec2D -> a -> a

-- | Uniformly scale an enveloped object so that it "has the same size as"
--   (fits within the width and height of) some other object.
sizedAs :: (Transformable a, Enveloped a, V a ~ R2, Enveloped b, V b ~ R2) => b -> a -> a

-- | A Texture is either a color <a>SC</a>, linear gradient <a>LG</a>, or
--   radial gradient <a>RG</a>. An object can have only one texture which
--   is determined by the <a>Last</a> semigroup structure.
data Texture
SC :: SomeColor -> Texture
LG :: LGradient -> Texture
RG :: RGradient -> Texture

-- | Convert a solid colour into a texture.
solid :: Color a => a -> Texture

-- | The <a>SpreadMethod</a> determines what happens before
--   <a>lGradStart</a> and after <a>lGradEnd</a>. <a>GradPad</a> fills the
--   space before the start of the gradient with the color of the first
--   stop and the color after end of the gradient with the color of the
--   last stop. <a>GradRepeat</a> restarts the gradient and
--   <a>GradReflect</a> restarts the gradient with the stops in reverse
--   order.
data SpreadMethod
GradPad :: SpreadMethod
GradReflect :: SpreadMethod
GradRepeat :: SpreadMethod

-- | A gradient stop contains a color and fraction (usually between 0 and
--   1)
data GradientStop
GradientStop :: SomeColor -> Double -> GradientStop
_stopColor :: GradientStop -> SomeColor
_stopFraction :: GradientStop -> Double

-- | A convenient function for making gradient stops from a list of
--   triples. (An opaque color, a stop fraction, an opacity).
mkStops :: [(Colour Double, Double, Double)] -> [GradientStop]
getFillTexture :: FillTexture -> Texture
fillTexture :: (HasStyle a, V a ~ R2) => Texture -> a -> a
getLineTexture :: LineTexture -> Texture
lineTexture :: (HasStyle a, V a ~ R2) => Texture -> a -> a
lineTextureA :: (HasStyle a, V a ~ R2) => LineTexture -> a -> a

-- | The fraction for stop.
stopFraction :: Lens' GradientStop Double

-- | A color for the stop.
stopColor :: Lens' GradientStop SomeColor

-- | Linear Gradient
data LGradient
LGradient :: [GradientStop] -> P2 -> P2 -> T2 -> SpreadMethod -> LGradient
_lGradStops :: LGradient -> [GradientStop]
_lGradStart :: LGradient -> P2
_lGradEnd :: LGradient -> P2
_lGradTrans :: LGradient -> T2
_lGradSpreadMethod :: LGradient -> SpreadMethod

-- | A list of stops (colors and fractions).
lGradStops :: Lens' LGradient [GradientStop]

-- | A transformation to be applied to the gradient. Usually this field
--   will start as the identity transform and capture the transforms that
--   are applied to the gradient.
lGradTrans :: Lens' LGradient T2

-- | The starting point for the first gradient stop. The coordinates are in
--   <a>Local</a> units and the default is (-0.5, 0).
lGradStart :: Lens' LGradient P2

-- | The ending point for the last gradient stop.The coordinates are in
--   <a>Local</a> units and the default is (0.5, 0).
lGradEnd :: Lens' LGradient P2

-- | For setting the spread method.
lGradSpreadMethod :: Lens' LGradient SpreadMethod

-- | A default is provided so that linear gradients can easily be created
--   using lenses. For example, <tt>lg = defaultLG &amp; lGradStart .~
--   (0.25 ^&amp; 0.33)</tt>. Note that no default value is provided for
--   <tt>lGradStops</tt>, this must be set before the gradient value is
--   used, otherwise the object will appear transparent.
defaultLG :: Texture
_LG :: Prism' Texture LGradient

-- | Make a linear gradient texture from a stop list, start point, end
--   point, and <a>SpreadMethod</a>. The <a>lGradTrans</a> field is set to
--   the identity transfrom, to change it use the <a>lGradTrans</a> lens.
mkLinearGradient :: [GradientStop] -> P2 -> P2 -> SpreadMethod -> Texture

-- | Radial Gradient
data RGradient
RGradient :: [GradientStop] -> P2 -> Double -> P2 -> Double -> T2 -> SpreadMethod -> RGradient
_rGradStops :: RGradient -> [GradientStop]
_rGradCenter0 :: RGradient -> P2
_rGradRadius0 :: RGradient -> Double
_rGradCenter1 :: RGradient -> P2
_rGradRadius1 :: RGradient -> Double
_rGradTrans :: RGradient -> T2
_rGradSpreadMethod :: RGradient -> SpreadMethod

-- | A list of stops (colors and fractions).
rGradStops :: Lens' RGradient [GradientStop]

-- | The center point of the inner circle.
rGradCenter0 :: Lens' RGradient P2

-- | The radius of the inner cirlce in <a>Local</a> coordinates.
rGradRadius0 :: Lens' RGradient Double

-- | The center of the outer circle.
rGradCenter1 :: Lens' RGradient P2

-- | The radius of the outer circle in <a>Local</a> coordinates.
rGradRadius1 :: Lens' RGradient Double

-- | A transformation to be applied to the gradient. Usually this field
--   will start as the identity transform and capture the transforms that
--   are applied to the gradient.
rGradTrans :: Lens' RGradient T2

-- | For setting the spread method.
rGradSpreadMethod :: Lens' RGradient SpreadMethod

-- | A default is provided so that radial gradients can easily be created
--   using lenses. For example, <tt>rg = defaultRG &amp; rGradRadius1 .~
--   0.25</tt>. Note that no default value is provided for
--   <tt>rGradStops</tt>, this must be set before the gradient value is
--   used, otherwise the object will appear transparent.
defaultRG :: Texture
_RG :: Prism' Texture RGradient

-- | Make a radial gradient texture from a stop list, radius, start point,
--   end point, and <a>SpreadMethod</a>. The <a>rGradTrans</a> field is set
--   to the identity transfrom, to change it use the <a>rGradTrans</a>
--   lens.
mkRadialGradient :: [GradientStop] -> P2 -> Double -> P2 -> Double -> SpreadMethod -> Texture

-- | Set the fill color. This function is polymorphic in the color type (so
--   it can be used with either <a>Colour</a> or <a>AlphaColour</a>), but
--   this can sometimes create problems for type inference, so the
--   <a>fc</a> and <a>fcA</a> variants are provided with more concrete
--   types.
fillColor :: (Color c, HasStyle a, V a ~ R2) => c -> a -> a

-- | A synonym for <a>fillColor</a>, specialized to <tt><a>Colour</a>
--   Double</tt> (i.e. opaque colors). See comment after <a>fillColor</a>
--   about backends.
fc :: (HasStyle a, V a ~ R2) => Colour Double -> a -> a

-- | A synonym for <a>fillColor</a>, specialized to <tt><a>AlphaColour</a>
--   Double</tt> (i.e. colors with transparency). See comment after
--   <a>fillColor</a> about backends.
fcA :: (HasStyle a, V a ~ R2) => AlphaColour Double -> a -> a

-- | Set a "recommended" fill color, to be used only if no explicit calls
--   to <a>fillColor</a> (or <a>fc</a>, or <a>fcA</a>) are used. See
--   comment after <a>fillColor</a> about backends.
recommendFillColor :: (Color c, HasStyle a, V a ~ R2) => c -> a -> a

-- | Set the line (stroke) color. This function is polymorphic in the color
--   type (so it can be used with either <a>Colour</a> or
--   <a>AlphaColour</a>), but this can sometimes create problems for type
--   inference, so the <a>lc</a> and <a>lcA</a> variants are provided with
--   more concrete types.
lineColor :: (Color c, HasStyle a, V a ~ R2) => c -> a -> a

-- | A synonym for <a>lineColor</a>, specialized to <tt><a>Colour</a>
--   Double</tt> (i.e. opaque colors). See comment in <a>lineColor</a>
--   about backends.
lc :: (HasStyle a, V a ~ R2) => Colour Double -> a -> a

-- | A synonym for <a>lineColor</a>, specialized to <tt><a>AlphaColour</a>
--   Double</tt> (i.e. colors with transparency). See comment in
--   <a>lineColor</a> about backends.
lcA :: (HasStyle a, V a ~ R2) => AlphaColour Double -> a -> a
_SC :: Prism' Texture SomeColor

-- | Line widths specified on child nodes always override line widths
--   specified at parent nodes.
data LineWidth
getLineWidth :: LineWidth -> Measure R2

-- | Set the line (stroke) width.
lineWidth :: (HasStyle a, V a ~ R2) => Measure R2 -> a -> a

-- | Apply a <a>LineWidth</a> attribute.
lineWidthA :: (HasStyle a, V a ~ R2) => LineWidth -> a -> a

-- | Default for <a>lineWidth</a>.
lw :: (HasStyle a, V a ~ R2) => Measure R2 -> a -> a

-- | A convenient synonym for 'lineWidth (Normalized w)'.
lwN :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'lineWidth (Output w)'.
lwO :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient sysnonym for 'lineWidth (Local w)'.
lwL :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | A convenient synonym for 'lineWidth (Global w)'.
lwG :: (HasStyle a, V a ~ R2) => Double -> a -> a

-- | Standard <tt>Measures</tt>.
ultraThin :: Measure R2

-- | Standard <tt>Measures</tt>.
veryThin :: Measure R2

-- | Standard <tt>Measures</tt>.
thin :: Measure R2

-- | Standard <tt>Measures</tt>.
medium :: Measure R2

-- | Standard <tt>Measures</tt>.
thick :: Measure R2

-- | Standard <tt>Measures</tt>.
veryThick :: Measure R2

-- | Standard <tt>Measures</tt>.
ultraThick :: Measure R2

-- | Standard <tt>Measures</tt>.
none :: Measure R2

-- | Standard <tt>Measures</tt>.
tiny :: Measure R2

-- | Standard <tt>Measures</tt>.
verySmall :: Measure R2

-- | Standard <tt>Measures</tt>.
small :: Measure R2

-- | Standard <tt>Measures</tt>.
normal :: Measure R2

-- | Standard <tt>Measures</tt>.
large :: Measure R2

-- | Standard <tt>Measures</tt>.
veryLarge :: Measure R2

-- | Standard <tt>Measures</tt>.
huge :: Measure R2

-- | Create lines that are dashing... er, dashed.
data Dashing
Dashing :: [Measure R2] -> (Measure R2) -> Dashing
data DashingA
getDashing :: DashingA -> Dashing

-- | Set the line dashing style.
dashing :: (HasStyle a, V a ~ R2) => [Measure R2] -> Measure R2 -> a -> a

-- | A convenient synonym for 'dashing (Output w)'.
dashingO :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | A convenient sysnonym for 'dashing (Local w)'.
dashingL :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | A convenient synonym for 'dashing (Normalized w)'.
dashingN :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | A convenient synonym for 'dashing (Global w)'.
dashingG :: (HasStyle a, V a ~ R2) => [Double] -> Double -> a -> a

-- | Mark the origin of a diagram by placing a red dot 1/50th its size.
showOrigin :: (Renderable (Path R2) b, Backend b R2, Monoid' m) => QDiagram b R2 m -> QDiagram b R2 m

-- | Mark the origin of a diagram, with control over colour and scale of
--   marker dot.
showOrigin' :: (Renderable (Path R2) b, Backend b R2, Monoid' m) => OriginOpts -> QDiagram b R2 m -> QDiagram b R2 m
data OriginOpts
OriginOpts :: Colour Double -> Double -> Double -> OriginOpts
_oColor :: OriginOpts -> Colour Double
_oScale :: OriginOpts -> Double
_oMinSize :: OriginOpts -> Double
oColor :: Lens' OriginOpts (Colour Double)
oScale :: Lens' OriginOpts Double
oMinSize :: Lens' OriginOpts Double
showLabels :: (Renderable Text b, Backend b R2, Semigroup m) => QDiagram b R2 m -> QDiagram b R2 Any


-- | Compute offsets to segments in two dimensions. More details can be
--   found in the manual at
--   <a>http://projects.haskell.org/diagrams/doc/manual.html#offsets-of-segments-trails-and-paths</a>.
module Diagrams.TwoD.Offset
offsetSegment :: Double -> Double -> Segment Closed R2 -> Located (Trail R2)

-- | Compute the offset of a segment. Given a segment compute the offset
--   curve that is a fixed distance from the original curve. For linear
--   segments nothing special happens, the same linear segment is returned
--   with a point that is offset by a perpendicular vector of the given
--   offset length.
--   
--   Cubic segments require a search for a subdivision of cubic segments
--   that gives an approximation of the offset within the given epsilon
--   factor (the given epsilon factor is applied to the radius giving a
--   concrete epsilon value). We must do this because the offset of a cubic
--   is not a cubic itself (the degree of the curve increases). Cubics do,
--   however, approach constant curvature as we subdivide. In light of this
--   we scale the handles of the offset cubic segment in proportion to the
--   radius of curvature difference between the original subsegment and the
--   offset which will have a radius increased by the offset parameter.
--   
--   In the following example the blue lines are the original segments and
--   the alternating green and red lines are the resulting offset trail
--   segments.
--   
--   
--   Note that when the original curve has a cusp, the offset curve forms a
--   radius around the cusp, and when there is a loop in the original
--   curve, there can be two cusps in the offset curve.
--   
--   Options for specifying line join and segment epsilon for an offset
--   involving multiple segments.
data OffsetOpts
OffsetOpts :: LineJoin -> Double -> Double -> OffsetOpts
_offsetJoin :: OffsetOpts -> LineJoin
_offsetMiterLimit :: OffsetOpts -> Double
_offsetEpsilon :: OffsetOpts -> Double

-- | Specifies the style of join for between adjacent offset segments.
offsetJoin :: Lens' OffsetOpts LineJoin

-- | Specifies the miter limit for the join.
offsetMiterLimit :: Lens' OffsetOpts Double

-- | Epsilon perimeter for <a>offsetSegment</a>.
offsetEpsilon :: Lens' OffsetOpts Double

-- | Offset a <a>Trail</a> with the default options and a given radius. See
--   <a>offsetTrail'</a>.
offsetTrail :: Double -> Located (Trail R2) -> Located (Trail R2)

-- | Offset a <a>Trail</a> with options and by a given radius. This
--   generates a new trail that is always radius <tt>r</tt> away from the
--   given <a>Trail</a> (depending on the line join option) on the right.
--   
--   The styles applied to an outside corner can be seen here (with the
--   original trail in blue and the result of <a>offsetTrail'</a> in
--   green):
--   
--   
--   When a negative radius is given, the offset trail will be on the left:
--   
--   
--   When offseting a counter-clockwise loop a positive radius gives an
--   outer loop while a negative radius gives an inner loop (both
--   counter-clockwise).
--   
offsetTrail' :: OffsetOpts -> Double -> Located (Trail R2) -> Located (Trail R2)

-- | Offset a <a>Path</a> with the default options and given radius. See
--   <a>offsetPath'</a>.
offsetPath :: Double -> Path R2 -> Path R2

-- | Offset a <a>Path</a> by applying <a>offsetTrail'</a> to each trail in
--   the path.
offsetPath' :: OffsetOpts -> Double -> Path R2 -> Path R2

-- | Options for specifying how a <a>Trail</a> should be expanded.
data ExpandOpts
ExpandOpts :: LineJoin -> Double -> LineCap -> Double -> ExpandOpts
_expandJoin :: ExpandOpts -> LineJoin
_expandMiterLimit :: ExpandOpts -> Double
_expandCap :: ExpandOpts -> LineCap
_expandEpsilon :: ExpandOpts -> Double

-- | Specifies the style of join for between adjacent offset segments.
expandJoin :: Lens' ExpandOpts LineJoin

-- | Specifies the miter limit for the join.
expandMiterLimit :: Lens' ExpandOpts Double

-- | Specifies how the ends are handled.
expandCap :: Lens' ExpandOpts LineCap

-- | Epsilon perimeter for <a>offsetSegment</a>.
expandEpsilon :: Lens' ExpandOpts Double

-- | Expand a <a>Trail</a> with the given radius and default options. See
--   <a>expandTrail'</a>.
expandTrail :: Double -> Located (Trail R2) -> Path R2

-- | Expand a <a>Trail</a> with the given options and radius <tt>r</tt>
--   around a given <a>Trail</a>. Expanding can be thought of as generating
--   the loop that, when filled, represents stroking the trail with a
--   radius <tt>r</tt> brush.
--   
--   The cap styles applied to an outside corner can be seen here (with the
--   original trail in white and the result of <a>expandTrail'</a> filled
--   in green):
--   
--   
--   Loops result in a path with an inner and outer loop:
--   
expandTrail' :: ExpandOpts -> Double -> Located (Trail R2) -> Path R2

-- | Expand a <a>Path</a> with the given radius and default options. See
--   <a>expandPath'</a>.
expandPath :: Double -> Path R2 -> Path R2

-- | Expand a <a>Path</a> using <a>expandTrail'</a> on each trail in the
--   path.
expandPath' :: ExpandOpts -> Double -> Path R2 -> Path R2
instance Default ExpandOpts
instance Eq ExpandOpts
instance Show ExpandOpts
instance Default OffsetOpts
instance Eq OffsetOpts
instance Show OffsetOpts


-- | A default diagram-adjustment implementation for two-dimensional
--   diagrams, useful for backend implementors.
module Diagrams.TwoD.Adjust

-- | Set default attributes of a 2D diagram (in case they have not been
--   set):
--   
--   <ul>
--   <li>Line width 0.01</li>
--   <li>Line color black</li>
--   <li>Font size 1</li>
--   <li>Line cap LineCapButt</li>
--   <li>line join miter</li>
--   <li>Miter limit 10</li>
--   </ul>
setDefault2DAttributes :: Semigroup m => QDiagram b R2 m -> QDiagram b R2 m

-- | Adjust the size and position of a 2D diagram to fit within the
--   requested size. The first argument is a lens into the output size
--   contained in the rendering options. Returns an updated options record,
--   any transformation applied to the diagram (the inverse of which can be
--   used, say, to translate output/device coordinates back into local
--   diagram coordinates), and the modified diagram itself.
adjustDiaSize2D :: Monoid' m => Lens' (Options b R2) SizeSpec2D -> b -> Options b R2 -> QDiagram b R2 m -> (Options b R2, T2, QDiagram b R2 m)

-- | <tt>adjustDia2D</tt> provides a useful default implementation of the
--   <a>adjustDia</a> method from the <a>Backend</a> type class.
--   
--   As its first argument it requires a lens into the output size
--   contained in the rendering options.
--   
--   It then performs the following adjustments:
--   
--   <ul>
--   <li>Set default attributes (see <a>setDefault2DAttributes</a>)</li>
--   <li>Scale and translate the diagram to fit within the requested size
--   (see <a>adjustDiaSize2D</a>)</li>
--   </ul>
--   
--   It returns an updated options record, any transformation applied to
--   the diagram (the inverse of which can be used, say, to translate
--   output/device coordinates back into local diagram coordinates), and
--   the modified diagram itself.
adjustDia2D :: Monoid' m => Lens' (Options b R2) SizeSpec2D -> b -> Options b R2 -> QDiagram b R2 m -> (Options b R2, T2, QDiagram b R2 m)


-- | Convenient creation of command-line-driven executables for rendering
--   diagrams. This module provides a general framework and default
--   behaviors for parsing command-line arguments, records for diagram
--   creation options in various forms, and classes and instances for a
--   unified entry point to command-line-driven diagram creation
--   executables.
--   
--   For a tutorial on command-line diagram creation see
--   <a>http://projects.haskell.org/diagrams/doc/cmdline.html</a>.
module Diagrams.Backend.CmdLine

-- | Standard options most diagrams are likely to have.
data DiagramOpts
DiagramOpts :: Maybe Int -> Maybe Int -> FilePath -> DiagramOpts

-- | Final output width of diagram.
_width :: DiagramOpts -> Maybe Int

-- | Final output height of diagram.
_height :: DiagramOpts -> Maybe Int

-- | Output file path, format is typically chosen by extension.
_output :: DiagramOpts -> FilePath

-- | Command line parser for <a>DiagramOpts</a>. Width is option
--   <tt>--width</tt> or <tt>-w</tt>. Height is option <tt>--height</tt> or
--   <tt>-h</tt> (note we change help to be <tt>-?</tt> due to this).
--   Output is option <tt>--output</tt> or <tt>-o</tt>.
diagramOpts :: Parser DiagramOpts
width :: Lens' DiagramOpts (Maybe Int)
height :: Lens' DiagramOpts (Maybe Int)
output :: Lens' DiagramOpts FilePath

-- | Extra options for a program that can offer a choice between multiple
--   diagrams.
data DiagramMultiOpts
DiagramMultiOpts :: Maybe String -> Bool -> DiagramMultiOpts

-- | Selected diagram to render.
_selection :: DiagramMultiOpts -> Maybe String

-- | Flag to indicate that a list of available diagrams should be printed
--   to standard out.
_list :: DiagramMultiOpts -> Bool

-- | Command line parser for <a>DiagramMultiOpts</a>. Selection is option
--   <tt>--selection</tt> or <tt>-s</tt>. List is <tt>--list</tt> or
--   <tt>-l</tt>.
diagramMultiOpts :: Parser DiagramMultiOpts
selection :: Lens' DiagramMultiOpts (Maybe String)
list :: Lens' DiagramMultiOpts Bool

-- | Extra options for animations.
data DiagramAnimOpts
DiagramAnimOpts :: Double -> DiagramAnimOpts

-- | Number of frames per unit time to generate for the animation.
_fpu :: DiagramAnimOpts -> Double

-- | Command line parser for <a>DiagramAnimOpts</a> Frames per unit is
--   <tt>--fpu</tt> or <tt>-f</tt>.
diagramAnimOpts :: Parser DiagramAnimOpts
fpu :: Iso' DiagramAnimOpts Double

-- | Extra options for command-line looping.
data DiagramLoopOpts
DiagramLoopOpts :: Bool -> Maybe FilePath -> Int -> DiagramLoopOpts

-- | Flag to indicate that the program should loop creation.
_loop :: DiagramLoopOpts -> Bool

-- | File path for the source file to recompile.
_src :: DiagramLoopOpts -> Maybe FilePath

-- | Interval in seconds at which to check for recompilation.
_interval :: DiagramLoopOpts -> Int

-- | CommandLine parser for <a>DiagramLoopOpts</a> Loop is <tt>--loop</tt>
--   or <tt>-l</tt>. Source is <tt>--src</tt> or <tt>-s</tt>. Interval is
--   <tt>-i</tt> defaulting to one second.
diagramLoopOpts :: Parser DiagramLoopOpts
loop :: Lens' DiagramLoopOpts Bool
src :: Lens' DiagramLoopOpts (Maybe FilePath)
interval :: Lens' DiagramLoopOpts Int

-- | Parseable instances give a command line parser for a type. If a custom
--   parser for a common type is wanted a newtype wrapper could be used to
--   make a new <a>Parseable</a> instance. Notice that we do <i>not</i>
--   want as many instances as <a>Read</a> because we want to limit
--   ourselves to things that make sense to parse from the command line.
class Parseable a
parser :: Parseable a => Parser a

-- | Parses a hexadecimal color. The string can start with <tt>"0x"</tt> or
--   <tt>"#"</tt> or just be a string of hexadecimal values. If four or
--   three digits are given each digit is repeated to form a full 24 or 32
--   bit color. For example, <tt>"0xfc4"</tt> is the same as
--   <tt>"0xffcc44"</tt>. When eight or six digits are given each pair of
--   digits is a color or alpha channel with the order being red, green,
--   blue, alpha.
readHexColor :: String -> Maybe (AlphaColour Double)

-- | This class represents the various ways we want to support diagram
--   creation from the command line. It has the right instances to select
--   between creating single static diagrams, multiple static diagrams,
--   static animations, and functions that produce diagrams as long as the
--   arguments are <a>Parseable</a>.
--   
--   Backends are expected to create <tt>Mainable</tt> instances for the
--   types that are suitable for generating output in the backend's format.
--   For instance, Postscript can handle single diagrams, pages of
--   diagrams, animations as separate files, and association lists. This
--   implies instances for <tt>Diagram Postscript R2</tt>, <tt>[Diagram
--   Postscript R2]</tt>, <tt>Animation Postscript R2</tt>, and
--   <tt>[(String,Diagram Postscript R2)]</tt>. We can consider these as
--   the base cases for the function instance.
--   
--   The associated type <a>MainOpts</a> describes the options which need
--   to be parsed from the command-line and passed to <tt>mainRender</tt>.
class Mainable d where type family MainOpts d :: * mainArgs _ = defaultOpts parser mainWith d = do { opts <- mainArgs d; mainRender opts d }
mainArgs :: (Mainable d, Parseable (MainOpts d)) => d -> IO (MainOpts d)
mainRender :: Mainable d => MainOpts d -> d -> IO ()
mainWith :: (Mainable d, Parseable (MainOpts d)) => d -> IO ()

-- | This class allows us to abstract over functions that take some
--   arguments and produce a final value. When some <tt>d</tt> is an
--   instance of <a>ToResult</a> we get a type <tt><a>Args</a> d</tt> that
--   is a type of <i>all</i> the arguments at once, and a type
--   <tt><a>ResultOf</a> d</tt> that is the type of the final result from
--   some base case instance.
class ToResult d where type family Args d :: * type family ResultOf d :: *
toResult :: ToResult d => d -> Args d -> ResultOf d

-- | <tt>defaultAnimMainRender</tt> is an implementation of
--   <a>mainRender</a> which renders an animation as numbered frames, named
--   by extending the given output file name by consecutive integers. For
--   example if the given output file name is <tt>foo/blah.ext</tt>, the
--   frames will be saved in <tt>foo/blah001.ext</tt>,
--   <tt>foo/blah002.ext</tt>, and so on (the number of padding digits used
--   depends on the total number of frames). It is up to the user to take
--   these images and stitch them together into an actual animation format
--   (using, <i>e.g.</i> <tt>ffmpeg</tt>).
--   
--   Of course, this is a rather crude method of rendering animations; more
--   sophisticated methods will likely be added in the future.
--   
--   The <tt>fpu</tt> option from <a>DiagramAnimOpts</a> can be used to
--   control how many frames will be output for each second (unit time) of
--   animation.
--   
--   This function requires a lens into the structure that the particular
--   backend uses for it's diagram base case. If <tt>MainOpts (Diagram b v)
--   ~ DiagramOpts</tt> then this lens will simply be <a>output</a>. For a
--   backend supporting looping it will most likely be <tt>_1 .
--   output</tt>. This lens is required because the implementation works by
--   modifying the output field and running the base <tt>mainRender</tt>.
--   Typically a backend can write its <tt>Animation B V</tt> instance as
--   
--   <pre>
--   instance Mainable (Animation B V) where
--       type MainOpts (Animation B V) = (DiagramOpts, DiagramAnimOpts)
--       mainRender = defaultAnimMainRender output
--   </pre>
--   
--   We do not provide this instance in general so that backends can choose
--   to opt-in to this form or provide a different instance that makes more
--   sense.
defaultAnimMainRender :: Mainable (Diagram b v) => (Lens' (MainOpts (Diagram b v)) FilePath) -> (MainOpts (Diagram b v), DiagramAnimOpts) -> Animation b v -> IO ()

-- | <tt>defaultMultiMainRender</tt> is an implementation of
--   <a>mainRender</a> where instead of a single diagram it takes a list of
--   diagrams paired with names as input. The generated executable then
--   takes a <tt>--selection</tt> option specifying the name of the diagram
--   that should be rendered. The list of available diagrams may also be
--   printed by passing the option <tt>--list</tt>.
--   
--   Typically a backend can write its <tt>[(String,Diagram B V)]</tt>
--   instance as
--   
--   <pre>
--   instance Mainable [(String,Diagram B V)] where
--       type MainOpts [(String,Diagram B V)] = (DiagramOpts, DiagramMultiOpts)
--       mainRender = defaultMultiMainRender
--   </pre>
--   
--   We do not provide this instance in general so that backends can choose
--   to opt-in to this form or provide a different instance that makes more
--   sense.
defaultMultiMainRender :: Mainable d => (MainOpts d, DiagramMultiOpts) -> [(String, d)] -> IO ()
instance Mainable d => Mainable (IO d)
instance (Parseable (Args (a -> d)), ToResult d, Mainable (ResultOf d)) => Mainable (a -> d)
instance ToResult d => ToResult (a -> d)
instance ToResult d => ToResult (IO d)
instance ToResult (Animation b v)
instance ToResult [(String, Diagram b v)]
instance ToResult [Diagram b v]
instance ToResult (Diagram b v)
instance (Parseable a, Parseable b) => Parseable (a, b)
instance Parseable ()
instance Parseable (AlphaColour Double)
instance Parseable (Colour Double)
instance Parseable DiagramLoopOpts
instance Parseable DiagramAnimOpts
instance Parseable DiagramMultiOpts
instance Parseable DiagramOpts
instance Parseable String
instance Parseable Double
instance Parseable Int
instance Typeable DiagramAnimOpts
instance Show DiagramAnimOpts
instance Data DiagramAnimOpts
instance Typeable DiagramMultiOpts
instance Show DiagramMultiOpts
instance Data DiagramMultiOpts
instance Typeable DiagramOpts
instance Show DiagramOpts
instance Data DiagramOpts


-- | A module to re-export most of the functionality of the diagrams core
--   and standard library.
module Diagrams.Prelude

-- | Passes the result of the left side to the function on the right side
--   (forward pipe operator).
--   
--   This is the flipped version of (<a>$</a>), which is more common in
--   languages like F# as (<tt>|&gt;</tt>) where it is needed for
--   inference. Here it is supplied for notational convenience and given a
--   precedence that allows it to be nested inside uses of (<a>$</a>).
--   
--   <pre>
--   &gt;&gt;&gt; a &amp; f
--   f a
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; "hello" &amp; length &amp; succ
--   6
--   </pre>
--   
--   This combinator is commonly used when applying multiple <a>Lens</a>
--   operations in sequence.
--   
--   <pre>
--   &gt;&gt;&gt; ("hello","world") &amp; _1.element 0 .~ 'j' &amp; _1.element 4 .~ 'y'
--   ("jelly","world")
--   </pre>
--   
--   This reads somewhat similar to:
--   
--   <pre>
--   &gt;&gt;&gt; flip execState ("hello","world") $ do _1.element 0 .= 'j'; _1.element 4 .= 'y'
--   ("jelly","world")
--   </pre>
(&) :: a -> (a -> b) -> b

-- | Replace the target of a <a>Lens</a> or all of the targets of a
--   <a>Setter</a> or <a>Traversal</a> with a constant value.
--   
--   This is an infix version of <a>set</a>, provided for consistency with
--   (<a>.=</a>).
--   
--   <pre>
--   f <a>&lt;$</a> a ≡ <a>mapped</a> <a>.~</a> f <a>$</a> a
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b,c,d) &amp; _4 .~ e
--   (a,b,c,e)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (42,"world") &amp; _1 .~ "hello"
--   ("hello","world")
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b) &amp; both .~ c
--   (c,c)
--   </pre>
--   
--   <pre>
--   (<a>.~</a>) :: <a>Setter</a> s t a b    -&gt; b -&gt; s -&gt; t
--   (<a>.~</a>) :: <a>Iso</a> s t a b       -&gt; b -&gt; s -&gt; t
--   (<a>.~</a>) :: <a>Lens</a> s t a b      -&gt; b -&gt; s -&gt; t
--   (<a>.~</a>) :: <a>Traversal</a> s t a b -&gt; b -&gt; s -&gt; t
--   </pre>
(.~) :: ASetter s t a b -> b -> s -> t

-- | Modifies the target of a <a>Lens</a> or all of the targets of a
--   <a>Setter</a> or <a>Traversal</a> with a user supplied function.
--   
--   This is an infix version of <a>over</a>.
--   
--   <pre>
--   <a>fmap</a> f ≡ <a>mapped</a> <a>%~</a> f
--   <a>fmapDefault</a> f ≡ <a>traverse</a> <a>%~</a> f
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b,c) &amp; _3 %~ f
--   (a,b,f c)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; (a,b) &amp; both %~ f
--   (f a,f b)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; _2 %~ length $ (1,"hello")
--   (1,5)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; traverse %~ f $ [a,b,c]
--   [f a,f b,f c]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; traverse %~ even $ [1,2,3]
--   [False,True,False]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; traverse.traverse %~ length $ [["hello","world"],["!!!"]]
--   [[5,5],[3]]
--   </pre>
--   
--   <pre>
--   (<a>%~</a>) :: <a>Setter</a> s t a b    -&gt; (a -&gt; b) -&gt; s -&gt; t
--   (<a>%~</a>) :: <a>Iso</a> s t a b       -&gt; (a -&gt; b) -&gt; s -&gt; t
--   (<a>%~</a>) :: <a>Lens</a> s t a b      -&gt; (a -&gt; b) -&gt; s -&gt; t
--   (<a>%~</a>) :: <a>Traversal</a> s t a b -&gt; (a -&gt; b) -&gt; s -&gt; t
--   </pre>
(%~) :: Profunctor p => Setting p s t a b -> p a b -> s -> t

-- | A functor with application, providing operations to
--   
--   <ul>
--   <li>embed pure expressions (<a>pure</a>), and</li>
--   <li>sequence computations and combine their results
--   (<a>&lt;*&gt;</a>).</li>
--   </ul>
--   
--   A minimal complete definition must include implementations of these
--   functions satisfying the following laws:
--   
--   <ul>
--   <li><i><i>identity</i></i> <tt><a>pure</a> <a>id</a> <a>&lt;*&gt;</a>
--   v = v</tt></li>
--   <li><i><i>composition</i></i> <tt><a>pure</a> (.) <a>&lt;*&gt;</a> u
--   <a>&lt;*&gt;</a> v <a>&lt;*&gt;</a> w = u <a>&lt;*&gt;</a> (v
--   <a>&lt;*&gt;</a> w)</tt></li>
--   <li><i><i>homomorphism</i></i> <tt><a>pure</a> f <a>&lt;*&gt;</a>
--   <a>pure</a> x = <a>pure</a> (f x)</tt></li>
--   <li><i><i>interchange</i></i> <tt>u <a>&lt;*&gt;</a> <a>pure</a> y =
--   <a>pure</a> (<a>$</a> y) <a>&lt;*&gt;</a> u</tt></li>
--   </ul>
--   
--   The other methods have the following default definitions, which may be
--   overridden with equivalent specialized implementations:
--   
--   <pre>
--   u <a>*&gt;</a> v = <a>pure</a> (<a>const</a> <a>id</a>) <a>&lt;*&gt;</a> u <a>&lt;*&gt;</a> v
--   u <a>&lt;*</a> v = <a>pure</a> <a>const</a> <a>&lt;*&gt;</a> u <a>&lt;*&gt;</a> v
--   </pre>
--   
--   As a consequence of these laws, the <a>Functor</a> instance for
--   <tt>f</tt> will satisfy
--   
--   <pre>
--   <a>fmap</a> f x = <a>pure</a> f <a>&lt;*&gt;</a> x
--   </pre>
--   
--   If <tt>f</tt> is also a <a>Monad</a>, it should satisfy
--   <tt><a>pure</a> = <a>return</a></tt> and <tt>(<a>&lt;*&gt;</a>) =
--   <a>ap</a></tt> (which implies that <a>pure</a> and <a>&lt;*&gt;</a>
--   satisfy the applicative functor laws).
class Functor f => Applicative (f :: * -> *)
pure :: Applicative f => a -> f a
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(*>) :: Applicative f => f a -> f b -> f b
(<*) :: Applicative f => f a -> f b -> f a

-- | Sequence actions, discarding the value of the first argument.
(*>) :: Applicative f => forall a b. f a -> f b -> f b

-- | Sequence actions, discarding the value of the second argument.
(<*) :: Applicative f => forall a b. f a -> f b -> f a

-- | An infix synonym for <a>fmap</a>.
(<$>) :: Functor f => (a -> b) -> f a -> f b

-- | Replace all locations in the input with the same value. The default
--   definition is <tt><a>fmap</a> . <a>const</a></tt>, but this may be
--   overridden with a more efficient version.
(<$) :: Functor f => forall a b. a -> f b -> f a

-- | Lift a function to actions. This function may be used as a value for
--   <a>fmap</a> in a <a>Functor</a> instance.
liftA :: Applicative f => (a -> b) -> f a -> f b

-- | Lift a binary function to actions.
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

-- | Lift a ternary function to actions.
liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
