-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A pure haskell drawing engine. -- -- -- Rasterific is a vector drawing library (a rasterizer) implemented in -- pure haskell @package Rasterific @version 0.2 -- | 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 -- | 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 -- | Inverse a transformation (if possible) inverseTransformation :: Transformation -> Transformation instance Eq Transformation instance Show Transformation instance Monoid Transformation -- | 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 -- | A texture is just a function which given pixel coordinate give back a -- pixel. The float coordinate type allow for transformations to happen -- in the pixel space. type Texture px = SamplerRepeat -> Float -> Float -> 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 :: (Pixel px, Modulable (PixelBaseComponent px)) => 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 SamplerPad gradDef
--                      (V2 100 100) 75) $
--      fill $ circle (V2 100 100) 100
--   
-- radialGradientTexture :: (Pixel px, Modulable (PixelBaseComponent px)) => 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 SamplerPad gradDef
--                      (V2 100 100) 75 (V2 70 70) ) $
--      fill $ circle (V2 100 100) 100
--   
-- radialGradientWithFocusTexture :: (Pixel px, Modulable (PixelBaseComponent px)) => Gradient px -> Point -> Float -> Point -> Texture px -- | Use another image as a texture for the filling. This texture use the -- nearest filtering, AKA no filtering at all. imageTexture :: Pixel px => Image px -> Texture px -- | Use another image as a texture for the filling. Contrary to -- imageTexture, this function perform a bilinear filtering on the -- texture. sampledImageTexture :: (Pixel px, Modulable (PixelBaseComponent px)) => 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, Modulable (PixelBaseComponent 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 -- | 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 () -- | 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 12 (V2 20 40) "A simple text test!"
--   
-- -- -- You can use any texture, like a gradient while rendering text. printTextAt :: Font -> Int -> Point -> String -> Drawing 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. renderDrawing :: (Pixel px, Pixel (PixelBaseComponent px), Modulable (PixelBaseComponent px), PixelBaseComponent (PixelBaseComponent px) ~ (PixelBaseComponent px)) => Int -> Int -> px -> Drawing px () -> Image px -- | Transform a path description into a list of renderable primitives. pathToPrimitives :: Path -> [Primitive] -- | A texture is just a function which given pixel coordinate give back a -- pixel. The float coordinate type allow for transformations to happen -- in the pixel space. type Texture px = SamplerRepeat -> Float -> Float -> px -- | Monad used to record the drawing actions. type Drawing px = Free (DrawCommand px) -- | Typeclass intented at pixel value modulation. May be throwed out soon. class (Ord a, Num a) => Modulable a -- | 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 -- | 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 :: (Pixel px, Modulable (PixelBaseComponent px)) => Image px -> StrokeWidth -> Point -> Drawing px () -- | Clip the geometry to a rectangle. clip :: Point -> Point -> Primitive -> [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] -- | 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] -- | 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 => Drawing px () -> String instance Monoid (Drawing px ()) instance Functor (DrawCommand px)