-- 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 0.6.0.1


-- | 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]]


-- | 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

-- | A value of <tt>Proxy a</tt> carries no information; it's used only to
--   fix the type <tt>a</tt>.
data Proxy a
Proxy :: Proxy 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;= 3) 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.
cubForm :: (Floating d, Ord d) => d -> d -> d -> d -> [d]


-- | 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)


-- | Some convenient functions related to transformations.
module Diagrams.Transform

-- | 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>rotationBy</tt> (-1/8 :: CircleFrac)</tt> is the
--   transformation which scales by a factor of 2 along the diagonal line y
--   = x.
--   
--   Note that
--   
--   <pre>
--   (transform t2) `under` t1 == transform (conjugate t1 t2)
--   </pre>
--   
--   for all transformations <tt>t1</tt> and <tt>t2</tt>.
under :: Transformable a => (a -> a) -> Transformation (V a) -> a -> a


-- | A <i>segment</i> is a translation-invariant, atomic path. 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.Path</a> should usually suffice instead. However, directly
--   manipulating segments can occasionally be useful.
module Diagrams.Segment

-- | The atomic constituents of paths are <i>segments</i>, which are 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 v

-- | A linear segment with given offset.
Linear :: v -> Segment 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 -> v -> Segment 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 v

-- | <tt>bezier3 v1 v2 v3</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>v1</tt>, <tt>v2</tt>, and <tt>v3</tt>.
bezier3 :: v -> v -> v -> Segment v

-- | <a>atParam</a> yields a parametrized view of segments as continuous
--   functions <tt>[0,1] -&gt; v</tt>, which give the offset from the start
--   of the segment for each value of the parameter between <tt>0</tt> and
--   <tt>1</tt>. It is designed to be used infix, like <tt>seg
--   `<a>atParam</a>` 0.5</tt>.
atParam :: (VectorSpace v, Num (Scalar v)) => Segment v -> Scalar v -> 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 v -> v

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

-- | <a>splitAtParam</a> splits a segment <tt>s</tt> into two new segments
--   <tt>(l,r)</tt> at the parameter <tt>t</tt> where <tt>l</tt>
--   corresponds to the portion of <tt>s</tt> for parameter values from
--   <tt>0</tt> to <tt>t</tt> and <tt>r</tt> for <tt>s</tt> from <tt>t</tt>
--   to <tt>1</tt>. The following should hold for splitting:
--   
--   <pre>
--   paramSplit s t u
--     | u &lt; t     = atParam s u == atParam l (u / t)
--     | otherwise = atParam s u == atParam s t ^+^ atParam l ((u - t) / (1.0 - t))
--     where (l,r) = splitAtParam s t
--   </pre>
--   
--   That is to say, the parameterization scales linearly with splitting.
--   
--   <a>splitAtParam</a> can also be used with parameters outside the range
--   (0,1). For example, using the parameter <tt>2</tt> gives two result
--   segments where the first is the original segment extended to the
--   parameter 2, and the second result segment travels <i>backwards</i>
--   from the end of the first to the end of the original segment.
splitAtParam :: VectorSpace v => Segment v -> Scalar v -> (Segment v, Segment v)

-- | <a>arcLength</a> <tt>s m</tt> approximates the arc length of the
--   segment curve <tt>s</tt> with accuracy of at least plus or minus
--   <tt>m</tt>. For a <a>Cubic</a> segment this is computed by subdividing
--   until the arc length of the path through the control points is within
--   <tt>m</tt> of distance from start to end.
arcLength :: (InnerSpace v, Floating (Scalar v), Ord (Scalar v)) => Segment v -> Scalar v -> Scalar v

-- | <tt><a>arcLengthToParam</a> s l m</tt> converts the absolute arc
--   length <tt>l</tt>, measured from the segment starting point, to a
--   parameter on the segment <tt>s</tt>, with accuracy of at least plus or
--   minus <tt>m</tt>. Works for <i>any</i> arc length, and may return any
--   parameter value (not just parameters between 0 and 1).
arcLengthToParam :: (InnerSpace v, Floating (Scalar v), Ord (Scalar v), AdditiveGroup v) => Segment v -> Scalar v -> Scalar v -> Scalar v

-- | Adjust the length of a segment. The second parameter is an option
--   record which controls how the adjustment should be performed; see
--   <a>AdjustOpts</a>.
adjustSegment :: (InnerSpace v, OrderedField (Scalar v)) => Segment v -> AdjustOpts v -> Segment v

-- | How should a segment, trail, or path be adjusted?
data AdjustOpts v
ALO :: AdjustMethod v -> AdjustSide -> Scalar v -> Proxy v -> AdjustOpts v
adjMethod :: AdjustOpts v -> AdjustMethod v
adjSide :: AdjustOpts v -> AdjustSide
adjEps :: AdjustOpts v -> Scalar v
adjOptsvProxy__ :: AdjustOpts v -> Proxy 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

-- | Given a segment and parameters <tt>t1</tt>, <tt>t2</tt>, produce the
--   segment which lies on the (infinitely extended) original segment
--   beginning at <tt>t1</tt> and ending at <tt>t2</tt>.
adjustSegmentToParams :: (Fractional (Scalar v), VectorSpace v) => Segment v -> Scalar v -> Scalar v -> Segment v

