-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A pure haskell drawing engine. -- @package Rasterific @version 0.5 -- | This module is a reduction of the Linear package from Edward -- Kmett to match just the need of Rasterific. -- -- If the flag embed_linear is disabled, this module is just a -- reexport from the real linear package. module Graphics.Rasterific.Linear -- | A 2-dimensional vector -- --
--   >>> pure 1 :: V2 Int
--   V2 1 1
--   
-- --
--   >>> V2 1 2 + V2 3 4
--   V2 4 6
--   
-- --
--   >>> V2 1 2 * V2 3 4
--   V2 3 8
--   
-- --
--   >>> sum (V2 1 2)
--   3
--   
data V2 a V2 :: !a -> !a -> V2 a -- | A 1-dimensional vector newtype V1 a V1 :: a -> V1 a -- | A vector is an additive group with additional structure. class Functor f => Additive f zero :: (Additive f, Num a) => f a (^+^) :: (Additive f, Num a) => f a -> f a -> f a (^-^) :: (Additive f, Num a) => f a -> f a -> f a lerp :: (Additive f, Num a) => a -> f a -> f a -> f a -- | Provides a fairly subjective test to see if a quantity is near zero. -- --
--   >>> nearZero (1e-11 :: Double)
--   False
--   
-- --
--   >>> nearZero (1e-17 :: Double)
--   True
--   
-- --
--   >>> nearZero (1e-5 :: Float)
--   False
--   
-- --
--   >>> nearZero (1e-7 :: Float)
--   True
--   
class Num a => Epsilon a nearZero :: Epsilon a => a -> Bool -- | Free and sparse inner product/metric spaces. class Additive f => Metric f where quadrance v = dot v v qd f g = quadrance (f ^-^ g) distance f g = norm (f ^-^ g) norm v = sqrt (quadrance v) signorm v = fmap (/ m) v where m = norm v dot :: (Metric f, Num a) => f a -> f a -> a quadrance :: (Metric f, Num a) => f a -> a qd :: (Metric f, Num a) => f a -> f a -> a distance :: (Metric f, Floating a) => f a -> f a -> a norm :: (Metric f, Floating a) => f a -> a signorm :: (Metric f, Floating a) => f a -> f a -- | Compute the right scalar product -- --
--   >>> V2 3 4 ^* 2
--   V2 6 8
--   
(^*) :: (Functor f, Num a) => f a -> a -> f a -- | Compute division by a scalar on the right. (^/) :: (Functor f, Floating a) => f a -> a -> f a -- | Normalize a Metric functor to have unit norm. This -- function does not change the functor if its norm is 0 or 1. normalize :: (Floating a, Metric f, Epsilon a) => f a -> f a instance Eq a => Eq (V2 a) instance Show a => Show (V2 a) instance Eq a => Eq (V1 a) instance Show a => Show (V1 a) instance Metric V2 instance Additive V1 instance Additive V2 instance Epsilon a => Epsilon (V2 a) instance Epsilon Double instance Epsilon Float instance Applicative V1 instance Applicative V2 instance Functor V1 instance Num a => Num (V2 a) instance Functor V2 -- | This module provide lenses compatible with the lens module but -- without the dependency to it. module Graphics.Rasterific.Lenses -- | Line origin point. lineX0 :: Lens' Line Point -- | Line end point. lineX1 :: Lens' Line Point -- | Traverse all the points of a line. linePoints :: Traversal' Line Point -- | Quadratic bezier starting point. bezX0 :: Lens' Bezier Point -- | bezier control point. bezX1 :: Lens' Bezier Point -- | bezier end point. bezX2 :: Lens' Bezier Point -- | Traversal of all the bezier's points. bezierPoints :: Traversal' Bezier Point -- | Cubic bezier first point cbezX0 :: Lens' CubicBezier Point -- | Cubic bezier first control point. cbezX1 :: Lens' CubicBezier Point -- | Cubic bezier second control point. cbezX2 :: Lens' CubicBezier Point -- | Cubic bezier last point. cbezX3 :: Lens' CubicBezier Point -- | Traversal of all the points of the cubic bezier. cubicBezierPoints :: Traversal' CubicBezier Point -- | Traverse all the points defined in the primitive. primitivePoints :: Traversal' Primitive Point -- | Traversal of all the points of a path pathCommandPoints :: Traversal' PathCommand Point -- | Traversal of all the points in a path. pathPoints :: Traversal' Path Point -- | Does it look familiar? yes it's the official Lens type. type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t -- | Try to match the Lens' type alias. type Lens' s a = Lens s s a a -- | Traversal type, matched to the one of the lens package. type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t type Traversal' s a = Traversal s s a a -- | This module provide some helpers in order to perform basic geometric -- transformation on the drawable primitives. -- -- You can combine the transformation is mappend or the -- `(<>)` operator from Data.Monoid . module Graphics.Rasterific.Transformations -- | Represent a 3*3 matrix for homogenous coordinates. -- --
--   | A C E |
--   | B D F |
--   | 0 0 1 |
--   
data Transformation Transformation :: {-# UNPACK #-} !Float -> {-# UNPACK #-} !Float -> {-# UNPACK #-} !Float -> {-# UNPACK #-} !Float -> {-# UNPACK #-} !Float -> {-# UNPACK #-} !Float -> Transformation _transformA :: Transformation -> {-# UNPACK #-} !Float _transformC :: Transformation -> {-# UNPACK #-} !Float -- | X translation _transformE :: Transformation -> {-# UNPACK #-} !Float _transformB :: Transformation -> {-# UNPACK #-} !Float _transformD :: Transformation -> {-# UNPACK #-} !Float -- | Y translation _transformF :: Transformation -> {-# UNPACK #-} !Float -- | Effectively transform a point given a transformation. applyTransformation :: Transformation -> Point -> Point -- | Effectively transform a vector given a transformation. The translation -- part won't be applied. applyVectorTransformation :: Transformation -> Vector -> Vector -- | Perform a translation of the given primitives. -- --
--   fill . transform (applyTransformation $ translate (V2 100 100))
--        $ rectangle (V2 40 40) 40 40
--   
-- translate :: Vector -> Transformation -- | Perform a scaling of the given primitives. -- --
--   fill . transform (applyTransformation $ scale 2 2)
--        $ rectangle (V2 40 40) 40 40
--   
-- scale :: Float -> Float -> Transformation -- | Create a transformation representing a rotation on the plane. -- --
--   fill . transform (applyTransformation $ rotate 0.2)
--        $ rectangle (V2 40 40) 120 120
--   
-- rotate :: Float -> Transformation -- | Create a transformation representing a rotation on the plane. The -- rotation center is given in parameter -- --
--   fill . transform (applyTransformation $ rotateCenter 0.2 (V2 200 200))
--        $ rectangle (V2 40 40) 120 120
--   
-- rotateCenter :: Float -> Point -> Transformation -- | Skew transformation along the X axis. -- --
--   fill . transform (applyTransformation $ skewX 0.3)
--        $ rectangle (V2 50 50) 80 80
--   
-- skewX :: Float -> Transformation -- | Skew transformation along the Y axis. -- --
--   fill . transform (applyTransformation $ skewY 0.3)
--        $ rectangle (V2 50 50) 80 80
--   
-- skewY :: Float -> Transformation -- | Given a new X-acis vector, create a rotation matrix to get into this -- new base, assuming an Y basis orthonormal to the X one. toNewXBase :: Vector -> Transformation -- | Inverse a transformation (if possible) inverseTransformation :: Transformation -> Maybe Transformation instance Eq Transformation instance Show Transformation instance Monoid Transformation -- | This module provide helper functions to create outline of shapes. module Graphics.Rasterific.Outline -- | Type alias just to get more meaningful type signatures type StrokeWidth = Float -- | This function will create the outline of a given geometry given a -- path. You can then stroke it. -- --
--   stroke 3 (JoinMiter 0) (CapStraight 0, CapStraight 0) $
--       strokize 40 JoinRound (CapRound, CapRound)
--         [CubicBezierPrim $
--              CubicBezier (V2  40 160) (V2 40   40)
--                          (V2 160  40) (V2 160 160)]
--   
-- strokize :: StrokeWidth -> Join -> (Cap, Cap) -> [Primitive] -> [Primitive] -- | Create a list of outlines corresponding to all the dashed elements. -- They can be then stroked -- --
--   mapM_ (stroke 3 (JoinMiter 0) (CapStraight 0, CapStraight 0)) $
--       dashedStrokize 0 [10, 5]
--                      40 JoinRound (CapStraight 0, CapStraight 0)
--         [CubicBezierPrim $
--              CubicBezier (V2  40 160) (V2 40   40)
--                          (V2 160  40) (V2 160 160)]
--   
-- dashedStrokize :: Float -> DashPattern -> StrokeWidth -> Join -> (Cap, Cap) -> [Primitive] -> [[Primitive]] -- | Return an approximation of the length of a given path. It's results is -- not precise but should be enough for rough calculations approximatePathLength :: Path -> Float -- | Module describing the various filling method of the geometric -- primitives. -- -- All points coordinate given in this module are expressed final image -- pixel coordinates. module Graphics.Rasterific.Texture -- | Reification of texture type data Texture px -- | A gradient definition is just a list of stop and pixel values. For -- instance for a simple gradient of black to white, the finition would -- be : -- --
--   [(0, PixelRGBA8 0 0 0 255), (1, PixelRGBA8 255 255 255 255)]
--   
-- -- the first stop value must be zero and the last, one. type Gradient px = [(Float, px)] -- | Set the repeat pattern of the texture (if any). With padding: -- --
--   withTexture (sampledImageTexture textureImage) $
--     fill $ rectangle (V2 0 0) 200 200
--   
-- -- -- With repeat: -- --
--   withTexture (withSampler SamplerRepeat $
--                   sampledImageTexture textureImage) $
--       fill $ rectangle (V2 0 0) 200 200
--   
-- -- -- With reflect: -- --
--   withTexture (withSampler SamplerReflect $
--                   sampledImageTexture textureImage) $
--       fill $ rectangle (V2 0 0) 200 200
--   
-- withSampler :: SamplerRepeat -> Texture px -> Texture px -- | The uniform texture is the simplest texture of all: an uniform color. uniformTexture :: px -> Texture px -- | Linear gradient texture. -- --
--   let gradDef = [(0, PixelRGBA8 0 0x86 0xc1 255)
--                 ,(0.5, PixelRGBA8 0xff 0xf4 0xc1 255)
--                 ,(1, PixelRGBA8 0xFF 0x53 0x73 255)] in
--   withTexture (linearGradientTexture SamplerPad gradDef
--                          (V2 40 40) (V2 130 130)) $
--      fill $ circle (V2 100 100) 100
--   
-- linearGradientTexture :: Gradient px -> Point -> Point -> Texture px -- | Radial gradient texture -- --
--   let gradDef = [(0, PixelRGBA8 0 0x86 0xc1 255)
--                 ,(0.5, PixelRGBA8 0xff 0xf4 0xc1 255)
--                 ,(1, PixelRGBA8 0xFF 0x53 0x73 255)] in
--   withTexture (radialGradientTexture gradDef
--                      (V2 100 100) 75) $
--      fill $ circle (V2 100 100) 100
--   
-- radialGradientTexture :: Gradient px -> Point -> Float -> Texture px -- | Radial gradient texture with a focus point. -- --
--   let gradDef = [(0, PixelRGBA8 0 0x86 0xc1 255)
--                 ,(0.5, PixelRGBA8 0xff 0xf4 0xc1 255)
--                 ,(1, PixelRGBA8 0xFF 0x53 0x73 255)] in
--   withTexture (radialGradientWithFocusTexture gradDef
--                      (V2 100 100) 75 (V2 70 70) ) $
--      fill $ circle (V2 100 100) 100
--   
-- radialGradientWithFocusTexture :: Gradient px -> Point -> Float -> Point -> Texture px -- | Use another image as a texture for the filling. Contrary to -- imageTexture, this function perform a bilinear filtering on -- the texture. sampledImageTexture :: Image px -> Texture px -- | Perform a multiplication operation between a full color texture and a -- greyscale one, used for clip-path implementation. modulateTexture :: Pixel px => Texture px -> Texture (PixelBaseComponent px) -> Texture px -- | Transform the coordinates used for texture before applying it, allow -- interesting transformations. -- --
--   withTexture (withSampler SamplerRepeat $
--               transformTexture (rotateCenter 1 (V2 0 0) <> 
--                                 scale 0.5 0.25)
--               $ sampledImageTexture textureImage) $
--       fill $ rectangle (V2 0 0) 200 200
--   
-- transformTexture :: Transformation -> Texture px -> Texture px -- | This module implements drawing primitives to draw directly into the -- output texture, without generating an intermediate scene -- representation. -- -- If you need to draw complex scenes or plot an important set of data, -- this is the module you should use. The downside is that you must -- specify everything you need at each draw call, there is no API to help -- you propagate constants. -- -- The "stroking" must be done using the functions of the Outline -- module. module Graphics.Rasterific.Immediate -- | Monad used to describe the drawing context. type DrawContext m px = StateT (MutableImage (PrimState m) px) m -- | Reify a filling function call, to be able to manipulate them in a -- simpler fashion. data DrawOrder px DrawOrder :: ![[Primitive]] -> !(Texture px) -> !FillMethod -> !(Maybe (Texture (PixelBaseComponent px))) -> DrawOrder px -- | Primitives to be filled. _orderPrimitives :: DrawOrder px -> ![[Primitive]] -- | Texture for the filled primitives. _orderTexture :: DrawOrder px -> !(Texture px) -- | How to fill the primitives. _orderFillMethod :: DrawOrder px -> !FillMethod -- | Optional mask used for clipping. _orderMask :: DrawOrder px -> !(Maybe (Texture (PixelBaseComponent px))) -- | Transform back a low level drawing order to a more high level Drawing orderToDrawing :: DrawOrder px -> Drawing px () -- | Start an image rendering. See fillWithTexture for an usage -- example. This function can work with either IO or ST. runDrawContext :: (PrimMonad m, RenderablePixel px) => Int -> Int -> px -> DrawContext m px () -> m (Image px) -- | Fill some geometry using a composition mask for visibility. -- --
--   immediateDrawMaskExample :: Image PixelRGBA8
--   immediateDrawMaskExample = runST $
--     runDrawContext 200 200 (PixelRGBA8 0 0 0 255) $
--       forM_ [1 .. 10] $ \ix ->
--          fillWithTextureAndMask FillWinding texture mask $
--              rectangle (V2 10 (ix * 18 - 5)) 180 13
--     where
--       texture = uniformTexture $ PixelRGBA8 0 0x86 0xc1 255
--       mask = sampledImageTexture
--            $ runST
--            $ runDrawContext 200 200 0
--            $ fillWithTexture FillWinding (uniformTexture 255) maskGeometry
--   
--       maskGeometry = strokize 15 JoinRound (CapRound, CapRound)
--                    $ circle (V2 100 100) 80
--   
-- fillWithTextureAndMask :: (PrimMonad m, RenderablePixel px, MonadState (MutableImage (PrimState m) px) (DrawContext m px)) => FillMethod -> Texture px -> Texture (PixelBaseComponent px) -> [Primitive] -> DrawContext m px () -- | Fill some geometry. -- --
--   immediateDrawExample :: Image PixelRGBA8
--   immediateDrawExample = runST $
--     runDrawContext 200 200 (PixelRGBA8 0 0 0 0) $
--       fillWithTexture FillWinding texture geometry
--     where
--       circlePrimitives = circle (V2 100 100) 50
--       geometry = strokize 4 JoinRound (CapRound, CapRound) circlePrimitives
--       texture = uniformTexture (PixelRGBA8 255 255 255 255)
--   
-- fillWithTexture :: (PrimMonad m, RenderablePixel px, MonadState (MutableImage (PrimState m) px) (DrawContext m px)) => FillMethod -> Texture px -> [Primitive] -> DrawContext m px () -- | Render the drawing orders on the canvas. fillOrder :: (PrimMonad m, RenderablePixel px) => DrawOrder px -> DrawContext m px () -- | This module help the walking of path of any shape, being able to -- return the current position and the actual orientation. module Graphics.Rasterific.PathWalker -- | The walking transformer monad. data PathWalkerT m a -- | Simpler alias if monad transformers are not needed. type PathWalker a = PathWalkerT Identity a -- | Callback function in charge to transform the DrawOrder given the -- transformation to place it on the path. type PathDrawer m px = Transformation -> PlaneBound -> DrawOrder px -> m () -- | Create a path walker from a given path runPathWalking :: Monad m => Path -> PathWalkerT m a -> m a -- | Advance by the given amount of pixels on the path. advanceBy :: Monad m => Float -> PathWalkerT m () -- | Obtain the current position if we are still on the path, if not, -- return Nothing. currentPosition :: Monad m => PathWalkerT m (Maybe Point) -- | Obtain the current tangeant of the path if we're still on it. Return -- Nothing otherwise. currentTangeant :: Monad m => PathWalkerT m (Maybe Vector) -- | This function is the workhorse of the placement, it will walk the path -- and calculate the appropriate transformation for every order. drawOrdersOnPath :: Monad m => PathDrawer m px -> Float -> Float -> Path -> [DrawOrder px] -> m () instance Monad m => Monad (PathWalkerT m) instance (Monad m, Functor m) => Applicative (PathWalkerT m) instance Functor m => Functor (PathWalkerT m) instance MonadTrans PathWalkerT -- | Main module of Rasterific, an Haskell rasterization engine. -- -- Creating an image is rather simple, here is a simple example of a -- drawing and saving it in a PNG file: -- --
--   import Codec.Picture( PixelRGBA8( .. ), writePng )
--   import Graphics.Rasterific
--   import Graphics.Rasterific.Texture
--   
--   main :: IO ()
--   main = do
--     let white = PixelRGBA8 255 255 255 255
--         drawColor = PixelRGBA8 0 0x86 0xc1 255
--         recColor = PixelRGBA8 0xFF 0x53 0x73 255
--         img = renderDrawing 400 200 white $
--            withTexture (uniformTexture drawColor) $ do
--               fill $ circle (V2 0 0) 30
--               stroke 4 JoinRound (CapRound, CapRound) $
--                      circle (V2 400 200) 40
--               withTexture (uniformTexture recColor) .
--                      fill $ rectangle (V2 100 100) 200 100
--   
--     writePng "yourimage.png" img
--   
-- -- -- The coordinate system is the picture classic one, with the origin in -- the upper left corner; with the y axis growing to the bottom and the x -- axis growing to the right: -- module Graphics.Rasterific -- | Fill some geometry. The geometry should be "looping", ie. the last -- point of the last primitive should be equal to the first point of the -- first primitive. -- -- The primitive should be connected. -- --
--   fill $ circle (V2 100 100) 75
--   
-- fill :: [Primitive] -> Drawing px () -- | This function let you choose how to fill the primitives in case of -- self intersection. See FillMethod documentation for more -- information. fillWithMethod :: FillMethod -> [Primitive] -> Drawing px () -- | Define the texture applyied to all the children draw call. -- --
--   withTexture (uniformTexture $ PixelRGBA8 0 0x86 0xc1 255) $ do
--       fill $ circle (V2 50 50) 20
--       fill $ circle (V2 100 100) 20
--       withTexture (uniformTexture $ PixelRGBA8 0xFF 0x53 0x73 255)
--            $ circle (V2 150 150) 20
--   
-- withTexture :: Texture px -> Drawing px () -> Drawing px () -- | Draw some geometry using a clipping path. -- --
--   withClipping (fill $ circle (V2 100 100) 75) $
--       mapM_ (stroke 7 JoinRound (CapRound, CapRound))
--         [line (V2 0 yf) (V2 200 (yf + 10))
--                        | y <- [5 :: Int, 17 .. 200]
--                        , let yf = fromIntegral y ]
--   
-- withClipping :: (forall innerPixel. Drawing innerPixel ()) -> Drawing px () -> Drawing px () -- | Draw all the sub drawing commands using a transformation. withTransformation :: Transformation -> Drawing px () -> Drawing px () -- | This command allows you to draw primitives on a given curve, for -- example, you can draw text on a curve: -- --
--   let path = Path (V2 100 180) False
--                   [PathCubicBezierCurveTo (V2 20 20) (V2 170 20) (V2 300 200)] in
--   stroke 3 JoinRound (CapStraight 0, CapStraight 0) $
--       pathToPrimitives path
--   withTexture (uniformTexture $ PixelRGBA8 0 0 0 255) $
--     withPathOrientation path 0 $
--       printTextAt font (PointSize 24) (V2 0 0) "Text on path"
--   
-- -- -- You can note that the position of the baseline match the size of the -- characters. -- -- You are not limited to text drawing while using this function, you can -- draw arbitrary geometry like in the following example: -- --
--   let path = Path (V2 100 180) False
--                   [PathCubicBezierCurveTo (V2 20 20) (V2 170 20) (V2 300 200)]
--   withTexture (uniformTexture $ PixelRGBA8 0 0 0 255) $
--     stroke 3 JoinRound (CapStraight 0, CapStraight 0) $
--         pathToPrimitives path
--   
--   withPathOrientation path 0 $ do
--     printTextAt font (PointSize 24) (V2 0 0) "TX"
--     fill $ rectangle (V2 (-10) (-10)) 30 20
--     fill $ rectangle (V2 45 0) 10 20
--     fill $ rectangle (V2 60 (-10)) 20 20
--     fill $ rectangle (V2 100 (-15)) 20 50
--   
-- withPathOrientation :: Path -> Float -> Drawing px () -> Drawing px () -- | Will stroke geometry with a given stroke width. The elements should be -- connected -- --
--   stroke 5 JoinRound (CapRound, CapRound) $ circle (V2 100 100) 75
--   
-- stroke :: Float -> Join -> (Cap, Cap) -> [Primitive] -> Drawing px () -- | With stroke geometry with a given stroke width, using a dash pattern. -- --
--   dashedStroke [5, 10, 5] 3 JoinRound (CapRound, CapStraight 0)
--          [line (V2 0 100) (V2 200 100)]
--   
-- dashedStroke :: DashPattern -> Float -> Join -> (Cap, Cap) -> [Primitive] -> Drawing px () -- | With stroke geometry with a given stroke width, using a dash pattern. -- The offset is there to specify the starting point into the pattern, -- the value can be negative. -- --
--   dashedStrokeWithOffset 3 [5, 10, 5] 3 JoinRound (CapRound, CapStraight 0)
--          [line (V2 0 100) (V2 200 100)]
--   
-- dashedStrokeWithOffset :: Float -> DashPattern -> Float -> Join -> (Cap, Cap) -> [Primitive] -> Drawing px () -- | Draw a string at a given position. Text printing imply loading a font, -- there is no default font (yet). Below an example of font rendering -- using a font installed on Microsoft Windows. -- --
--   import Graphics.Text.TrueType( loadFontFile )
--   import Codec.Picture( PixelRGBA8( .. ), writePng )
--   import Graphics.Rasterific
--   import Graphics.Rasterific.Texture
--   
--   main :: IO ()
--   main = do
--     fontErr <- loadFontFile "C:/Windows/Fonts/arial.ttf"
--     case fontErr of
--       Left err -> putStrLn err
--       Right font ->
--         writePng "text_example.png" .
--             renderDrawing 300 70 (PixelRGBA8 255 255 255 255)
--                 . withTexture (uniformTexture $ PixelRGBA8 0 0 0 255) $
--                         printTextAt font (PointSize 12) (V2 20 40)
--                              "A simple text test!"
--   
-- -- -- You can use any texture, like a gradient while rendering text. printTextAt :: Font -> PointSize -> Point -> String -> Drawing px () -- | Print complex text, using different texture font and point size for -- different parts of the text. -- --
--   let blackTexture =
--         Just . uniformTexture $ PixelRGBA8 0 0 0 255
--       redTexture =
--         Just . uniformTexture $ PixelRGBA8 255 0 0 255
--   in
--   printTextRanges (V2 20 40)
--     [ TextRange font1 (PointSize 12) "A complex " blackTexture
--     , TextRange font2 (PointSize 8) "text test" redTexture]
--   
-- printTextRanges :: Point -> [TextRange px] -> Drawing px () -- | Structure defining how to render a text range data TextRange px TextRange :: Font -> PointSize -> String -> Maybe (Texture px) -> TextRange px -- | Font used during the rendering _textFont :: TextRange px -> Font -- | Size of the text (in pixels) _textSize :: TextRange px -> PointSize -- | Text to draw | Texture to use for drawing, if Nothing, the currently -- active texture is used. _text :: TextRange px -> String _textTexture :: TextRange px -> Maybe (Texture px) -- | Font size expressed in points. You must convert size expressed in -- pixels to point using the DPI information. See pixelSizeInPointAtDpi newtype PointSize :: * PointSize :: Float -> PointSize getPointSize :: PointSize -> Float -- | This constraint ensure that a type is a pixel and we're allowed to -- modulate it's color components generically. type ModulablePixel px = (Pixel px, PackeablePixel px, Storable (PackedRepresentation px), Modulable (PixelBaseComponent px)) -- | This constraint tells us that pixel component must also be pixel and -- be the "bottom" of component, we cannot go further than a -- PixelBaseComponent level. -- -- All pixel instances of JuicyPixels should be usable. type RenderablePixel px = (ModulablePixel px, Pixel (PixelBaseComponent px), PackeablePixel (PixelBaseComponent px), Storable (PackedRepresentation (PixelBaseComponent px)), PixelBaseComponent (PixelBaseComponent px) ~ (PixelBaseComponent px)) -- | Function to call in order to start the image creation. Tested pixels -- type are PixelRGBA8 and Pixel8, pixel types in other colorspace will -- probably produce weird results. Default DPI is 96 renderDrawing :: RenderablePixel px => Int -> Int -> px -> Drawing px () -> Image px -- | Function to call in order to start the image creation. Tested pixels -- type are PixelRGBA8 and Pixel8, pixel types in other colorspace will -- probably produce weird results. renderDrawingAtDpi :: RenderablePixel px => Int -> Int -> Dpi -> px -> Drawing px () -> Image px -- | Transform a path description into a list of renderable primitives. pathToPrimitives :: Path -> [Primitive] -- | Reification of texture type data Texture px -- | Monad used to record the drawing actions. type Drawing px = F (DrawCommand px) -- | Typeclass intented at pixel value modulation. May be throwed out soon. class (Ord a, Num a) => Modulable a where coverageModulate c a = (clamped, fullValue - clamped) where clamped = modulate a c -- | A 2-dimensional vector -- --
--   >>> pure 1 :: V2 Int
--   V2 1 1
--   
-- --
--   >>> V2 1 2 + V2 3 4
--   V2 4 6
--   
-- --
--   >>> V2 1 2 * V2 3 4
--   V2 3 8
--   
-- --
--   >>> sum (V2 1 2)
--   3
--   
data V2 a V2 :: !a -> !a -> V2 a -- | Represent a point type Point = V2 Float -- | Represent a vector type Vector = V2 Float -- | Describe a cubic bezier spline, described using 4 points. -- --
--   stroke 4 JoinRound (CapRound, CapRound) $
--      [CubicBezierPrim $ CubicBezier (V2 0 10) (V2 205 250)
--                                     (V2 (-10) 250) (V2 160 35)]
--   
-- data CubicBezier CubicBezier :: {-# UNPACK #-} !Point -> {-# UNPACK #-} !Point -> {-# UNPACK #-} !Point -> {-# UNPACK #-} !Point -> CubicBezier -- | Origin point, the spline will pass through it. _cBezierX0 :: CubicBezier -> {-# UNPACK #-} !Point -- | First control point of the cubic bezier curve. _cBezierX1 :: CubicBezier -> {-# UNPACK #-} !Point -- | Second control point of the cubic bezier curve. _cBezierX2 :: CubicBezier -> {-# UNPACK #-} !Point -- | End point of the cubic bezier curve _cBezierX3 :: CubicBezier -> {-# UNPACK #-} !Point -- | Describe a simple 2D line between two points. -- --
--   fill $ LinePrim <$> [ Line (V2 10 10) (V2 190 10)
--                       , Line (V2 190 10) (V2 95 170)
--                       , Line (V2 95 170) (V2 10 10)]
--   
-- data Line Line :: {-# UNPACK #-} !Point -> {-# UNPACK #-} !Point -> Line -- | Origin point _lineX0 :: Line -> {-# UNPACK #-} !Point -- | End point _lineX1 :: Line -> {-# UNPACK #-} !Point -- | Describe a quadratic bezier spline, described using 3 points. -- --
--   fill $ BezierPrim <$> [Bezier (V2 10 10) (V2 200 50) (V2 200 100)
--                         ,Bezier (V2 200 100) (V2 150 200) (V2 120 175)
--                         ,Bezier (V2 120 175) (V2 30 100) (V2 10 10)]
--   
-- data Bezier Bezier :: {-# UNPACK #-} !Point -> {-# UNPACK #-} !Point -> {-# UNPACK #-} !Point -> Bezier -- | Origin points, the spline will pass through it. _bezierX0 :: Bezier -> {-# UNPACK #-} !Point -- | Control point, the spline won't pass on it. _bezierX1 :: Bezier -> {-# UNPACK #-} !Point -- | End point, the spline will pass through it. _bezierX2 :: Bezier -> {-# UNPACK #-} !Point -- | This datatype gather all the renderable primitives, they are kept -- separated otherwise to allow specialization on some specific -- algorithms. You can mix the different primitives in a single call : -- --
--   fill
--      [ CubicBezierPrim $ CubicBezier (V2 50 20) (V2 90 60)
--                                      (V2  5 100) (V2 50 140)
--      , LinePrim $ Line (V2 50 140) (V2 120 80)
--      , LinePrim $ Line (V2 120 80) (V2 50 20) ]
--   
-- data Primitive -- | Primitive used for lines LinePrim :: !Line -> Primitive -- | Primitive used for quadratic beziers curves BezierPrim :: !Bezier -> Primitive -- | Primitive used for cubic bezier curve CubicBezierPrim :: !CubicBezier -> Primitive -- | Describe a path in a way similar to many graphical packages, using a -- "pen" position in memory and reusing it for the next "move" For -- example the example from Primitive could be rewritten: -- --
--   fill . pathToPrimitives $ Path (V2 50 20) True
--      [ PathCubicBezierCurveTo (V2 90 60) (V2  5 100) (V2 50 140)
--      , PathLineTo (V2 120 80) ]
--   
-- data Path Path :: Point -> Bool -> [PathCommand] -> Path -- | Origin of the point, equivalent to the first "move" command. _pathOriginPoint :: Path -> Point -- | Tell if we must close the path. _pathClose :: Path -> Bool -- | List of commands in the path _pathCommand :: Path -> [PathCommand] -- | Actions to create a path data PathCommand -- | Draw a line from the current point to another point PathLineTo :: Point -> PathCommand -- | Draw a quadratic bezier curve from the current point through the -- control point to the end point. PathQuadraticBezierCurveTo :: Point -> Point -> PathCommand -- | Draw a cubic bezier curve using 2 control points. PathCubicBezierCurveTo :: Point -> Point -> Point -> PathCommand -- | This typeclass is there to help transform the geometry, by applying a -- transformation on every point of a geometric element. class Transformable a transform :: Transformable a => (Point -> Point) -> a -> a -- | Typeclass helper gathering all the points of a given geometry. class PointFoldable a foldPoints :: PointFoldable a => (b -> Point -> b) -> b -> a -> b -- | Class used to calculate bounds of various geometrical primitives. The -- calculated is precise, the bounding should be minimal with respect -- with drawn curve. class PlaneBoundable a planeBounds :: PlaneBoundable a => a -> PlaneBound -- | Represent the minimal axis aligned rectangle in which some primitives -- can be drawn. Should fit to bezier curve and not use directly their -- control points. data PlaneBound PlaneBound :: !Point -> !Point -> PlaneBound -- | Corner upper left of the bounding box of the considered primitives. _planeMinBound :: PlaneBound -> !Point -- | Corner lower right of the bounding box of the considered primitives. _planeMaxBound :: PlaneBound -> !Point -- | Extract the width of the bounds boundWidth :: PlaneBound -> Float -- | Extract the height of the bound boundHeight :: PlaneBound -> Float -- | Extract the position of the lower left corner of the bounds. boundLowerLeftCorner :: PlaneBound -> Point -- | Return a simple line ready to be stroked. -- --
--   stroke 17 JoinRound (CapRound, CapRound) $
--       line (V2 10 10) (V2 180 170)
--   
-- line :: Point -> Point -> [Primitive] -- | Generate a list of primitive representing a rectangle -- --
--   fill $ rectangle (V2 30 30) 150 100
--   
-- rectangle :: Point -> Float -> Float -> [Primitive] -- | Generate a list of primitive representing a rectangle with rounded -- corner. -- --
--   fill $ roundedRectangle (V2 10 10) 150 150 20 10
--   
-- roundedRectangle :: Point -> Float -> Float -> Float -> Float -> [Primitive] -- | Generate a list of primitive representing a circle. -- --
--   fill $ circle (V2 100 100) 75
--   
-- circle :: Point -> Float -> [Primitive] -- | Generate a list of primitive representing an ellipse. -- --
--   fill $ ellipse (V2 100 100) 75 30
--   
-- ellipse :: Point -> Float -> Float -> [Primitive] -- | Generate a strokable line out of points list. Just an helper around -- lineFromPath. -- --
--   stroke 4 JoinRound (CapRound, CapRound) $
--      polyline [V2 10 10, V2 100 70, V2 190 190]
--   
-- polyline :: [Point] -> [Primitive] -- | Generate a fillable polygon out of points list. Similar to the -- polyline function, but close the path. -- --
--   fill $ polygon [V2 30 30, V2 100 70, V2 80 170]
--   
-- polygon :: [Point] -> [Primitive] -- | Draw an image with the desired size -- --
--   drawImageAtSize textureImage 2 (V2 30 30) 128 128
--   
-- drawImageAtSize :: (Pixel px, Modulable (PixelBaseComponent px)) => Image px -> StrokeWidth -> Point -> Float -> Float -> Drawing px () -- | Simply draw an image into the canvas. Take into account any previous -- transformation performed on the geometry. -- --
--   drawImage textureImage 0 (V2 30 30)
--   
-- drawImage :: ModulablePixel px => Image px -> StrokeWidth -> Point -> Drawing px () -- | Clip the geometry to a rectangle. clip :: Point -> Point -> Primitive -> Container Primitive -- | Create a list of bezier patch from a list of points, -- --
--   bezierFromPath [a, b, c, d, e] == [Bezier a b c, Bezier c d e]
--   bezierFromPath [a, b, c, d, e, f] == [Bezier a b c, Bezier c d e]
--   bezierFromPath [a, b, c, d, e, f, g] ==
--       [Bezier a b c, Bezier c d e, Bezier e f g]
--   
bezierFromPath :: [Point] -> [Bezier] -- | Transform a list a point to a list of lines -- --
--   lineFromPath [a, b, c, d] = [Line a b, Line b c, Line c d]
--   
lineFromPath :: [Point] -> [Line] -- | Create a list of cubic bezier patch from a list of points. -- --
--   cubicBezierFromPath [a, b, c, d, e] = [CubicBezier a b c d]
--   cubicBezierFromPath [a, b, c, d, e, f, g] =
--      [CubicBezier a b c d, CubicBezier d e f g]
--   
cubicBezierFromPath :: [Point] -> [CubicBezier] -- | Gives the orientation vector for the start of the primitive. firstTangeantOf :: Primitive -> Vector -- | Gives the orientation vector at the end of the primitive. lastTangeantOf :: Primitive -> Vector -- | Extract the first point of the primitive. firstPointOf :: Primitive -> Point -- | Return the last point of a given primitive. lastPointOf :: Primitive -> Point -- | Describe how to display the join of broken lines while stroking. data Join -- | Make a curved join. JoinRound :: Join -- | Make a mitter join. Value must be positive or null. Seems to make -- sense in [0;1] only -- -- JoinMiter :: Float -> Join -- | Describe how we will "finish" the stroking that don't loop. data Cap -- | Create a straight caping on the stroke. Cap value should be positive -- and represent the distance from the end of curve to the actual cap -- -- CapStraight :: Float -> Cap -- | Create a rounded caping on the stroke. CapRound :: Cap -- | Describe the behaviour of samplers and texturers when they are out of -- the bounds of image and/or gradient. data SamplerRepeat -- | Will clamp (ie. repeat the last pixel) when out of bound SamplerPad :: SamplerRepeat -- | Will loop on it's definition domain SamplerRepeat :: SamplerRepeat -- | Will loop inverting axises SamplerReflect :: SamplerRepeat -- | Tell how to fill complex shapes when there is self intersections. If -- the filling mode is not specified, then it's the FillWinding -- method which is used. -- -- The examples used are produced with the following function: -- --
--   fillingSample :: FillMethod -> Drawing px ()
--   fillingSample fillMethod = fillWithMethod fillMethod geometry where
--     geometry = transform (applyTransformation $ scale 0.35 0.4
--                                              <> translate (V2 (-80) (-180)))
--              $ concatMap pathToPrimitives
--        [ Path (V2 484 499) True
--            [ PathCubicBezierCurveTo (V2 681 452) (V2 639 312) (V2 541 314)
--            , PathCubicBezierCurveTo (V2 327 337) (V2 224 562) (V2 484 499)
--            ]
--        , Path (V2 136 377) True
--            [ PathCubicBezierCurveTo (V2 244 253) (V2 424 420) (V2 357 489)
--            , PathCubicBezierCurveTo (V2 302 582) (V2 47 481) (V2 136 377)
--            ]
--        , Path (V2 340 265) True
--            [ PathCubicBezierCurveTo (V2 64 371) (V2 128 748) (V2 343 536)
--            , PathCubicBezierCurveTo (V2 668 216) (V2 17 273) (V2 367 575)
--            , PathCubicBezierCurveTo (V2 589 727) (V2 615 159) (V2 340 265)
--            ]
--        ]
--   
data FillMethod -- | Also known as nonzero rule. To determine if a point falls inside the -- curve, you draw an imaginary line through that point. Next you will -- count how many times that line crosses the curve before it reaches -- that point. For every clockwise rotation, you subtract 1 and for every -- counter-clockwise rotation you add 1. -- FillWinding :: FillMethod -- | This rule determines the insideness of a point on the canvas by -- drawing a ray from that point to infinity in any direction and -- counting the number of path segments from the given shape that the ray -- crosses. If this number is odd, the point is inside; if even, the -- point is outside. -- FillEvenOdd :: FillMethod -- | Dash pattern to use type DashPattern = [Float] -- | Transform a drawing into a serie of low-level drawing orders. drawOrdersOfDrawing :: RenderablePixel px => Int -> Int -> Dpi -> px -> Drawing px () -> [DrawOrder px] -- | This function will spit out drawing instructions to help debugging. -- -- The outputted code looks like Haskell, but there is no guarantee that -- it is compilable. dumpDrawing :: (Show px, Show (PixelBaseComponent px), PixelBaseComponent (PixelBaseComponent px) ~ (PixelBaseComponent px)) => Drawing px () -> String