-- | <tt>FixedSegment</tt>s are like <a>Segment</a>s except that they have
--   absolute locations.
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 starting point and a
--   <a>Segment</a>.
mkFixedSeg :: AdditiveGroup v => Point v -> Segment v -> FixedSegment v

-- | Decompose a <a>FixedSegment</a> into a starting point and a
--   <a>Segment</a>.
fromFixedSeg :: AdditiveGroup v => FixedSegment v -> (Point v, Segment v)

-- | Compute the point on a fixed segment at a given parameter. A parameter
--   of 0 corresponds to the starting point and 1 corresponds to the ending
--   point.
fAtParam :: VectorSpace v => FixedSegment v -> Scalar v -> Point v
instance Show v => Show (Segment v)
instance Functor Segment
instance Eq v => Eq (Segment v)
instance Ord v => Ord (Segment v)
instance Show AdjustSide
instance Read AdjustSide
instance Eq AdjustSide
instance Ord AdjustSide
instance Bounded AdjustSide
instance Enum AdjustSide
instance Show v => Show (FixedSegment v)
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (FixedSegment v)
instance VectorSpace v => HasOrigin (FixedSegment v)
instance HasLinearMap v => Transformable (FixedSegment v)
instance Fractional (Scalar v) => Default (AdjustOpts v)
instance Default AdjustSide
instance Fractional (Scalar v) => Default (AdjustMethod v)
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Segment v)
instance HasLinearMap v => Renderable (Segment v) NullBackend
instance HasLinearMap v => Transformable (Segment v)


-- | 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
alignBy :: Alignable a => V a -> Scalar (V a) -> a -> a

-- | Default implementation of <a>alignBy</a> for types with
--   <a>HasOrigin</a> and <a>Enveloped</a> instances.
alignByDefault :: (HasOrigin a, Enveloped a, Num (Scalar (V a))) => V a -> Scalar (V a) -> a -> 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, Num (Scalar (V a))) => V a -> a -> a

-- | <tt>center v</tt> centers an enveloped object along the direction of
--   <tt>v</tt>.
center :: (Alignable a, Num (Scalar (V a))) => V a -> a -> a
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => Alignable (QDiagram b v m)
instance (Enveloped b, HasOrigin b) => Alignable (Map k b)
instance (Enveloped b, HasOrigin b, Ord b) => Alignable (Set b)
instance (Enveloped b, HasOrigin b) => Alignable [b]
instance (InnerSpace v, OrderedField (Scalar v)) => Alignable (Envelope v)


-- | 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
colorToRGBA :: Color c => c -> (Double, Double, Double, Double)

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

-- | The color with which lines (strokes) are drawn. Note that child colors
--   always override parent colors; that is, <tt><a>lineColor</a> c1 .
--   <a>lineColor</a> c2 $ d</tt> is equivalent to <tt><a>lineColor</a> c2
--   $ d</tt>. More precisely, the semigroup structure on line color
--   attributes is that of <a>Last</a>.
data LineColor
getLineColor :: LineColor -> SomeColor

-- | 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) => c -> a -> a

-- | A synonym for <a>lineColor</a>, specialized to <tt><a>Colour</a>
--   Double</tt> (i.e. opaque colors).
lc :: HasStyle a => Colour Double -> a -> a

-- | A synonym for <a>lineColor</a>, specialized to <tt><a>AlphaColour</a>
--   Double</tt> (i.e. colors with transparency).
lcA :: HasStyle a => AlphaColour Double -> a -> a

-- | The color with which shapes are filled. Note that child colors always
--   override parent colors; that is, <tt><a>fillColor</a> c1 .
--   <a>fillColor</a> c2 $ d</tt> is equivalent to <tt><a>lineColor</a> c2
--   $ d</tt>. More precisely, the semigroup structure on fill color
--   attributes is that of <a>Last</a>.
data FillColor
getFillColor :: FillColor -> SomeColor

-- | 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.
recommendFillColor :: (Color c, HasStyle a) => c -> a -> a

-- | 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) => c -> a -> a

-- | A synonym for <a>fillColor</a>, specialized to <tt><a>Colour</a>
--   Double</tt> (i.e. opaque colors).
fc :: HasStyle a => Colour Double -> a -> a

-- | A synonym for <a>fillColor</a>, specialized to <tt><a>AlphaColour</a>
--   Double</tt> (i.e. colors with transparency).
fcA :: HasStyle a => AlphaColour Double -> a -> a

-- | 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

-- | The width of lines. By default, the line width is measured with
--   respect to the <i>final</i> coordinate system of a rendered diagram,
--   as opposed to the local coordinate systems in effect at the time the
--   line width was set for various subdiagrams. This is so that it is easy
--   to combine a variety of shapes (some created by scaling) and have them
--   all drawn using a consistent line width. However, sometimes it is
--   desirable for scaling to affect line width; the <a>freeze</a>
--   operation is provided for this purpose. The line width of frozen
--   diagrams is affected by transformations.
--   
--   Line widths specified on child nodes always override line widths
--   specified at parent nodes.
data LineWidth
getLineWidth :: LineWidth -> Double

-- | Set the line (stroke) width.
lineWidth :: HasStyle a => Double -> a -> a

-- | A convenient synonym for <a>lineWidth</a>.
lw :: HasStyle a => Double -> a -> a

-- | 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

-- | Create lines that are dashing... er, dashed.
data Dashing
Dashing :: [Double] -> Double -> Dashing
data DashingA
getDashing :: DashingA -> Dashing

-- | Set the line dashing style.
dashing :: HasStyle a => [Double] -> Double -> a -> a
instance Typeable SomeColor
instance Typeable LineColor
instance Typeable FillColor
instance Typeable Opacity
instance Typeable LineWidth
instance Typeable LineCap
instance Typeable LineCapA
instance Typeable LineJoin
instance Typeable LineJoinA
instance Typeable Dashing
instance Typeable DashingA
instance Semigroup LineColor
instance Semigroup FillColor
instance Semigroup Opacity
instance Semigroup LineWidth
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 Eq Dashing
instance Semigroup DashingA
instance Eq DashingA
instance AttributeClass DashingA
instance AttributeClass LineJoinA
instance AttributeClass LineCapA
instance AttributeClass LineWidth
instance AttributeClass Opacity
instance Color FillColor
instance Color LineColor
instance Color SomeColor
instance (Floating a, Real a) => Color (AlphaColour a)
instance (Floating a, Real a) => Color (Colour a)
instance AttributeClass FillColor
instance AttributeClass LineColor


-- | 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 :: *
(&) :: Coordinates c => PrevDim c -> FinalCoord c -> c
coords :: Coordinates c => c -> Decomposition c
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 (a, b, c, d)
instance Coordinates (a, b, c)
instance Coordinates (a, b)


-- | Some miscellaneous utilities for working with points.
module Diagrams.Points

-- | 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
instance Coordinates v => Coordinates (Point v)


-- | This module defines <i>trails</i> (translationally invariant sequences
--   of linear or cubic Bézier segments) and <i>paths</i> (collections of
--   concretely located trails). Trails and paths can be used for drawing
--   shapes, laying out other diagrams, clipping, and other things.
module Diagrams.Path

-- | Type class for path-like things, which must be monoids. Instances
--   include <a>Trail</a>s, <a>Path</a>s, and two-dimensional
--   <a>Diagram</a>s.
class (Monoid' p, VectorSpace (V p)) => PathLike p
pathLike :: PathLike p => Point (V p) -> Bool -> [Segment (V p)] -> p

-- | Construct an open path-like thing with the origin as a starting point.
fromSegments :: PathLike p => [Segment (V p)] -> p

-- | Construct an open path-like thing of linear segments from a list of
--   offsets. The starting point is the origin.
fromOffsets :: PathLike p => [V p] -> p

-- | Construct a path-like thing of linear segments from a list of
--   vertices, with the first vertex as the starting point.
fromVertices :: PathLike p => [Point (V p)] -> p

-- | Construct a list of linear segments from a list of vertices. The input
--   list must contain at least two points to generate a non-empty list of
--   segments.
segmentsFromVertices :: AdditiveGroup v => [Point v] -> [Segment v]

-- | Convert a trail to any path-like thing. <tt>pathLikeFromTrail</tt> is
--   the identity on trails.
pathLikeFromTrail :: PathLike p => Trail (V p) -> p

-- | Path-like things that can be "open" or "closed".
class PathLike p => Closeable p
open :: Closeable p => p -> p
close :: Closeable p => p -> p

-- | A <i>trail</i> is a sequence of segments placed end-to-end. Trails are
--   thus translationally invariant, and form a monoid under concatenation.
--   Trails can also be <i>open</i> (the default) or <i>closed</i> (the
--   final point in a closed trail is implicitly connected back to the
--   starting point).
data Trail v
Trail :: [Segment v] -> Bool -> Trail v
trailSegments :: Trail v -> [Segment v]
isClosed :: Trail v -> Bool

-- | <tt>trailSegments'</tt> is like <a>trailSegments</a>, but explicitly
--   includes the implicit closing segment at the end of the list for
--   closed trails.
trailSegments' :: AdditiveGroup v => Trail v -> [Segment v]

-- | Extract the offsets of the segments of a trail.
trailOffsets :: Trail v -> [v]

-- | Compute the offset from the start of a trail to the end.
trailOffset :: AdditiveGroup v => Trail v -> v

-- | Extract the vertices of a trail, given a concrete location at which to
--   place the first vertex.
trailVertices :: AdditiveGroup v => Point v -> Trail v -> [Point v]

-- | Reverse a trail's direction of travel.
reverseTrail :: AdditiveGroup v => Trail v -> Trail v

-- | If the trail is closed, this adds in the closing segment. Otherwise,
--   the trail is returned unmodified.
addClosingSegment :: AdditiveGroup v => Trail v -> Trail v

-- | Convert a starting point and a trail into a list of fixed segments.
fixTrail :: AdditiveGroup v => Point v -> Trail v -> [FixedSegment v]

-- | A <i>path</i> is a (possibly empty) list of trails, with each trail
--   paired with an absolute starting point. Hence, paths are <i>not</i>
--   translationally invariant, and form a monoid under superposition.
newtype Path v
Path :: [(Point v, Trail v)] -> Path v
pathTrails :: Path v -> [(Point v, Trail v)]

-- | Convert a trail to a path beginning at the origin.
pathFromTrail :: AdditiveGroup v => Trail v -> Path v

-- | Convert a trail to a path with a particular starting point.
pathFromTrailAt :: Trail v -> Point v -> Path v

-- | Extract the vertices of a path.
pathVertices :: AdditiveGroup v => Path v -> [[Point v]]

-- | Compute the total offset of each trail comprising a path.
pathOffsets :: AdditiveGroup v => Path v -> [v]

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

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

-- | Reverse the direction of all the component trails of a path.
reversePath :: AdditiveGroup v => Path v -> Path v

-- | Convert a path into a list of lists of <a>FixedSegment</a>s.
fixPath :: AdditiveGroup v => Path v -> [[FixedSegment v]]

-- | Given a starting point, "explode" a trail by turning each segment
--   (including the implicit closing segment, if the trail is closed) into
--   its own separate path. Useful for (say) applying a different style to
--   each segment.
explodeTrail :: (VectorSpace (V p), PathLike p) => Point (V p) -> Trail (V p) -> [p]

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

-- | Create a single-segment path between two given points.
(~~) :: PathLike p => Point (V p) -> Point (V p) -> p
instance Show v => Show (Trail v)
instance Functor Trail
instance Eq v => Eq (Trail v)
instance Ord v => Ord (Trail v)
instance Show v => Show (Path v)
instance Semigroup (Path v)
instance Monoid (Path v)
instance Eq v => Eq (Path v)
instance Ord v => Ord (Path v)
instance HasLinearMap 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 => Transformable (Path v)
instance VectorSpace v => PathLike (Path v)
instance VectorSpace v => HasOrigin (Path v)
instance Newtype (Path v) [(Point v, Trail v)]
instance HasLinearMap v => Renderable (Trail v) NullBackend
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Trail v)
instance HasLinearMap v => Transformable (Trail v)
instance VectorSpace v => PathLike (Trail v)
instance Monoid (Trail v)
instance Semigroup (Trail v)
instance VectorSpace v => Closeable (Path v)
instance VectorSpace v => Closeable (Trail v)
instance VectorSpace v => PathLike [Point 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.
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), 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.
strut :: (Backend b 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>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

-- | <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.
--   
--   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>.
--   However, they do <i>not</i> form a monoid, since there is no identity
--   element. <a>mempty</a> is a right identity (<tt>beside v d1 mempty ===
--   d1</tt>) but not a left identity (<tt>beside v mempty d1 === d1 #
--   align (negateV v)</tt>).
--   
--   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>.
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.
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 :: (HasOrigin a, Monoid' a) => 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 :: (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), Floating (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 {sep =
--   2}</tt>.
--   
--   Note that <tt>cat' v with {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), Floating (Scalar (V a))) => V a -> CatOpts (V a) -> [a] -> a

-- | Options for <a>cat'</a>.
data CatOpts v
CatOpts :: CatMethod -> Scalar v -> Proxy v -> CatOpts v

-- | Which <a>CatMethod</a> should be used: normal catenation (default), or
--   distribution?
catMethod :: 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 :: CatOpts v -> Scalar v

-- | This field exists solely to aid type inference; please ignore it.
catOptsvProxy__ :: CatOpts v -> Proxy 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)


-- | 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, 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. See:
--   <a>http://mathworld.wolfram.com/CubicSpline.html</a>
cubicSpline :: (PathLike p, Fractional (V p)) => Bool -> [Point (V p)] -> p


-- | 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>PathLike</a> instance for <tt><a>Active</a> p</tt> where
--   <tt>p</tt> is also <a>PathLike</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 <a>Alignable</a> instance for <tt><a>Active</a> a</tt> where
--   <tt>a</tt> is also <a>Alignable</a>; the active value is aligned
--   pointwise over time.</li>
--   </ul>
module Diagrams.Animation.Active
instance Alignable a => Alignable (Active a)
instance Juxtaposable a => Juxtaposable (Active a)
instance PathLike p => PathLike (Active p)
instance HasStyle a => HasStyle (Active a)
instance Transformable a => Transformable (Active a)
instance HasOrigin a => HasOrigin (Active a)


-- | 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>
--   
--   <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
--   <a>&amp;</a>.
r2 :: (Double, Double) -> R2

-- | Convert a 2D vector back into a pair of components. See also
--   <a>coords</a>.
unr2 :: 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

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

-- | Transformations in R^2.
type T2 = Transformation R2

-- | Type class for types that measure angles.
class Num a => Angle a
toCircleFrac :: Angle a => a -> CircleFrac
fromCircleFrac :: Angle a => CircleFrac -> a

-- | Newtype wrapper used to represent angles as fractions of a circle. For
--   example, 1/3 = tau/3 radians = 120 degrees.
newtype CircleFrac
CircleFrac :: Double -> CircleFrac
getCircleFrac :: CircleFrac -> Double

-- | Newtype wrapper for representing angles in radians.
newtype Rad
Rad :: Double -> Rad
getRad :: Rad -> Double

-- | Newtype wrapper for representing angles in degrees.
newtype Deg
Deg :: Double -> Deg
getDeg :: Deg -> Double

-- | An angle representing a full circle.
fullCircle :: Angle a => a

-- | Convert between two angle representations.
convertAngle :: (Angle a, Angle b) => a -> b
instance Typeable R2
instance AdditiveGroup R2
instance Eq R2
instance Ord R2
instance Num R2
instance Fractional R2
instance Read CircleFrac
instance Show CircleFrac
instance Eq CircleFrac
instance Ord CircleFrac
instance Enum CircleFrac
instance Floating CircleFrac
instance Fractional CircleFrac
instance Num CircleFrac
instance Real CircleFrac
instance RealFloat CircleFrac
instance RealFrac CircleFrac
instance Read Rad
instance Show Rad
instance Eq Rad
instance Ord Rad
instance Enum Rad
instance Floating Rad
instance Fractional Rad
instance Num Rad
instance Real Rad
instance RealFloat Rad
instance RealFrac Rad
instance Read Deg
instance Show Deg
instance Eq Deg
instance Ord Deg
instance Enum Deg
instance Floating Deg
instance Fractional Deg
instance Num Deg
instance Real Deg
instance RealFloat Deg
instance RealFrac Deg
instance Angle Deg
instance Angle Rad
instance Angle CircleFrac
instance Transformable R2
instance Coordinates R2
instance InnerSpace R2
instance HasBasis R2
instance VectorSpace R2
instance Newtype R2 (Double, Double)
instance Read R2
instance Show 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 a transformation mapping from the local
--   vector space of the text to the vector space in which it is embedded.
data Text
Text :: 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, measured with respect to the current local vector space.
--   Inner <tt>FontSize</tt> attributes override outer ones.
newtype FontSize
FontSize :: (Last Double) -> FontSize

-- | Extract the size from a <tt>FontSize</tt> attribute.
getFontSize :: FontSize -> Double

-- | 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 => 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 Font
instance Typeable FontSize
instance Typeable FontSlantA
instance Typeable FontWeightA
instance Semigroup Font
instance Eq Font
instance Semigroup FontSize
instance Eq 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 AttributeClass FontSize
instance AttributeClass Font
instance Renderable Text NullBackend
instance HasOrigin Text
instance Transformable Text


-- | 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 :: Angle a => R2 -> a

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

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


-- | 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. For example, to align several
--   diagrams along their tops, we first move their local origins to the
--   upper edge of their envelopes (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, V a ~ R2) => a -> a

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

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

-- | Align along the bottom edge.
alignB :: (Alignable a, V a ~ R2) => a -> a
alignTL :: (Alignable a, V a ~ R2) => a -> a
alignTR :: (Alignable a, V a ~ R2) => a -> a
alignBL :: (Alignable a, V a ~ R2) => a -> a
alignBR :: (Alignable a, V a ~ R2) => a -> a

-- | <tt>alignX</tt> moves the local origin horizontally as follows:
--   
--   <ul>
--   <li><tt>alignX (-1)</tt> moves the local origin to the left edge of
--   the envelope;</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>
--   </ul>
alignX :: (Alignable 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, V a ~ R2) => Double -> a -> a

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

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

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


-- | 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


-- | 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 a => a -> 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 type which is an instance of
--   <a>Angle</a>. For example, <tt>rotate (1/4 :: <a>CircleFrac</a>)</tt>,
--   <tt>rotate (tau/4 :: <a>Rad</a>)</tt>, and <tt>rotate (90 ::
--   <a>Deg</a>)</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 type annotation, 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 is specialized to take a <a>CircleFrac</a> argument.
rotate :: (Transformable t, V t ~ R2, Angle a) => a -> t -> t

-- | A synonym for <a>rotate</a>, specialized to only work with
--   <tt>CircleFrac</tt> arguments; it can be more convenient to write
--   <tt>rotateBy (1/4)</tt> than <tt><a>rotate</a> (1/4 ::
--   <a>CircleFrac</a>)</tt>.
rotateBy :: (Transformable t, V t ~ R2) => CircleFrac -> t -> t

-- | <tt>rotationAbout p</tt> is a rotation about the point <tt>p</tt>
--   (instead of around the local origin).
rotationAbout :: Angle a => P2 -> a -> 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, Angle a) => P2 -> a -> 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 <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
unScaleInv :: ScaleInv t -> t
scaleInvDir :: ScaleInv t -> R2
scaleInvLoc :: ScaleInv t -> P2

-- | Create a scale-invariant object pointing in the given direction.
scaleInv :: t -> R2 -> ScaleInv t
instance Show t => Show (ScaleInv t)
instance (V t ~ R2, Transformable t) => Transformable (ScaleInv t)
instance (V t ~ R2, HasOrigin t) => HasOrigin (ScaleInv 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 :: (Angle a, PathLike p, V p ~ R2) => a -> a -> p

-- | 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.
arc' :: (Angle a, PathLike p, V p ~ R2) => Double -> a -> a -> p

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

-- | 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 a => a -> a -> 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 <tt>s</tt> radians. 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 then it is truncated to tau.
bezierFromSweep :: Rad -> [Segment R2]

-- | Create a circular wedge of the given radius, beginning at the first
--   angle and extending counterclockwise to the second.
wedge :: (Angle a, PathLike p, V p ~ R2) => Double -> a -> a -> 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 :: (PathLike p, V p ~ R2) => p

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

-- | <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 :: (PathLike p, V p ~ R2, Transformable p) => Double -> p

-- | <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 :: (PathLike p, V p ~ R2, Transformable p) => Double -> Double -> p


-- | 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 :: [a] -> [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 :: [a] -> [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

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

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

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

-- | Generate the vertices of a polygon. See <a>PolygonOpts</a> for more
--   information.
polyVertices :: PolygonOpts -> [P2]
polygon :: (PathLike p, V p ~ R2) => PolygonOpts -> p

-- | Generate the vertices of a polygon specified by polar data (central
--   angles and radii). See <a>PolyPolar</a>.
polyPolarVs :: Angle a => [a] -> [Double] -> [P2]

-- | Generate the vertices of a polygon specified by side length and
--   angles, with the origin placed at the centroid. See <a>PolySides</a>.
polySidesVs :: Angle a => [a] -> [Double] -> [P2]

-- | Generate the vertices of a polygon specified by side length and
--   angles, with the origin corresponding to the first vertex. See
--   <a>PolySides</a>.
polySidesVs' :: Angle a => [a] -> [Double] -> [P2]

-- | Generate the vertices of a regular polygon. See <a>PolyRegular</a>.
polyRegularVs :: Int -> Double -> [P2]

-- | Orient a list of points, rotating them as little as possible. The
--   points are rotated so that the edge furthest in the direction of the
--   given vector is perpendicular to it. (Note: this may do odd things to
--   non-convex lists of points.)
orient :: R2 -> [P2] -> [P2]

-- | 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>PathLike</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>PathLike</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 Eq PolyOrientation
instance Ord PolyOrientation
instance Show PolyOrientation
instance Read PolyOrientation
instance Show a => Show (GraphPart a)
instance Functor GraphPart
instance Default PolygonOpts


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

-- | Create a centered horizontal (L-R) line of the given length.
hrule :: (PathLike p, V p ~ R2) => Double -> p

-- | Create a centered vertical (T-B) line of the given length.
vrule :: (PathLike p, V p ~ R2) => Double -> p

-- | 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 :: (PathLike p, V p ~ R2) => Int -> Double -> p

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

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

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

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

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

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

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

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

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

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

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

-- | <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 :: (PathLike p, Transformable p, V p ~ R2) => Double -> Double -> p

-- | <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
--   <tt>roundedRect'</tt> instead.
roundedRect :: (PathLike p, V p ~ R2) => Double -> Double -> Double -> p
data RoundedRectOpts
RoundedRectOpts :: Double -> Double -> Double -> Double -> RoundedRectOpts
radiusTL :: RoundedRectOpts -> Double
radiusTR :: RoundedRectOpts -> Double
radiusBL :: RoundedRectOpts -> Double
radiusBR :: 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' :: (PathLike p, V p ~ R2) => Double -> Double -> RoundedRectOpts -> p
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 :: (PathLike p, Enveloped p, Transformable p, V p ~ R2) => QAnimation b R2 m -> p

-- | 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' :: (PathLike p, Enveloped p, Transformable p, V p ~ R2) => Rational -> QAnimation b R2 m -> p


-- | 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>
--   </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 two arguments specify a method for
--   extracting the requested output size from the rendering options, and a
--   way of updating the rendering options with a new (more specific) size.
adjustDiaSize2D :: Monoid' m => (Options b R2 -> SizeSpec2D) -> (SizeSpec2D -> Options b R2 -> Options b R2) -> b -> Options b R2 -> QDiagram b R2 m -> (Options b R2, 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 two arguments it requires a method for extracting the
--   requested output size from the rendering options, and a way of
--   updating the rendering options with a new (more specific) size.
--   
--   It then performs the following adjustments:
--   
--   <ul>
--   <li>Set default attributes (see <a>setDefault2DAttributes</a>)</li>
--   <li>Freeze the diagram in its final form</li>
--   <li>Scale and translate the diagram to fit within the requested size
--   (see <a>adjustDiaSize2D</a>)</li>
--   <li>Also return the actual adjusted size of the diagram.</li>
--   </ul>
adjustDia2D :: Monoid' m => (Options b R2 -> SizeSpec2D) -> (SizeSpec2D -> Options b R2 -> Options b R2) -> b -> Options b R2 -> QDiagram b R2 m -> (Options b R2, QDiagram b R2 m)

-- | Re-export <a>requiredScaleT</a> with the name <a>adjustSize</a> for
--   backwards compatibility.

-- | <i>Deprecated: Use Diagrams.TwoD.Size.requiredScaleT instead. </i>
adjustSize :: 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


-- | 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 R2)


-- | 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> { ... }</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>strokeT</tt> as
--   well. The solution is to give a type signature to expressions
--   involving <tt>strokeT</tt>, or (recommended) upgrade GHC (the bug is
--   fixed in 7.0.2 onwards).
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.
strokeT' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Trail 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

-- | 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 :: StrokeOpts 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 :: 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
getClip :: Clip -> [Path R2]

-- | 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
instance Typeable FillRuleA
instance Typeable Clip
instance Eq FillRule
instance Semigroup FillRuleA
instance Semigroup Clip
instance Transformable Clip
instance AttributeClass Clip
instance AttributeClass FillRuleA
instance Default (StrokeOpts a)
instance Renderable (Path R2) b => PathLike (QDiagram b R2 Any)
instance Traced (Path R2)
instance Traced (Trail R2)


-- | 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
showLabels :: (Renderable Text b, Backend b R2) => QDiagram b R2 m -> QDiagram b R2 Any
instance Default OriginOpts


-- | Importing external images into diagrams.
module Diagrams.TwoD.Image

-- | An external image primitive, representing an image the backend should
--   import from another file when rendering.
data Image
Image :: FilePath -> SizeSpec2D -> T2 -> Image
imgFile :: Image -> FilePath
imgSize :: Image -> SizeSpec2D
imgTransf :: Image -> T2

-- | Take an external image from the specified file and turn it into a
--   diagram with the specified width and height, centered at the origin.
--   Note that the image's aspect ratio will be preserved; if the specified
--   width and height have a different ratio than the image's aspect ratio,
--   there will be extra space in one dimension.
image :: Renderable Image b => FilePath -> Double -> Double -> Diagram b R2
instance Renderable Image NullBackend
instance HasOrigin Image
instance Transformable Image


-- | 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 a right
--   (but not left) 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 a right (but not left) 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 b) => b -> 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 d</tt> is an empty diagram with width <tt>d</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 d</tt> is an empty diagram with height <tt>d</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 :: (Semigroup m, 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 :: (Semigroup m, 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 :: (Semigroup m, 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 :: (Semigroup m, 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 p, Transformable p, PathLike p, V p ~ R2, Enveloped a, V a ~ R2) => a -> p

-- | "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


-- | 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.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>
--   
--   <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
--   <a>&amp;</a>.
r2 :: (Double, Double) -> R2

-- | Convert a 2D vector back into a pair of components. See also
--   <a>coords</a>.
unr2 :: 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

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

-- | 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 :: Angle a => R2 -> a

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

-- | A convenient synonym for <a>fromDirection</a>.
e :: Angle a => a -> 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

-- | Type class for types that measure angles.
class Num a => Angle a
toCircleFrac :: Angle a => a -> CircleFrac
fromCircleFrac :: Angle a => CircleFrac -> a

-- | Newtype wrapper used to represent angles as fractions of a circle. For
--   example, 1/3 = tau/3 radians = 120 degrees.
newtype CircleFrac
CircleFrac :: Double -> CircleFrac
getCircleFrac :: CircleFrac -> Double

-- | Newtype wrapper for representing angles in radians.
newtype Rad
Rad :: Double -> Rad
getRad :: Rad -> Double

-- | Newtype wrapper for representing angles in degrees.
newtype Deg
Deg :: Double -> Deg
getDeg :: Deg -> Double

-- | An angle representing a full circle.
fullCircle :: Angle a => a

-- | Convert between two angle representations.
convertAngle :: (Angle a, Angle b) => a -> b

-- | 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> { ... }</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>strokeT</tt> as
--   well. The solution is to give a type signature to expressions
--   involving <tt>strokeT</tt>, or (recommended) upgrade GHC (the bug is
--   fixed in 7.0.2 onwards).
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.
strokeT' :: (Renderable (Path R2) b, IsName a) => StrokeOpts a -> Trail 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

-- | 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 :: StrokeOpts 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 :: 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

-- | Create a centered horizontal (L-R) line of the given length.
hrule :: (PathLike p, V p ~ R2) => Double -> p

-- | Create a centered vertical (T-B) line of the given length.
vrule :: (PathLike p, V p ~ R2) => Double -> p

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

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

-- | <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 :: (PathLike p, V p ~ R2, Transformable p) => Double -> p

-- | <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 :: (PathLike p, V p ~ R2, Transformable p) => Double -> Double -> p

-- | 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 :: (Angle a, PathLike p, V p ~ R2) => a -> a -> p

-- | 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.
arc' :: (Angle a, PathLike p, V p ~ R2) => Double -> a -> a -> p

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

-- | Create a circular wedge of the given radius, beginning at the first
--   angle and extending counterclockwise to the second.
wedge :: (Angle a, PathLike p, V p ~ R2) => Double -> a -> a -> p
polygon :: (PathLike p, V p ~ R2) => PolygonOpts -> p

-- | Generate the vertices of a polygon. See <a>PolygonOpts</a> for more
--   information.
polyVertices :: PolygonOpts -> [P2]

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

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

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

-- | Should a translation be applied to the polygon in order to place the
--   center at a particular location?
polyCenter :: 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 :: [a] -> [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 :: [a] -> [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>PathLike</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>PathLike</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 :: (PathLike p, V p ~ R2) => Int -> Double -> p

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

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

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

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

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

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

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

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

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

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

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

-- | <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 :: (PathLike p, Transformable p, V p ~ R2) => Double -> Double -> p

-- | <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
--   <tt>roundedRect'</tt> instead.
roundedRect :: (PathLike p, V p ~ R2) => Double -> Double -> Double -> p

-- | <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' :: (PathLike p, V p ~ R2) => Double -> Double -> RoundedRectOpts -> p
data RoundedRectOpts
RoundedRectOpts :: Double -> Double -> Double -> Double -> RoundedRectOpts
radiusTL :: RoundedRectOpts -> Double
radiusTR :: RoundedRectOpts -> Double
radiusBL :: RoundedRectOpts -> Double
radiusBR :: RoundedRectOpts -> Double

-- | 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 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 => Double -> 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

-- | Take an external image from the specified file and turn it into a
--   diagram with the specified width and height, centered at the origin.
--   Note that the image's aspect ratio will be preserved; if the specified
--   width and height have a different ratio than the image's aspect ratio,
--   there will be extra space in one dimension.
image :: Renderable Image b => FilePath -> Double -> Double -> 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 a => a -> 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 type which is an instance of
--   <a>Angle</a>. For example, <tt>rotate (1/4 :: <a>CircleFrac</a>)</tt>,
--   <tt>rotate (tau/4 :: <a>Rad</a>)</tt>, and <tt>rotate (90 ::
--   <a>Deg</a>)</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 type annotation, 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 is specialized to take a <a>CircleFrac</a> argument.
rotate :: (Transformable t, V t ~ R2, Angle a) => a -> t -> t

-- | A synonym for <a>rotate</a>, specialized to only work with
--   <tt>CircleFrac</tt> arguments; it can be more convenient to write
--   <tt>rotateBy (1/4)</tt> than <tt><a>rotate</a> (1/4 ::
--   <a>CircleFrac</a>)</tt>.
rotateBy :: (Transformable t, V t ~ R2) => CircleFrac -> t -> t

-- | <tt>rotationAbout p</tt> is a rotation about the point <tt>p</tt>
--   (instead of around the local origin).
rotationAbout :: Angle a => P2 -> a -> 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, Angle a) => P2 -> a -> 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

-- | 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 a right
--   (but not left) 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 a right (but not left) 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 b) => b -> 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 d</tt> is an empty diagram with width <tt>d</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 d</tt> is an empty diagram with height <tt>d</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 :: (Semigroup m, 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 :: (Semigroup m, 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 :: (Semigroup m, 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 :: (Semigroup m, 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 p, Transformable p, PathLike p, V p ~ R2, Enveloped a, V a ~ R2) => a -> p

-- | "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, V a ~ R2) => a -> a

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

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

-- | Align along the bottom edge.
alignB :: (Alignable a, V a ~ R2) => a -> a
alignTL :: (Alignable a, V a ~ R2) => a -> a
alignTR :: (Alignable a, V a ~ R2) => a -> a
alignBL :: (Alignable a, V a ~ R2) => a -> a
alignBR :: (Alignable a, V a ~ R2) => a -> a

-- | <tt>alignX</tt> moves the local origin horizontally as follows:
--   
--   <ul>
--   <li><tt>alignX (-1)</tt> moves the local origin to the left edge of
--   the envelope;</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>
--   </ul>
alignX :: (Alignable 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, V a ~ R2) => Double -> a -> a

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

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

-- | Center along both the X- and Y-axes.
centerXY :: (Alignable 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

-- | 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
showLabels :: (Renderable Text b, Backend b R2) => QDiagram b R2 m -> QDiagram b R2 Any


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

-- | The three-dimensional Euclidean vector space R^3.
data 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)

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

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

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

-- | Transformations in R^3.
type T3 = Transformation R3
instance AdditiveGroup R3
instance Eq R3
instance Ord R3
instance Show R3
instance Read R3
instance Transformable R3
instance Coordinates R3
instance InnerSpace R3
instance HasBasis R3
instance VectorSpace R3
instance Newtype R3 (Double, Double, Double)


-- | Various three-dimensional shapes.
module Diagrams.ThreeD.Shapes
data Ellipsoid
Ellipsoid :: T3 -> Ellipsoid
sphere :: (Backend b R3, Renderable Ellipsoid b) => Diagram b R3
instance Renderable Ellipsoid NullBackend
instance Transformable Ellipsoid


-- | A module to re-export most of the functionality of the diagrams core
--   and standard library.
module Diagrams.Prelude

-- | 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


-- | A simple Show-based diagrams backend, for testing purposes.
module Diagrams.Backend.Show

-- | Token for identifying this backend.
data ShowBackend
ShowBackend :: ShowBackend
renderTransf :: (Num (Scalar v), HasLinearMap v, Show (Scalar v)) => Transformation v -> Doc
renderMat :: Show a => [[a]] -> Doc
instance (Ord v, Show v, HasLinearMap v) => Renderable (Path v) ShowBackend
instance (Show v, HasLinearMap v) => Renderable (Trail v) ShowBackend
instance (Show v, HasLinearMap v) => Renderable (Segment v) ShowBackend
instance Monoid (Render ShowBackend v)
instance HasLinearMap v => Backend ShowBackend v
