packages feed

gelatin 0.0.0.3 → 0.1.0.0

raw patch · 34 files changed

+1597/−1948 lines, 34 filesdep +mtldep +transformersdep −FontyFruitydep −GLFW-bdep −JuicyPixelsdep ~basedep ~bytestringdep ~containersbinary-addedPVP ok

version bump matches the API change (PVP)

Dependencies added: mtl, transformers

Dependencies removed: FontyFruity, GLFW-b, JuicyPixels, async, directory, file-embed, gl, time

Dependency ranges changed: base, bytestring, containers, lens, linear, vector

API changes (from Hackage documentation)

- Gelatin.Core.Color: alpha :: (Num a, Fractional a) => V4 a -> a -> V4 a
- Gelatin.Core.Color: hex :: (Num b, Fractional b) => Int -> V4 b
- Gelatin.Core.Color: solid :: V4 Float -> Fill
- Gelatin.Core.Rendering: alphaMask :: Window -> MaskRenderSource -> IO () -> IO () -> IO Rendering
- Gelatin.Core.Rendering: calculateDpi :: IO Dpi
- Gelatin.Core.Rendering: clipTexture :: GLuint -> ClippingArea -> IO GLuint
- Gelatin.Core.Rendering: colorBezRendering :: Window -> BezRenderSource -> [Bezier (V2 Float)] -> [Triangle (V4 Float)] -> IO Rendering
- Gelatin.Core.Rendering: colorFontRendering :: Window -> GeomRenderSource -> BezRenderSource -> FontString -> (V2 Float -> V4 Float) -> IO Rendering
- Gelatin.Core.Rendering: colorRendering :: Window -> GeomRenderSource -> GLuint -> [V2 Float] -> [V4 Float] -> IO Rendering
- Gelatin.Core.Rendering: filledTriangleRendering :: Window -> GeomRenderSource -> [Triangle (V2 Float)] -> Fill -> IO Rendering
- Gelatin.Core.Rendering: initGelatin :: IO Bool
- Gelatin.Core.Rendering: loadBezRenderSource :: IO BezRenderSource
- Gelatin.Core.Rendering: loadGeomRenderSource :: IO GeomRenderSource
- Gelatin.Core.Rendering: loadImageAsTexture :: FilePath -> IO (Maybe GLuint)
- Gelatin.Core.Rendering: loadMaskRenderSource :: IO MaskRenderSource
- Gelatin.Core.Rendering: loadRenderSource :: RenderDef -> IO RenderSource
- Gelatin.Core.Rendering: loadTexture :: DynamicImage -> IO GLuint
- Gelatin.Core.Rendering: loadTextureUnit :: Maybe GLuint -> DynamicImage -> IO GLuint
- Gelatin.Core.Rendering: maskRendering :: Window -> MaskRenderSource -> GLuint -> [V2 Float] -> [V2 Float] -> IO Rendering
- Gelatin.Core.Rendering: newWindow :: Int -> Int -> String -> Maybe Monitor -> Maybe Window -> IO Window
- Gelatin.Core.Rendering: stencilMask :: IO () -> IO () -> IO ()
- Gelatin.Core.Rendering: textureRendering :: Window -> GeomRenderSource -> GLuint -> [V2 Float] -> [V2 Float] -> IO Rendering
- Gelatin.Core.Rendering: textureUnitRendering :: (Maybe GLint) -> Window -> GeomRenderSource -> GLuint -> [V2 Float] -> [V2 Float] -> IO Rendering
- Gelatin.Core.Rendering: toTexture :: Window -> IO () -> IO GLuint
- Gelatin.Core.Rendering: toTextureUnit :: Maybe GLuint -> Window -> IO () -> IO GLuint
- Gelatin.Core.Rendering: transformRendering :: Transform -> Rendering -> Rendering
- Gelatin.Core.Rendering: unloadTexture :: GLuint -> IO ()
- Gelatin.Core.Rendering.Font: allFonts :: Async FontCache -> IO (Maybe [FontDescriptor])
- Gelatin.Core.Rendering.Font: compileFontCache :: IO (Async FontCache)
- Gelatin.Core.Rendering.Font: concaveTriangles :: [a] -> [Triangle a]
- Gelatin.Core.Rendering.Font: findFont :: Async FontCache -> FontDescriptor -> IO (Maybe FilePath)
- Gelatin.Core.Rendering.Font: fontGeom :: Dpi -> FontString -> ([Bezier (V2 Float)], [Triangle (V2 Float)])
- Gelatin.Core.Rendering.Font: withFont :: FontCache -> FontDescriptor -> (Font -> IO a) -> IO (Maybe a)
- Gelatin.Core.Rendering.Font: withFontAsync :: Async FontCache -> FontDescriptor -> (Font -> IO a) -> IO (Maybe a)
- Gelatin.Core.Rendering.Geometrical: bez :: (Ord a, Fractional a) => V2 a -> V2 a -> V2 a -> Bezier (V2 a)
- Gelatin.Core.Rendering.Geometrical: mat4Rotate :: (Num a, Epsilon a, Floating a) => a -> V3 a -> M44 a
- Gelatin.Core.Rendering.Geometrical: mat4Scale :: Num a => V3 a -> M44 a
- Gelatin.Core.Rendering.Geometrical: mat4Translate :: Num a => V3 a -> M44 a
- Gelatin.Core.Rendering.Geometrical: rotate :: RealFrac a => a -> Transform -> Transform
- Gelatin.Core.Rendering.Geometrical: scale :: RealFrac a => a -> a -> Transform -> Transform
- Gelatin.Core.Rendering.Geometrical: toArrows :: Floating a => [V2 a] -> [Line (V2 a)]
- Gelatin.Core.Rendering.Geometrical: toBeziers :: (Fractional a, Ord a) => [V2 a] -> [Bezier (V2 a)]
- Gelatin.Core.Rendering.Geometrical: toLines :: [a] -> [Line a]
- Gelatin.Core.Rendering.Geometrical: transform :: Transform -> V3 Float -> V3 Float
- Gelatin.Core.Rendering.Geometrical: transformPoly :: Transform -> Poly -> Poly
- Gelatin.Core.Rendering.Geometrical: transformV2 :: Transform -> V2 Float -> V2 Float
- Gelatin.Core.Rendering.Geometrical: translate :: RealFrac a => a -> a -> Transform -> Transform
- Gelatin.Core.Rendering.Geometrical: triPoints :: Triangle (V2 a) -> [V2 a]
- Gelatin.Core.Rendering.Geometrical: trisToComp :: [Triangle (V2 a)] -> [V2 a]
- Gelatin.Core.Rendering.Polylines: Join :: V2 Float -> Float -> Join
- Gelatin.Core.Rendering.Polylines: [joinLength] :: Join -> Float
- Gelatin.Core.Rendering.Polylines: [joinVector] :: Join -> V2 Float
- Gelatin.Core.Rendering.Polylines: angleBetween :: V2 Float -> V2 Float -> Float
- Gelatin.Core.Rendering.Polylines: bevelJoint :: Float -> V2 Float -> V2 Float -> V2 Float -> Joint
- Gelatin.Core.Rendering.Polylines: capFunc :: EndCap -> Float -> V2 Float -> V2 Float -> Joint
- Gelatin.Core.Rendering.Polylines: capJoin :: Float -> V2 Float -> V2 Float -> Join
- Gelatin.Core.Rendering.Polylines: data Join
- Gelatin.Core.Rendering.Polylines: entryLine :: Joint -> (V2 Float, V2 Float)
- Gelatin.Core.Rendering.Polylines: exitLine :: Joint -> (V2 Float, V2 Float)
- Gelatin.Core.Rendering.Polylines: instance GHC.Classes.Eq Gelatin.Core.Rendering.Polylines.Join
- Gelatin.Core.Rendering.Polylines: instance GHC.Show.Show Gelatin.Core.Rendering.Polylines.Join
- Gelatin.Core.Rendering.Polylines: join :: Float -> V2 Float -> V2 Float -> V2 Float -> Join
- Gelatin.Core.Rendering.Polylines: joints :: EndCap -> LineJoin -> Float -> [V2 Float] -> [Joint]
- Gelatin.Core.Rendering.Polylines: miterFunc :: LineJoin -> Float -> V2 Float -> V2 Float -> V2 Float -> Joint
- Gelatin.Core.Rendering.Polylines: miterJoint :: Float -> V2 Float -> V2 Float -> V2 Float -> Joint
- Gelatin.Core.Rendering.Polylines: miterLine :: Join -> V2 Float -> (V2 Float, V2 Float)
- Gelatin.Core.Rendering.Polylines: miters :: LineJoin -> Float -> [V2 Float] -> [Joint]
- Gelatin.Core.Rendering.Polylines: outlinePolyline :: EndCap -> LineJoin -> Float -> [V2 Float] -> [V2 Float]
- Gelatin.Core.Rendering.Polylines: polygonExpand :: Float -> [V2 Float] -> [V2 Float]
- Gelatin.Core.Rendering.Polylines: polyline :: EndCap -> LineJoin -> Float -> [V2 Float] -> [Triangle (V2 Float)]
- Gelatin.Core.Rendering.Polylines: tangentOf :: V2 Float -> V2 Float -> V2 Float -> V2 Float
- Gelatin.Core.Rendering.Polylines: tangentPoints :: Joint -> ([V2 Float], [V2 Float])
- Gelatin.Core.Rendering.Polylines: triangulate :: [Joint] -> [Triangle (V2 Float)]
- Gelatin.Core.Rendering.Polylines: triangulateArm :: Joint -> Joint -> [Triangle (V2 Float)]
- Gelatin.Core.Rendering.Polylines: triangulateCap :: Joint -> [Triangle (V2 Float)]
- Gelatin.Core.Rendering.Polylines: triangulateElbow :: Joint -> [Triangle (V2 Float)]
- Gelatin.Core.Rendering.Types: BRS :: RenderSource -> BezRenderSource
- Gelatin.Core.Rendering.Types: Bezier :: Ordering -> a -> a -> a -> Bezier a
- Gelatin.Core.Rendering.Types: Cap :: (V2 Float) -> [V2 Float] -> Joint
- Gelatin.Core.Rendering.Types: Clockwise :: Winding
- Gelatin.Core.Rendering.Types: CounterCW :: Winding
- Gelatin.Core.Rendering.Types: Elbow :: Winding -> (V2 Float, V2 Float) -> [V2 Float] -> Joint
- Gelatin.Core.Rendering.Types: EndCapBevel :: EndCap
- Gelatin.Core.Rendering.Types: EndCapButt :: EndCap
- Gelatin.Core.Rendering.Types: EndCapRound :: EndCap
- Gelatin.Core.Rendering.Types: EndCapSquare :: EndCap
- Gelatin.Core.Rendering.Types: FillColor :: (V2 Float -> V4 Float) -> Fill
- Gelatin.Core.Rendering.Types: FillResultColor :: [V4 Float] -> FillResult
- Gelatin.Core.Rendering.Types: FillResultTexture :: GLuint -> [V2 Float] -> FillResult
- Gelatin.Core.Rendering.Types: FillTexture :: FilePath -> (V2 Float -> V2 Float) -> Fill
- Gelatin.Core.Rendering.Types: FontString :: Font -> Float -> (Float, Float) -> String -> FontString
- Gelatin.Core.Rendering.Types: GRS :: RenderSource -> GeomRenderSource
- Gelatin.Core.Rendering.Types: Line :: a -> a -> Line a
- Gelatin.Core.Rendering.Types: LineJoinBevel :: LineJoin
- Gelatin.Core.Rendering.Types: LineJoinMiter :: LineJoin
- Gelatin.Core.Rendering.Types: MRS :: RenderSource -> MaskRenderSource
- Gelatin.Core.Rendering.Types: Point :: a -> Point a
- Gelatin.Core.Rendering.Types: RenderDefBS :: [(ByteString, GLuint)] -> [String] -> RenderDef
- Gelatin.Core.Rendering.Types: RenderDefFP :: [(String, GLuint)] -> [String] -> RenderDef
- Gelatin.Core.Rendering.Types: RenderSource :: ShaderProgram -> [(String, GLint)] -> RenderSource
- Gelatin.Core.Rendering.Types: Rendering :: RenderFunction -> CleanupFunction -> Rendering
- Gelatin.Core.Rendering.Types: Resources :: Async FontCache -> RenderCache -> RenderSources -> Window -> Dpi -> UTCTime -> Resources
- Gelatin.Core.Rendering.Types: Transform :: Position -> Scale -> Rotation -> Transform
- Gelatin.Core.Rendering.Types: Triangle :: a -> a -> a -> Triangle a
- Gelatin.Core.Rendering.Types: UniformUpdates :: Maybe GLint -> Maybe GLint -> (GLint, GLint) -> (GLint, GLint) -> UniformUpdates
- Gelatin.Core.Rendering.Types: [rdShaderPaths] :: RenderDef -> [(String, GLuint)]
- Gelatin.Core.Rendering.Types: [rdShaderSrcs] :: RenderDef -> [(ByteString, GLuint)]
- Gelatin.Core.Rendering.Types: [rdUniforms] :: RenderDef -> [String]
- Gelatin.Core.Rendering.Types: [rsAttributes] :: RenderSource -> [(String, GLint)]
- Gelatin.Core.Rendering.Types: [rsProgram] :: RenderSource -> ShaderProgram
- Gelatin.Core.Rendering.Types: [rsrcDpi] :: Resources -> Dpi
- Gelatin.Core.Rendering.Types: [rsrcFonts] :: Resources -> Async FontCache
- Gelatin.Core.Rendering.Types: [rsrcRenderings] :: Resources -> RenderCache
- Gelatin.Core.Rendering.Types: [rsrcSources] :: Resources -> RenderSources
- Gelatin.Core.Rendering.Types: [rsrcUTC] :: Resources -> UTCTime
- Gelatin.Core.Rendering.Types: [rsrcWindow] :: Resources -> Window
- Gelatin.Core.Rendering.Types: [tfrmRotation] :: Transform -> Rotation
- Gelatin.Core.Rendering.Types: [tfrmScale] :: Transform -> Scale
- Gelatin.Core.Rendering.Types: [tfrmTranslation] :: Transform -> Position
- Gelatin.Core.Rendering.Types: [uuHasUV] :: UniformUpdates -> (GLint, GLint)
- Gelatin.Core.Rendering.Types: [uuModelview] :: UniformUpdates -> Maybe GLint
- Gelatin.Core.Rendering.Types: [uuProjection] :: UniformUpdates -> Maybe GLint
- Gelatin.Core.Rendering.Types: [uuSampler] :: UniformUpdates -> (GLint, GLint)
- Gelatin.Core.Rendering.Types: cleanRendering :: Rendering -> IO ()
- Gelatin.Core.Rendering.Types: data BezRenderSource
- Gelatin.Core.Rendering.Types: data Bezier a
- Gelatin.Core.Rendering.Types: data EndCap
- Gelatin.Core.Rendering.Types: data Fill
- Gelatin.Core.Rendering.Types: data FillResult
- Gelatin.Core.Rendering.Types: data FontString
- Gelatin.Core.Rendering.Types: data GeomRenderSource
- Gelatin.Core.Rendering.Types: data Joint
- Gelatin.Core.Rendering.Types: data Line a
- Gelatin.Core.Rendering.Types: data LineJoin
- Gelatin.Core.Rendering.Types: data MaskRenderSource
- Gelatin.Core.Rendering.Types: data Point a
- Gelatin.Core.Rendering.Types: data RenderDef
- Gelatin.Core.Rendering.Types: data RenderSource
- Gelatin.Core.Rendering.Types: data Rendering
- Gelatin.Core.Rendering.Types: data Resources
- Gelatin.Core.Rendering.Types: data Transform
- Gelatin.Core.Rendering.Types: data Triangle a
- Gelatin.Core.Rendering.Types: data UniformUpdates
- Gelatin.Core.Rendering.Types: data Winding
- Gelatin.Core.Rendering.Types: instance GHC.Base.Functor Gelatin.Core.Rendering.Types.Bezier
- Gelatin.Core.Rendering.Types: instance GHC.Base.Functor Gelatin.Core.Rendering.Types.Line
- Gelatin.Core.Rendering.Types: instance GHC.Base.Functor Gelatin.Core.Rendering.Types.Point
- Gelatin.Core.Rendering.Types: instance GHC.Base.Functor Gelatin.Core.Rendering.Types.Triangle
- Gelatin.Core.Rendering.Types: instance GHC.Base.Monoid Gelatin.Core.Rendering.Types.Rendering
- Gelatin.Core.Rendering.Types: instance GHC.Base.Monoid Gelatin.Core.Rendering.Types.Transform
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq Gelatin.Core.Rendering.Types.EndCap
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq Gelatin.Core.Rendering.Types.Joint
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq Gelatin.Core.Rendering.Types.LineJoin
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq Gelatin.Core.Rendering.Types.RenderDef
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq Gelatin.Core.Rendering.Types.Winding
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Gelatin.Core.Rendering.Types.Bezier a)
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Gelatin.Core.Rendering.Types.Line a)
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Gelatin.Core.Rendering.Types.Primitive a)
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Gelatin.Core.Rendering.Types.Triangle a)
- Gelatin.Core.Rendering.Types: instance GHC.Classes.Ord Gelatin.Core.Rendering.Types.RenderDef
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show Gelatin.Core.Rendering.Types.EndCap
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show Gelatin.Core.Rendering.Types.Joint
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show Gelatin.Core.Rendering.Types.LineJoin
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show Gelatin.Core.Rendering.Types.RenderDef
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show Gelatin.Core.Rendering.Types.RenderSource
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show Gelatin.Core.Rendering.Types.Transform
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show Gelatin.Core.Rendering.Types.Winding
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show a => GHC.Show.Show (Gelatin.Core.Rendering.Types.Bezier a)
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show a => GHC.Show.Show (Gelatin.Core.Rendering.Types.Line a)
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show a => GHC.Show.Show (Gelatin.Core.Rendering.Types.Primitive a)
- Gelatin.Core.Rendering.Types: instance GHC.Show.Show a => GHC.Show.Show (Gelatin.Core.Rendering.Types.Triangle a)
- Gelatin.Core.Rendering.Types: runRendering :: Transform -> Rendering -> IO ()
- Gelatin.Core.Rendering.Types: type ClippingArea = (V2 Int, V2 Int)
- Gelatin.Core.Shader: bezLoc :: GLuint
- Gelatin.Core.Shader: colorLoc :: GLuint
- Gelatin.Core.Shader: compileProgram :: [GLuint] -> IO GLuint
- Gelatin.Core.Shader: compileShader :: ByteString -> GLuint -> IO GLuint
- Gelatin.Core.Shader: fragSourceBezier :: ByteString
- Gelatin.Core.Shader: fragSourceGeom :: ByteString
- Gelatin.Core.Shader: fragSourceMask :: ByteString
- Gelatin.Core.Shader: positionLoc :: GLuint
- Gelatin.Core.Shader: uvLoc :: GLuint
- Gelatin.Core.Shader: vertSourceBezier :: ByteString
- Gelatin.Core.Shader: vertSourceGeom :: ByteString
- Gelatin.Core.Shader: vertSourceMask :: ByteString
- Gelatin.Core.Triangulation.Common: cycleN :: a -> [a] -> [[a]]
- Gelatin.Core.Triangulation.Common: cycleNeighbours :: [a] -> [[a]]
- Gelatin.Core.Triangulation.Common: insidePoly :: Poly -> Poly -> Bool
- Gelatin.Core.Triangulation.Common: pathHasPoint :: (R1 f, R2 f, Ord a, Fractional a) => [f a] -> f a -> Bool
- Gelatin.Core.Triangulation.Common: pointInside :: (V2 Float) -> Poly -> Bool
- Gelatin.Core.Triangulation.Common: rotateLeft :: [a] -> [a]
- Gelatin.Core.Triangulation.Common: signedArea :: Num a => [V2 a] -> a
- Gelatin.Core.Triangulation.Common: signedAreaOfPoints :: Num a => [V2 a] -> a
- Gelatin.Core.Triangulation.Common: triangleArea :: Fractional a => V2 a -> V2 a -> V2 a -> a
- Gelatin.Core.Triangulation.Common: type Poly = [V2 Float]
- Gelatin.Core.Triangulation.EarClipping: area :: Fractional a => V2 a -> V2 a -> V2 a -> a
- Gelatin.Core.Triangulation.EarClipping: removeColinears :: (Fractional a, Eq a) => [V2 a] -> [V2 a]
- Gelatin.Core.Triangulation.EarClipping: removeHeadTail :: Eq a => [a] -> [a]
- Gelatin.Core.Triangulation.EarClipping: triangulate :: [V2 Float] -> [Triangle (V2 Float)]
- Gelatin.Core.Triangulation.KET: triangulate :: RealFrac a => [V2 a] -> [(V2 a, V2 a, V2 a)]
+ Gelatin.Compiler: Alpha :: Float -> Raster
+ Gelatin.Compiler: Backend :: BackendOps tex event -> BackendCompiler vert spatial rot rast -> Backend tex event vert spatial rot rast
+ Gelatin.Compiler: BackendComp :: (Renderer spatial rot rast -> RenderingOption -> Renderer spatial rot rast) -> GeometryCompiler vert spatial rot rast -> BackendCompiler vert spatial rot rast
+ Gelatin.Compiler: BackendOps :: IO (V2 Int) -> IO (V2 Int) -> IO () -> IO () -> (V4 Float -> IO ()) -> (FilePath -> IO (Maybe (tex, V2 Int))) -> ([tex] -> IO () -> IO ()) -> IO [event] -> BackendOps tex event
+ Gelatin.Compiler: ColorReplacement :: (V4 Float) -> Raster
+ Gelatin.Compiler: GeometryCompiler :: (VertexType -> Vector vx -> IO (Renderer v r s)) -> (Stroke -> Vector vx -> IO (Renderer v r s)) -> GeometryCompiler vx v r s
+ Gelatin.Compiler: Multiply :: (V4 Float) -> Raster
+ Gelatin.Compiler: Spatial :: (Affine v r) -> RenderTransform v r s
+ Gelatin.Compiler: Special :: s -> RenderTransform v r s
+ Gelatin.Compiler: VertexBeziers :: VertexType
+ Gelatin.Compiler: VertexFan :: VertexType
+ Gelatin.Compiler: VertexStrip :: VertexType
+ Gelatin.Compiler: VertexTriangles :: VertexType
+ Gelatin.Compiler: [backendCompApplyOption] :: BackendCompiler vert spatial rot rast -> Renderer spatial rot rast -> RenderingOption -> Renderer spatial rot rast
+ Gelatin.Compiler: [backendCompCompiler] :: BackendCompiler vert spatial rot rast -> GeometryCompiler vert spatial rot rast
+ Gelatin.Compiler: [backendCompiler] :: Backend tex event vert spatial rot rast -> BackendCompiler vert spatial rot rast
+ Gelatin.Compiler: [backendOpAllocTexture] :: BackendOps tex event -> FilePath -> IO (Maybe (tex, V2 Int))
+ Gelatin.Compiler: [backendOpBindTextures] :: BackendOps tex event -> [tex] -> IO () -> IO ()
+ Gelatin.Compiler: [backendOpClearWindow] :: BackendOps tex event -> IO ()
+ Gelatin.Compiler: [backendOpGetEvents] :: BackendOps tex event -> IO [event]
+ Gelatin.Compiler: [backendOpGetFramebufferSize] :: BackendOps tex event -> IO (V2 Int)
+ Gelatin.Compiler: [backendOpGetWindowSize] :: BackendOps tex event -> IO (V2 Int)
+ Gelatin.Compiler: [backendOpSetClearColor] :: BackendOps tex event -> V4 Float -> IO ()
+ Gelatin.Compiler: [backendOpUpdateWindow] :: BackendOps tex event -> IO ()
+ Gelatin.Compiler: [backendOps] :: Backend tex event vert spatial rot rast -> BackendOps tex event
+ Gelatin.Compiler: [compileLine] :: GeometryCompiler vx v r s -> Stroke -> Vector vx -> IO (Renderer v r s)
+ Gelatin.Compiler: [compileShapes] :: GeometryCompiler vx v r s -> VertexType -> Vector vx -> IO (Renderer v r s)
+ Gelatin.Compiler: allocTexture :: Backend tex event vert spatial rot rast -> FilePath -> IO (Maybe (tex, V2 Int))
+ Gelatin.Compiler: alpha :: Float -> RenderTransform2
+ Gelatin.Compiler: applyCompilerOption :: Backend tex event vert spatial rot rast -> Renderer spatial rot rast -> RenderingOption -> Renderer spatial rot rast
+ Gelatin.Compiler: bindTextures :: Backend tex event vert spatial rot rast -> [tex] -> IO () -> IO ()
+ Gelatin.Compiler: clearWindow :: Backend tex event vert spatial rot rast -> IO ()
+ Gelatin.Compiler: compileGeometry :: GeometryCompiler vx v r s -> [StrokeAttr] -> RawGeometry vx -> IO (Renderer v r s)
+ Gelatin.Compiler: compilePicture :: MonadIO m => Backend tex event vert spatial rot rast -> Picture tex vert a -> m (a, Renderer spatial rot rast)
+ Gelatin.Compiler: compilePictureData :: MonadIO m => Backend tex event vert spatial rot rast -> PictureData tex vert -> m (Renderer spatial rot rast)
+ Gelatin.Compiler: compilePictureT :: MonadIO m => Backend tex event vert spatial rot rast -> PictureT tex vert m a -> m (a, Renderer spatial rot rast)
+ Gelatin.Compiler: compiler :: Backend tex event vert spatial rot rast -> GeometryCompiler vert spatial rot rast
+ Gelatin.Compiler: data Backend tex event vert spatial rot rast
+ Gelatin.Compiler: data BackendCompiler vert spatial rot rast
+ Gelatin.Compiler: data BackendOps tex event
+ Gelatin.Compiler: data GeometryCompiler vx v r s
+ Gelatin.Compiler: data Raster
+ Gelatin.Compiler: data RenderTransform v r s
+ Gelatin.Compiler: data VertexType
+ Gelatin.Compiler: extractSpatial :: [RenderTransform v r s] -> [Affine v r]
+ Gelatin.Compiler: getEvents :: Backend tex event vert spatial rot rast -> IO [event]
+ Gelatin.Compiler: instance GHC.Classes.Eq Gelatin.Compiler.Raster
+ Gelatin.Compiler: instance GHC.Classes.Eq Gelatin.Compiler.VertexType
+ Gelatin.Compiler: instance GHC.Show.Show Gelatin.Compiler.Raster
+ Gelatin.Compiler: instance GHC.Show.Show Gelatin.Compiler.VertexType
+ Gelatin.Compiler: move :: Float -> Float -> RenderTransform2
+ Gelatin.Compiler: moveV2 :: V2 Float -> RenderTransform2
+ Gelatin.Compiler: multiply :: Float -> Float -> Float -> Float -> RenderTransform2
+ Gelatin.Compiler: multiplyV4 :: V4 Float -> RenderTransform2
+ Gelatin.Compiler: redChannelReplacement :: Float -> Float -> Float -> Float -> RenderTransform2
+ Gelatin.Compiler: redChannelReplacementV4 :: V4 Float -> RenderTransform2
+ Gelatin.Compiler: rotate :: Float -> RenderTransform2
+ Gelatin.Compiler: scale :: Float -> Float -> RenderTransform2
+ Gelatin.Compiler: scaleV2 :: V2 Float -> RenderTransform2
+ Gelatin.Compiler: type MakeCompiler z vx v r s = z -> GeometryCompiler vx v r s
+ Gelatin.Compiler: type RenderTransform2 = RenderTransform (V2 Float) Float Raster
+ Gelatin.Compiler: type Renderer v r s = (IO (), [RenderTransform v r s] -> IO ())
+ Gelatin.Compiler: type Renderer2 = Renderer (V2 Float) Float Raster
+ Gelatin.Compiler: unwrapTransforms :: [RenderTransform2] -> (M44 Float, Float, V4 Float, Maybe (V4 Float))
+ Gelatin.Compiler: updateWindow :: Backend tex event vert spatial rot rast -> IO ()
+ Gelatin.Core.Bezier: arcBez3 :: (Epsilon a, RealFloat a, Unbox a) => a -> a -> a -> a -> Vector (QuadraticBezier (V2 a))
+ Gelatin.Core.Bezier: arcBez4 :: (Epsilon a, RealFloat a) => a -> a -> a -> a -> [CubicBezier (V2 a)]
+ Gelatin.Core.Bezier: bez3 :: V2 a -> V2 a -> V2 a -> QuadraticBezier (V2 a)
+ Gelatin.Core.Bezier: bez3ToBez :: (Ord a, Fractional a, Unbox a) => QuadraticBezier (V2 a) -> Bezier (V2 a)
+ Gelatin.Core.Bezier: bez3ToBezInner :: (Ord a, Fractional a, Unbox a) => QuadraticBezier (V2 a) -> Bezier (V2 a)
+ Gelatin.Core.Bezier: bez3ToBezOuter :: (Ord a, Fractional a, Unbox a) => QuadraticBezier (V2 a) -> Bezier (V2 a)
+ Gelatin.Core.Bezier: bez4 :: V2 a -> V2 a -> V2 a -> V2 a -> CubicBezier (V2 a)
+ Gelatin.Core.Bezier: bez4ToBez :: (Ord a, Fractional a, Unbox a) => CubicBezier (V2 a) -> Vector (Bezier (V2 a))
+ Gelatin.Core.Bezier: bez4ToBezInner :: (Ord a, Fractional a, Unbox a) => CubicBezier (V2 a) -> Vector (Bezier (V2 a))
+ Gelatin.Core.Bezier: bez4ToBezOuter :: (Ord a, Fractional a, Unbox a) => CubicBezier (V2 a) -> Vector (Bezier (V2 a))
+ Gelatin.Core.Bezier: bez4sToPath :: (RealFloat a, Unbox a) => a -> a -> Vector (CubicBezier (V2 a)) -> Vector (V2 a)
+ Gelatin.Core.Bezier: bezToBez3 :: Bezier a -> QuadraticBezier a
+ Gelatin.Core.Bezier: bezier :: (Ord a, Fractional a) => V2 a -> V2 a -> V2 a -> Bezier (V2 a)
+ Gelatin.Core.Bezier: cleanSeqDupes :: (Eq a, Unbox a) => Vector a -> Vector a
+ Gelatin.Core.Bezier: cornerBez3 :: (RealFloat a, Unbox a) => a -> a -> Vector (QuadraticBezier (V2 a))
+ Gelatin.Core.Bezier: cornerBez4 :: RealFloat a => a -> a -> CubicBezier (V2 a)
+ Gelatin.Core.Bezier: deCasteljau :: (Additive f, R1 f, R2 f, Num a) => a -> [f a] -> f a
+ Gelatin.Core.Bezier: demoteCubic :: (Fractional a, Unbox a) => CubicBezier (V2 a) -> Vector (QuadraticBezier (V2 a))
+ Gelatin.Core.Bezier: ellipseBez3 :: (Epsilon a, RealFloat a, Unbox a) => a -> a -> Vector (QuadraticBezier (V2 a))
+ Gelatin.Core.Bezier: ellipseBez4 :: (Epsilon a, RealFloat a) => a -> a -> [CubicBezier (V2 a)]
+ Gelatin.Core.Bezier: flipBez4 :: CubicBezier a -> CubicBezier a
+ Gelatin.Core.Bezier: fmapBezier :: (a -> b) -> Bezier a -> Bezier b
+ Gelatin.Core.Bezier: fmapCubicBezier :: (a -> b) -> CubicBezier a -> CubicBezier b
+ Gelatin.Core.Bezier: fmapQuadraticBezier :: (a -> b) -> QuadraticBezier a -> QuadraticBezier b
+ Gelatin.Core.Bezier: subdivideAdaptive :: (RealFloat a, Unbox a) => a -> a -> QuadraticBezier (V2 a) -> Vector (V2 a)
+ Gelatin.Core.Bezier: subdivideAdaptive3 :: (RealFloat a, Unbox a) => a -> a -> QuadraticBezier (V2 a) -> Vector (V2 a)
+ Gelatin.Core.Bezier: subdivideAdaptive4 :: (RealFloat a, Unbox a) => a -> a -> CubicBezier (V2 a) -> Vector (V2 a)
+ Gelatin.Core.Bezier: transformBezier :: Num a => M44 a -> Bezier (V2 a) -> Bezier (V2 a)
+ Gelatin.Core.Bezier: transformCubicBezier :: Num a => M44 a -> CubicBezier (V2 a) -> CubicBezier (V2 a)
+ Gelatin.Core.Bezier: transformQuadraticBezier :: Num a => M44 a -> QuadraticBezier (V2 a) -> QuadraticBezier (V2 a)
+ Gelatin.Core.Bezier: triangleArea :: Num a => V2 a -> V2 a -> V2 a -> a
+ Gelatin.Core.Bezier: type Bezier a = (Bool, a, a, a)
+ Gelatin.Core.Bezier: type CubicBezier a = (a, a, a, a)
+ Gelatin.Core.Bezier: type QuadraticBezier a = (a, a, a)
+ Gelatin.Core.Bounds: applyTfrmToBox :: M44 Float -> BBox -> BBox
+ Gelatin.Core.Bounds: applyTfrmToCube :: M44 Float -> BBox -> BBox
+ Gelatin.Core.Bounds: both :: Arrow a => a d c -> a (d, d) (c, c)
+ Gelatin.Core.Bounds: boundingBox :: (Unbox a, Real a) => Vector (V2 a) -> BBox
+ Gelatin.Core.Bounds: boundingCube :: (Unbox a, Real a) => Vector (V3 a) -> BCube
+ Gelatin.Core.Bounds: foldIntoBox :: Vector BBox -> BBox
+ Gelatin.Core.Bounds: foldIntoCube :: Vector BCube -> BCube
+ Gelatin.Core.Bounds: listToBox :: [V2 Float] -> BBox
+ Gelatin.Core.Bounds: listToCube :: [V3 Float] -> BCube
+ Gelatin.Core.Bounds: pointInBox :: V2 Float -> BBox -> Bool
+ Gelatin.Core.Bounds: pointInCube :: V2 Float -> BBox -> Bool
+ Gelatin.Core.Bounds: type BBox = (V2 Float, V2 Float)
+ Gelatin.Core.Bounds: type BCube = (V3 Float, V3 Float)
+ Gelatin.Core.Color: canary :: Fractional a => V4 a
+ Gelatin.Core.Color: fromHex :: Fractional b => Int -> V4 b
+ Gelatin.Core.Color: type Color = V4 Float
+ Gelatin.Core.Color: withAlpha :: V4 a -> a -> V4 a
+ Gelatin.Core.Polyline: expandPolyline :: Unbox (f Float) => Vector (V2 Float) -> Vector (f Float) -> Float -> Float -> Maybe (PolylineData f)
+ Gelatin.Core.Polyline: type PolylineData f = (Vector (V2 Float), Vector (f Float), Vector (V2 Float), Vector (V2 Float), Vector (V2 Float), Float)
+ Gelatin.Core.Stroke: LineCapButt :: LineCap
+ Gelatin.Core.Stroke: LineCapNone :: LineCap
+ Gelatin.Core.Stroke: LineCapRound :: LineCap
+ Gelatin.Core.Stroke: LineCapSquare :: LineCap
+ Gelatin.Core.Stroke: LineCapTriIn :: LineCap
+ Gelatin.Core.Stroke: LineCapTriOut :: LineCap
+ Gelatin.Core.Stroke: Stroke :: Float -> Float -> (LineCap, LineCap) -> Stroke
+ Gelatin.Core.Stroke: StrokeCaps :: (LineCap, LineCap) -> StrokeAttr
+ Gelatin.Core.Stroke: StrokeFeather :: Float -> StrokeAttr
+ Gelatin.Core.Stroke: StrokeNone :: StrokeAttr
+ Gelatin.Core.Stroke: StrokeWidth :: Float -> StrokeAttr
+ Gelatin.Core.Stroke: [strokeFeather] :: Stroke -> Float
+ Gelatin.Core.Stroke: [strokeLineCaps] :: Stroke -> (LineCap, LineCap)
+ Gelatin.Core.Stroke: [strokeWidth] :: Stroke -> Float
+ Gelatin.Core.Stroke: data LineCap
+ Gelatin.Core.Stroke: data Stroke
+ Gelatin.Core.Stroke: data StrokeAttr
+ Gelatin.Core.Stroke: defaultStroke :: Stroke
+ Gelatin.Core.Stroke: instance GHC.Classes.Eq Gelatin.Core.Stroke.LineCap
+ Gelatin.Core.Stroke: instance GHC.Classes.Eq Gelatin.Core.Stroke.Stroke
+ Gelatin.Core.Stroke: instance GHC.Classes.Eq Gelatin.Core.Stroke.StrokeAttr
+ Gelatin.Core.Stroke: instance GHC.Classes.Ord Gelatin.Core.Stroke.LineCap
+ Gelatin.Core.Stroke: instance GHC.Enum.Enum Gelatin.Core.Stroke.LineCap
+ Gelatin.Core.Stroke: instance GHC.Generics.Generic Gelatin.Core.Stroke.LineCap
+ Gelatin.Core.Stroke: instance GHC.Generics.Generic Gelatin.Core.Stroke.Stroke
+ Gelatin.Core.Stroke: instance GHC.Generics.Generic Gelatin.Core.Stroke.StrokeAttr
+ Gelatin.Core.Stroke: instance GHC.Show.Show Gelatin.Core.Stroke.LineCap
+ Gelatin.Core.Stroke: instance GHC.Show.Show Gelatin.Core.Stroke.Stroke
+ Gelatin.Core.Stroke: instance GHC.Show.Show Gelatin.Core.Stroke.StrokeAttr
+ Gelatin.Core.Stroke: strokeAttr :: Maybe Stroke -> StrokeAttr -> Maybe Stroke
+ Gelatin.Core.Stroke: strokeWith :: [StrokeAttr] -> Stroke
+ Gelatin.Core.Transform: Rotate :: r -> Affine a r
+ Gelatin.Core.Transform: Scale :: a -> Affine a r
+ Gelatin.Core.Transform: Translate :: a -> Affine a r
+ Gelatin.Core.Transform: affine2Modelview :: (Num a, Real a, Floating a, Epsilon a) => Affine2 a -> M44 a
+ Gelatin.Core.Transform: affine2sModelview :: (Num a, Real a, Floating a, Epsilon a) => [Affine2 a] -> M44 a
+ Gelatin.Core.Transform: affine3Modelview :: (Num a, Real a, Floating a, Epsilon a) => Affine3 a -> M44 a
+ Gelatin.Core.Transform: data Affine a r
+ Gelatin.Core.Transform: demoteV3 :: V3 a -> V2 a
+ Gelatin.Core.Transform: instance (GHC.Classes.Eq r, GHC.Classes.Eq a) => GHC.Classes.Eq (Gelatin.Core.Transform.Affine a r)
+ Gelatin.Core.Transform: instance (GHC.Show.Show r, GHC.Show.Show a) => GHC.Show.Show (Gelatin.Core.Transform.Affine a r)
+ Gelatin.Core.Transform: m41ToV3 :: V4 (V1 a) -> V3 a
+ Gelatin.Core.Transform: mat4Rotate :: (Num a, Epsilon a, Floating a) => a -> V3 a -> M44 a
+ Gelatin.Core.Transform: mat4Scale :: Num a => V3 a -> M44 a
+ Gelatin.Core.Transform: mat4Translate :: Num a => V3 a -> M44 a
+ Gelatin.Core.Transform: promoteAffine2 :: Num a => Affine2 a -> Affine3 a
+ Gelatin.Core.Transform: promoteV2 :: Num a => V2 a -> V3 a
+ Gelatin.Core.Transform: rotateAbout :: (Num a, Epsilon a, Floating a) => V3 a -> a -> V3 a -> V3 a
+ Gelatin.Core.Transform: transformPoly :: M44 Float -> [V2 Float] -> [V2 Float]
+ Gelatin.Core.Transform: transformV2 :: Num a => M44 a -> V2 a -> V2 a
+ Gelatin.Core.Transform: transformV3 :: RealFloat a => M44 a -> V3 a -> V3 a
+ Gelatin.Core.Transform: type Affine2 a = Affine (V2 a) a
+ Gelatin.Core.Transform: type Affine3 a = Affine (V3 a) (a, V3 a)
+ Gelatin.Core.Transform: v3ToM41 :: Num a => V3 a -> V4 (V1 a)
+ Gelatin.Core.Triangle: bezToTri :: Bezier a -> Triangle a
+ Gelatin.Core.Triangle: fmapTriangle :: (t -> t1) -> (t, t, t) -> (t1, t1, t1)
+ Gelatin.Core.Triangle: sizeToTris :: V2 Float -> Vector (Triangle (V2 Float))
+ Gelatin.Core.Triangle: triBounds :: Triangle (V2 Float) -> BBox
+ Gelatin.Core.Triangle: triPoints :: Unbox a => Triangle (V2 a) -> Vector (V2 a)
+ Gelatin.Core.Triangle: triToPath :: Unbox a => Triangle a -> Vector a
+ Gelatin.Core.Triangle: trisToComp :: Unbox a => Vector (Triangle (V2 a)) -> Vector (V2 a)
+ Gelatin.Core.Triangle: type Triangle a = (a, a, a)
+ Gelatin.Core.Utils: pathHasPoint :: (Ord a, Fractional a, Unbox a) => Vector (V2 a) -> V2 a -> Bool
+ Gelatin.Picture: Geometry :: StateT (Vector (RawGeometry a)) m b -> GeometryT a m b
+ Gelatin.Picture: PictureData :: Vector (RawGeometry vertex) -> [StrokeAttr] -> [texture] -> [RenderingOption] -> PictureData texture vertex
+ Gelatin.Picture: RawBeziers :: (Vector a) -> RawGeometry a
+ Gelatin.Picture: RawLine :: (Vector a) -> RawGeometry a
+ Gelatin.Picture: RawTriangleFan :: (Vector a) -> RawGeometry a
+ Gelatin.Picture: RawTriangleStrip :: (Vector a) -> RawGeometry a
+ Gelatin.Picture: RawTriangles :: (Vector a) -> RawGeometry a
+ Gelatin.Picture: StencilMaskOption :: RenderingOption
+ Gelatin.Picture: Vertices :: StateT (Vector a) m b -> VerticesT a m b
+ Gelatin.Picture: [_picDataGeometry] :: PictureData texture vertex -> Vector (RawGeometry vertex)
+ Gelatin.Picture: [_picDataOptions] :: PictureData texture vertex -> [RenderingOption]
+ Gelatin.Picture: [_picDataStroke] :: PictureData texture vertex -> [StrokeAttr]
+ Gelatin.Picture: [_picDataTextures] :: PictureData texture vertex -> [texture]
+ Gelatin.Picture: [unGeometry] :: GeometryT a m b -> StateT (Vector (RawGeometry a)) m b
+ Gelatin.Picture: [unVertices] :: VerticesT a m b -> StateT (Vector a) m b
+ Gelatin.Picture: addVertexList :: (Monad m, Unbox a) => [a] -> VerticesT a m ()
+ Gelatin.Picture: bez :: (Monad m, Unbox a) => a -> a -> a -> VerticesT a m ()
+ Gelatin.Picture: beziers :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture: data PictureData texture vertex
+ Gelatin.Picture: data RawGeometry a
+ Gelatin.Picture: data RenderingOption
+ Gelatin.Picture: fan :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture: getRawGeometry :: Monad m => PictureT t v m (Vector (RawGeometry v))
+ Gelatin.Picture: getRenderingOptions :: Monad m => PictureT t v m [RenderingOption]
+ Gelatin.Picture: getStroke :: Monad m => PictureT t v m [StrokeAttr]
+ Gelatin.Picture: getTextures :: Monad m => PictureT t v m [t]
+ Gelatin.Picture: line :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture: mapGeometry :: (Monad m, Unbox a, Unbox c) => (a -> c) -> GeometryT a m b -> GeometryT c m ()
+ Gelatin.Picture: mapRawGeometry :: (Unbox a, Unbox b) => (a -> b) -> RawGeometry a -> RawGeometry b
+ Gelatin.Picture: mapToSpaceVec :: (Monad m, Unbox v, Unbox s) => (v -> s) -> PictureT t v m (Vector s)
+ Gelatin.Picture: mapVertices :: (Monad m, Unbox a, Unbox c) => (a -> c) -> VerticesT a m b -> VerticesT c m ()
+ Gelatin.Picture: newtype GeometryT a m b
+ Gelatin.Picture: newtype VerticesT a m b
+ Gelatin.Picture: pictureBounds2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float, V2 Float)
+ Gelatin.Picture: pictureBounds3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m BCube
+ Gelatin.Picture: pictureCenter2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float)
+ Gelatin.Picture: pictureCenter3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m (V3 Float)
+ Gelatin.Picture: pictureOrigin2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float)
+ Gelatin.Picture: pictureOrigin3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m (V3 Float)
+ Gelatin.Picture: pictureSize2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float)
+ Gelatin.Picture: pictureSize3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m (V3 Float)
+ Gelatin.Picture: runGeometry :: Geometry a -> Vector (RawGeometry a)
+ Gelatin.Picture: runGeometryT :: Monad m => GeometryT a m b -> m (Vector (RawGeometry a))
+ Gelatin.Picture: runPicture :: Picture t v a -> (a, PictureData t v)
+ Gelatin.Picture: runPictureT :: PictureT t v m a -> m (a, PictureData t v)
+ Gelatin.Picture: runVertices :: Unbox a => Vertices a -> Vector a
+ Gelatin.Picture: runVerticesT :: (Monad m, Unbox a) => VerticesT a m b -> m (Vector a)
+ Gelatin.Picture: segment :: (Monad m, Unbox a) => a -> a -> VerticesT a m ()
+ Gelatin.Picture: setGeometry :: Monad m => GeometryT v m () -> PictureT t v m ()
+ Gelatin.Picture: setRawGeometry :: Monad m => Vector (RawGeometry v) -> PictureT t v m ()
+ Gelatin.Picture: setRenderingOptions :: Monad m => [RenderingOption] -> PictureT t v m ()
+ Gelatin.Picture: setStroke :: Monad m => [StrokeAttr] -> PictureT t v m ()
+ Gelatin.Picture: setTextures :: Monad m => [t] -> PictureT t v m ()
+ Gelatin.Picture: strip :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture: to :: (Monad m, Unbox a) => a -> VerticesT a m ()
+ Gelatin.Picture: tri :: (Monad m, Unbox a) => a -> a -> a -> VerticesT a m ()
+ Gelatin.Picture: triangles :: (Unbox a, Monad m) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture: type Geometry a = GeometryT a Identity ()
+ Gelatin.Picture: type Picture t v = PictureT t v Identity
+ Gelatin.Picture: type PictureT tex vert = StateT (PictureData tex vert)
+ Gelatin.Picture: type Vertices a = VerticesT a Identity ()
+ Gelatin.Picture.Internal: Geometry :: StateT (Vector (RawGeometry a)) m b -> GeometryT a m b
+ Gelatin.Picture.Internal: PictureData :: Vector (RawGeometry vertex) -> [StrokeAttr] -> [texture] -> [RenderingOption] -> PictureData texture vertex
+ Gelatin.Picture.Internal: RawBeziers :: (Vector a) -> RawGeometry a
+ Gelatin.Picture.Internal: RawLine :: (Vector a) -> RawGeometry a
+ Gelatin.Picture.Internal: RawTriangleFan :: (Vector a) -> RawGeometry a
+ Gelatin.Picture.Internal: RawTriangleStrip :: (Vector a) -> RawGeometry a
+ Gelatin.Picture.Internal: RawTriangles :: (Vector a) -> RawGeometry a
+ Gelatin.Picture.Internal: StencilMaskOption :: RenderingOption
+ Gelatin.Picture.Internal: Vertices :: StateT (Vector a) m b -> VerticesT a m b
+ Gelatin.Picture.Internal: [_picDataGeometry] :: PictureData texture vertex -> Vector (RawGeometry vertex)
+ Gelatin.Picture.Internal: [_picDataOptions] :: PictureData texture vertex -> [RenderingOption]
+ Gelatin.Picture.Internal: [_picDataStroke] :: PictureData texture vertex -> [StrokeAttr]
+ Gelatin.Picture.Internal: [_picDataTextures] :: PictureData texture vertex -> [texture]
+ Gelatin.Picture.Internal: [unGeometry] :: GeometryT a m b -> StateT (Vector (RawGeometry a)) m b
+ Gelatin.Picture.Internal: [unVertices] :: VerticesT a m b -> StateT (Vector a) m b
+ Gelatin.Picture.Internal: add :: Monad m => RawGeometry a -> StateT (Vector (RawGeometry a)) m ()
+ Gelatin.Picture.Internal: addVertexList :: (Monad m, Unbox a) => [a] -> VerticesT a m ()
+ Gelatin.Picture.Internal: bez :: (Monad m, Unbox a) => a -> a -> a -> VerticesT a m ()
+ Gelatin.Picture.Internal: beziers :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture.Internal: bothToFrac :: (Real a, Fractional b) => (V2 a, V2 a) -> (V2 b, V2 b)
+ Gelatin.Picture.Internal: data PictureData texture vertex
+ Gelatin.Picture.Internal: data RawGeometry a
+ Gelatin.Picture.Internal: data RenderingOption
+ Gelatin.Picture.Internal: emptyPictureData :: PictureData t v
+ Gelatin.Picture.Internal: fan :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture.Internal: getRawGeometry :: Monad m => PictureT t v m (Vector (RawGeometry v))
+ Gelatin.Picture.Internal: getRenderingOptions :: Monad m => PictureT t v m [RenderingOption]
+ Gelatin.Picture.Internal: getStroke :: Monad m => PictureT t v m [StrokeAttr]
+ Gelatin.Picture.Internal: getTextures :: Monad m => PictureT t v m [t]
+ Gelatin.Picture.Internal: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Gelatin.Picture.Internal.GeometryT a m)
+ Gelatin.Picture.Internal: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Gelatin.Picture.Internal.VerticesT a m)
+ Gelatin.Picture.Internal: instance Control.Monad.Trans.Class.MonadTrans (Gelatin.Picture.Internal.GeometryT a)
+ Gelatin.Picture.Internal: instance Control.Monad.Trans.Class.MonadTrans (Gelatin.Picture.Internal.VerticesT a)
+ Gelatin.Picture.Internal: instance GHC.Base.Functor m => GHC.Base.Functor (Gelatin.Picture.Internal.GeometryT a m)
+ Gelatin.Picture.Internal: instance GHC.Base.Functor m => GHC.Base.Functor (Gelatin.Picture.Internal.VerticesT a m)
+ Gelatin.Picture.Internal: instance GHC.Base.Monad m => GHC.Base.Applicative (Gelatin.Picture.Internal.GeometryT a m)
+ Gelatin.Picture.Internal: instance GHC.Base.Monad m => GHC.Base.Applicative (Gelatin.Picture.Internal.VerticesT a m)
+ Gelatin.Picture.Internal: instance GHC.Base.Monad m => GHC.Base.Monad (Gelatin.Picture.Internal.GeometryT a m)
+ Gelatin.Picture.Internal: instance GHC.Base.Monad m => GHC.Base.Monad (Gelatin.Picture.Internal.VerticesT a m)
+ Gelatin.Picture.Internal: line :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture.Internal: mapGeometry :: (Monad m, Unbox a, Unbox c) => (a -> c) -> GeometryT a m b -> GeometryT c m ()
+ Gelatin.Picture.Internal: mapRawGeometry :: (Unbox a, Unbox b) => (a -> b) -> RawGeometry a -> RawGeometry b
+ Gelatin.Picture.Internal: mapToSpaceVec :: (Monad m, Unbox v, Unbox s) => (v -> s) -> PictureT t v m (Vector s)
+ Gelatin.Picture.Internal: mapVertices :: (Monad m, Unbox a, Unbox c) => (a -> c) -> VerticesT a m b -> VerticesT c m ()
+ Gelatin.Picture.Internal: newtype GeometryT a m b
+ Gelatin.Picture.Internal: newtype VerticesT a m b
+ Gelatin.Picture.Internal: picDataGeometry :: forall texture_aLGU vertex_aLGV vertex_aMl3. Lens (PictureData texture_aLGU vertex_aLGV) (PictureData texture_aLGU vertex_aMl3) (Vector (RawGeometry vertex_aLGV)) (Vector (RawGeometry vertex_aMl3))
+ Gelatin.Picture.Internal: picDataOptions :: forall texture_aLGU vertex_aLGV. Lens' (PictureData texture_aLGU vertex_aLGV) [RenderingOption]
+ Gelatin.Picture.Internal: picDataStroke :: forall texture_aLGU vertex_aLGV. Lens' (PictureData texture_aLGU vertex_aLGV) [StrokeAttr]
+ Gelatin.Picture.Internal: picDataTextures :: forall texture_aLGU vertex_aLGV texture_aMl4. Lens (PictureData texture_aLGU vertex_aLGV) (PictureData texture_aMl4 vertex_aLGV) [texture_aLGU] [texture_aMl4]
+ Gelatin.Picture.Internal: pictureBounds2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float, V2 Float)
+ Gelatin.Picture.Internal: pictureBounds3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m BCube
+ Gelatin.Picture.Internal: pictureCenter2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float)
+ Gelatin.Picture.Internal: pictureCenter3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m (V3 Float)
+ Gelatin.Picture.Internal: pictureOrigin2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float)
+ Gelatin.Picture.Internal: pictureOrigin3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m (V3 Float)
+ Gelatin.Picture.Internal: pictureSize2 :: (Monad m, Unbox v) => (v -> V2 Float) -> PictureT t v m (V2 Float)
+ Gelatin.Picture.Internal: pictureSize3 :: (Monad m, Unbox v) => (v -> V3 Float) -> PictureT t v m (V3 Float)
+ Gelatin.Picture.Internal: runGeometry :: Geometry a -> Vector (RawGeometry a)
+ Gelatin.Picture.Internal: runGeometryT :: Monad m => GeometryT a m b -> m (Vector (RawGeometry a))
+ Gelatin.Picture.Internal: runPicture :: Picture t v a -> (a, PictureData t v)
+ Gelatin.Picture.Internal: runPictureT :: PictureT t v m a -> m (a, PictureData t v)
+ Gelatin.Picture.Internal: runVertices :: Unbox a => Vertices a -> Vector a
+ Gelatin.Picture.Internal: runVerticesT :: (Monad m, Unbox a) => VerticesT a m b -> m (Vector a)
+ Gelatin.Picture.Internal: segment :: (Monad m, Unbox a) => a -> a -> VerticesT a m ()
+ Gelatin.Picture.Internal: setGeometry :: Monad m => GeometryT v m () -> PictureT t v m ()
+ Gelatin.Picture.Internal: setRawGeometry :: Monad m => Vector (RawGeometry v) -> PictureT t v m ()
+ Gelatin.Picture.Internal: setRenderingOptions :: Monad m => [RenderingOption] -> PictureT t v m ()
+ Gelatin.Picture.Internal: setStroke :: Monad m => [StrokeAttr] -> PictureT t v m ()
+ Gelatin.Picture.Internal: setTextures :: Monad m => [t] -> PictureT t v m ()
+ Gelatin.Picture.Internal: snoc3 :: Unbox a => Vector a -> a -> a -> a -> Vector a
+ Gelatin.Picture.Internal: strip :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture.Internal: to :: (Monad m, Unbox a) => a -> VerticesT a m ()
+ Gelatin.Picture.Internal: tri :: (Monad m, Unbox a) => a -> a -> a -> VerticesT a m ()
+ Gelatin.Picture.Internal: triangles :: (Unbox a, Monad m) => VerticesT a m () -> GeometryT a m ()
+ Gelatin.Picture.Internal: type Geometry a = GeometryT a Identity ()
+ Gelatin.Picture.Internal: type Picture t v = PictureT t v Identity
+ Gelatin.Picture.Internal: type PictureT tex vert = StateT (PictureData tex vert)
+ Gelatin.Picture.Internal: type Vertices a = VerticesT a Identity ()
+ Gelatin.Picture.Internal: vertexData :: RawGeometry v -> Vector v
+ Gelatin.Picture.Shapes: arc :: (Unbox a, Epsilon a, RealFloat a, Monad m) => a -> a -> a -> a -> VerticesT (V2 a) m ()
+ Gelatin.Picture.Shapes: corner :: (RealFloat a, Unbox a, Monad m) => a -> a -> VerticesT (V2 a) m ()
+ Gelatin.Picture.Shapes: curve :: (RealFloat a, Unbox a, Monad m) => V2 a -> V2 a -> V2 a -> VerticesT (V2 a) m ()
+ Gelatin.Picture.Shapes: rectangle :: (Unbox a, Monad m) => V2 a -> V2 a -> VerticesT (V2 a) m ()
- Gelatin.Core.Color: aliceBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: aliceBlue :: Fractional a => V4 a
- Gelatin.Core.Color: amethyst :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: amethyst :: Fractional a => V4 a
- Gelatin.Core.Color: antiqueWhite :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: antiqueWhite :: Fractional a => V4 a
- Gelatin.Core.Color: aqua :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: aqua :: Fractional a => V4 a
- Gelatin.Core.Color: aquamarine :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: aquamarine :: Fractional a => V4 a
- Gelatin.Core.Color: azure :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: azure :: Fractional a => V4 a
- Gelatin.Core.Color: beige :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: beige :: Fractional a => V4 a
- Gelatin.Core.Color: bisque :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: bisque :: Fractional a => V4 a
- Gelatin.Core.Color: black :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: black :: Fractional a => V4 a
- Gelatin.Core.Color: blanchedAlmond :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: blanchedAlmond :: Fractional a => V4 a
- Gelatin.Core.Color: blue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: blue :: Fractional a => V4 a
- Gelatin.Core.Color: blueViolet :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: blueViolet :: Fractional a => V4 a
- Gelatin.Core.Color: brown :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: brown :: Fractional a => V4 a
- Gelatin.Core.Color: burlyWood :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: burlyWood :: Fractional a => V4 a
- Gelatin.Core.Color: cadetBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: cadetBlue :: Fractional a => V4 a
- Gelatin.Core.Color: chartreuse :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: chartreuse :: Fractional a => V4 a
- Gelatin.Core.Color: chocolate :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: chocolate :: Fractional a => V4 a
- Gelatin.Core.Color: coral :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: coral :: Fractional a => V4 a
- Gelatin.Core.Color: cornflowerBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: cornflowerBlue :: Fractional a => V4 a
- Gelatin.Core.Color: cornsilk :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: cornsilk :: Fractional a => V4 a
- Gelatin.Core.Color: crimson :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: crimson :: Fractional a => V4 a
- Gelatin.Core.Color: cyan :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: cyan :: Fractional a => V4 a
- Gelatin.Core.Color: darkBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkBlue :: Fractional a => V4 a
- Gelatin.Core.Color: darkCyan :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkCyan :: Fractional a => V4 a
- Gelatin.Core.Color: darkGoldenrod :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkGoldenrod :: Fractional a => V4 a
- Gelatin.Core.Color: darkGray :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkGray :: Fractional a => V4 a
- Gelatin.Core.Color: darkGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkGreen :: Fractional a => V4 a
- Gelatin.Core.Color: darkKhaki :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkKhaki :: Fractional a => V4 a
- Gelatin.Core.Color: darkMagenta :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkMagenta :: Fractional a => V4 a
- Gelatin.Core.Color: darkOliveGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkOliveGreen :: Fractional a => V4 a
- Gelatin.Core.Color: darkOrange :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkOrange :: Fractional a => V4 a
- Gelatin.Core.Color: darkOrchid :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkOrchid :: Fractional a => V4 a
- Gelatin.Core.Color: darkRed :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkRed :: Fractional a => V4 a
- Gelatin.Core.Color: darkSalmon :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkSalmon :: Fractional a => V4 a
- Gelatin.Core.Color: darkSeaGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkSeaGreen :: Fractional a => V4 a
- Gelatin.Core.Color: darkSlateBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkSlateBlue :: Fractional a => V4 a
- Gelatin.Core.Color: darkSlateGray :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkSlateGray :: Fractional a => V4 a
- Gelatin.Core.Color: darkTurquoise :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkTurquoise :: Fractional a => V4 a
- Gelatin.Core.Color: darkViolet :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: darkViolet :: Fractional a => V4 a
- Gelatin.Core.Color: deepPink :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: deepPink :: Fractional a => V4 a
- Gelatin.Core.Color: deepSkyBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: deepSkyBlue :: Fractional a => V4 a
- Gelatin.Core.Color: dimGray :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: dimGray :: Fractional a => V4 a
- Gelatin.Core.Color: dodgerBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: dodgerBlue :: Fractional a => V4 a
- Gelatin.Core.Color: fireBrick :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: fireBrick :: Fractional a => V4 a
- Gelatin.Core.Color: floralWhite :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: floralWhite :: Fractional a => V4 a
- Gelatin.Core.Color: forestGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: forestGreen :: Fractional a => V4 a
- Gelatin.Core.Color: fuchsia :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: fuchsia :: Fractional a => V4 a
- Gelatin.Core.Color: gainsboro :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: gainsboro :: Fractional a => V4 a
- Gelatin.Core.Color: ghostWhite :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: ghostWhite :: Fractional a => V4 a
- Gelatin.Core.Color: gold :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: gold :: Fractional a => V4 a
- Gelatin.Core.Color: goldenrod :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: goldenrod :: Fractional a => V4 a
- Gelatin.Core.Color: gray :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: gray :: Fractional a => V4 a
- Gelatin.Core.Color: green :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: green :: Fractional a => V4 a
- Gelatin.Core.Color: greenYellow :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: greenYellow :: Fractional a => V4 a
- Gelatin.Core.Color: grey :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: grey :: Fractional a => V4 a
- Gelatin.Core.Color: honeydew :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: honeydew :: Fractional a => V4 a
- Gelatin.Core.Color: hotPink :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: hotPink :: Fractional a => V4 a
- Gelatin.Core.Color: indianRed :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: indianRed :: Fractional a => V4 a
- Gelatin.Core.Color: indigo :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: indigo :: Fractional a => V4 a
- Gelatin.Core.Color: ivory :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: ivory :: Fractional a => V4 a
- Gelatin.Core.Color: khaki :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: khaki :: Fractional a => V4 a
- Gelatin.Core.Color: lavender :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lavender :: Fractional a => V4 a
- Gelatin.Core.Color: lavenderBlush :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lavenderBlush :: Fractional a => V4 a
- Gelatin.Core.Color: lawnGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lawnGreen :: Fractional a => V4 a
- Gelatin.Core.Color: lemonChiffon :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lemonChiffon :: Fractional a => V4 a
- Gelatin.Core.Color: lightBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightBlue :: Fractional a => V4 a
- Gelatin.Core.Color: lightCoral :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightCoral :: Fractional a => V4 a
- Gelatin.Core.Color: lightCyan :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightCyan :: Fractional a => V4 a
- Gelatin.Core.Color: lightGoldenrodYellow :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightGoldenrodYellow :: Fractional a => V4 a
- Gelatin.Core.Color: lightGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightGreen :: Fractional a => V4 a
- Gelatin.Core.Color: lightGrey :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightGrey :: Fractional a => V4 a
- Gelatin.Core.Color: lightPink :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightPink :: Fractional a => V4 a
- Gelatin.Core.Color: lightSalmon :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightSalmon :: Fractional a => V4 a
- Gelatin.Core.Color: lightSeaGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightSeaGreen :: Fractional a => V4 a
- Gelatin.Core.Color: lightSkyBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightSkyBlue :: Fractional a => V4 a
- Gelatin.Core.Color: lightSlateGray :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightSlateGray :: Fractional a => V4 a
- Gelatin.Core.Color: lightSteelBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightSteelBlue :: Fractional a => V4 a
- Gelatin.Core.Color: lightYellow :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lightYellow :: Fractional a => V4 a
- Gelatin.Core.Color: lime :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: lime :: Fractional a => V4 a
- Gelatin.Core.Color: limeGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: limeGreen :: Fractional a => V4 a
- Gelatin.Core.Color: linen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: linen :: Fractional a => V4 a
- Gelatin.Core.Color: magenta :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: magenta :: Fractional a => V4 a
- Gelatin.Core.Color: maroon :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: maroon :: Fractional a => V4 a
- Gelatin.Core.Color: mediumAquamarine :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumAquamarine :: Fractional a => V4 a
- Gelatin.Core.Color: mediumBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumBlue :: Fractional a => V4 a
- Gelatin.Core.Color: mediumOrchid :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumOrchid :: Fractional a => V4 a
- Gelatin.Core.Color: mediumPurple :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumPurple :: Fractional a => V4 a
- Gelatin.Core.Color: mediumSeaGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumSeaGreen :: Fractional a => V4 a
- Gelatin.Core.Color: mediumSlateBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumSlateBlue :: Fractional a => V4 a
- Gelatin.Core.Color: mediumSpringGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumSpringGreen :: Fractional a => V4 a
- Gelatin.Core.Color: mediumTurquoise :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumTurquoise :: Fractional a => V4 a
- Gelatin.Core.Color: mediumVioletRed :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mediumVioletRed :: Fractional a => V4 a
- Gelatin.Core.Color: midnightBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: midnightBlue :: Fractional a => V4 a
- Gelatin.Core.Color: mintCream :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mintCream :: Fractional a => V4 a
- Gelatin.Core.Color: mistyRose :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: mistyRose :: Fractional a => V4 a
- Gelatin.Core.Color: moccasin :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: moccasin :: Fractional a => V4 a
- Gelatin.Core.Color: navajoWhite :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: navajoWhite :: Fractional a => V4 a
- Gelatin.Core.Color: navy :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: navy :: Fractional a => V4 a
- Gelatin.Core.Color: oldLace :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: oldLace :: Fractional a => V4 a
- Gelatin.Core.Color: olive :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: olive :: Fractional a => V4 a
- Gelatin.Core.Color: oliveDrab :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: oliveDrab :: Fractional a => V4 a
- Gelatin.Core.Color: orange :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: orange :: Fractional a => V4 a
- Gelatin.Core.Color: orangeRed :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: orangeRed :: Fractional a => V4 a
- Gelatin.Core.Color: orchid :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: orchid :: Fractional a => V4 a
- Gelatin.Core.Color: paleGoldenrod :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: paleGoldenrod :: Fractional a => V4 a
- Gelatin.Core.Color: paleGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: paleGreen :: Fractional a => V4 a
- Gelatin.Core.Color: paleTurquoise :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: paleTurquoise :: Fractional a => V4 a
- Gelatin.Core.Color: paleVioletRed :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: paleVioletRed :: Fractional a => V4 a
- Gelatin.Core.Color: papayaWhip :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: papayaWhip :: Fractional a => V4 a
- Gelatin.Core.Color: peachPuff :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: peachPuff :: Fractional a => V4 a
- Gelatin.Core.Color: peru :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: peru :: Fractional a => V4 a
- Gelatin.Core.Color: pink :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: pink :: Fractional a => V4 a
- Gelatin.Core.Color: plum :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: plum :: Fractional a => V4 a
- Gelatin.Core.Color: powderBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: powderBlue :: Fractional a => V4 a
- Gelatin.Core.Color: purple :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: purple :: Fractional a => V4 a
- Gelatin.Core.Color: red :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: red :: Fractional a => V4 a
- Gelatin.Core.Color: rosyBrown :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: rosyBrown :: Fractional a => V4 a
- Gelatin.Core.Color: royalBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: royalBlue :: Fractional a => V4 a
- Gelatin.Core.Color: saddleBrown :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: saddleBrown :: Fractional a => V4 a
- Gelatin.Core.Color: salmon :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: salmon :: Fractional a => V4 a
- Gelatin.Core.Color: sandyBrown :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: sandyBrown :: Fractional a => V4 a
- Gelatin.Core.Color: seaGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: seaGreen :: Fractional a => V4 a
- Gelatin.Core.Color: seashell :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: seashell :: Fractional a => V4 a
- Gelatin.Core.Color: sienna :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: sienna :: Fractional a => V4 a
- Gelatin.Core.Color: silver :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: silver :: Fractional a => V4 a
- Gelatin.Core.Color: skyBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: skyBlue :: Fractional a => V4 a
- Gelatin.Core.Color: slateBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: slateBlue :: Fractional a => V4 a
- Gelatin.Core.Color: slateGray :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: slateGray :: Fractional a => V4 a
- Gelatin.Core.Color: snow :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: snow :: Fractional a => V4 a
- Gelatin.Core.Color: springGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: springGreen :: Fractional a => V4 a
- Gelatin.Core.Color: steelBlue :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: steelBlue :: Fractional a => V4 a
- Gelatin.Core.Color: tan :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: tan :: Fractional a => V4 a
- Gelatin.Core.Color: teal :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: teal :: Fractional a => V4 a
- Gelatin.Core.Color: thistle :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: thistle :: Fractional a => V4 a
- Gelatin.Core.Color: tomato :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: tomato :: Fractional a => V4 a
- Gelatin.Core.Color: transparent :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: transparent :: Fractional a => V4 a
- Gelatin.Core.Color: turquoise :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: turquoise :: Fractional a => V4 a
- Gelatin.Core.Color: violet :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: violet :: Fractional a => V4 a
- Gelatin.Core.Color: wheat :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: wheat :: Fractional a => V4 a
- Gelatin.Core.Color: white :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: white :: Fractional a => V4 a
- Gelatin.Core.Color: whiteSmoke :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: whiteSmoke :: Fractional a => V4 a
- Gelatin.Core.Color: yellow :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: yellow :: Fractional a => V4 a
- Gelatin.Core.Color: yellowGreen :: (Num a, Fractional a) => V4 a
+ Gelatin.Core.Color: yellowGreen :: Fractional a => V4 a

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2015 Schell Scivally+Copyright (c) 2016 Schell Scivally  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
+ app/Example.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+import           Gelatin+import           Linear++--------------------------------------------------------------------------------+-- Example+--------------------------------------------------------------------------------+picture :: Picture () (V2 Float, V4 Float) ()+picture = setGeometry $ fan $ do+  to (0, red)+  to (V2 100 0, green)+  to (100, blue)+  to (V2 0 100, white)++main :: IO ()+main = putStrLn "picture"
+ docimages/demoteCubic.png view

binary file changed (absent → 23597 bytes)

gelatin.cabal view
@@ -1,124 +1,59 @@--- Initial gelatin-core.cabal generated by cabal init.  For further--- documentation, see http://haskell.org/cabal/users-guide/---- The name of the package. name:                gelatin---- The package version.  See the Haskell package versioning policy (PVP)--- for standards guiding when and how versions should be incremented.--- http://www.haskell.org/haskellwiki/Package_versioning_policy--- PVP summary:      +-+------- breaking API changes---                   | | +----- non-breaking API additions---                   | | | +--- code changes with no API change-version:             0.0.0.3---- A short (one-line) description of the package.-synopsis:            An experimental real time renderer.---- A longer description of the package.-description:         gelatin is a very experimental real time rendering-                     engine for 2d graphics. It is backed by opengl 3.3.---- The license under which the package is released.+version:             0.1.0.0+synopsis:            A graphics description language.+description:         An EDSL for describing pictures and scenes.+homepage:            https://github.com/schell/gelatin license:             MIT---- The file containing the license text. license-file:        LICENSE---- The package author(s). author:              Schell Scivally---- An email address to which users can send suggestions, bug reports, and--- patches.-maintainer:          efsubenovex@gmail.com---- A copyright notice.--- copyright:-+maintainer:          schell@takt.com category:            Graphics- build-type:          Simple---- Extra files to be distributed with the package, such as examples or a--- README.-extra-source-files:    shaders/2d.frag,-                       shaders/2d.vert,-                       shaders/bezier.frag,-                       shaders/bezier.vert,-                       shaders/mask.frag,-                       shaders/mask.vert---- Constraint on the version of Cabal needed to build this package.-cabal-version:       >=1.10+extra-doc-files:     docimages/*.png+stability:           experimental -source-repository head-  type: git-  location: https://github.com/schell/gelatin+cabal-version:       >=1.18  library   ghc-options:         -Wall-  -- Modules exported by the library.-  exposed-modules:     Gelatin.Core.Rendering,-                       Gelatin.Core.Rendering.Font,-                       Gelatin.Core.Rendering.Types,-                       Gelatin.Core.Rendering.Geometrical,-                       Gelatin.Core.Rendering.Polylines,-                       Gelatin.Core.Shader,-                       Gelatin.Core.Color,-                       Gelatin.Core.Triangulation.Common,-                       Gelatin.Core.Triangulation.EarClipping,-                       Gelatin.Core.Triangulation.KET -  -- Modules included in this library but not exported.-  -- other-modules:--  -- LANGUAGE extensions used by modules in this package.-  other-extensions:    OverloadedStrings,-                       FlexibleContexts,-                       GeneralizedNewtypeDeriving,-                       TemplateHaskell+  exposed-modules:     Gelatin+                     , Gelatin.Compiler+                     , Gelatin.Core+                     , Gelatin.Core.Bezier+                     , Gelatin.Core.Bounds+                     , Gelatin.Core.Color+                     --, Gelatin.Core.Font+                     , Gelatin.Core.Polyline+                     , Gelatin.Core.Stroke+                     , Gelatin.Core.Transform+                     , Gelatin.Core.Triangle+                     , Gelatin.Core.Utils+                     , Gelatin.Picture+                     , Gelatin.Picture.Internal+                     , Gelatin.Picture.Shapes -  -- Other library packages from which modules are imported.-  build-depends:       base >=4.7 && < 5,-                       linear >=1.18,-                       gl >=0.7,-                       GLFW-b >= 1.4.7.2,-                       FontyFruity >=0.5,-                       JuicyPixels,-                       time >=1.4,-                       async >=2.0,-                       directory >=1.2,-                       containers >=0.5,-                       vector >=0.10,-                       lens,-                       file-embed >= 0.0.8.2,-                       bytestring+  build-depends:       base                  >=4.8 && <4.11+                     , linear                >=1.20 && <1.21+                     , containers            >=0.5 && <0.6+                     , vector                >=0.12 && <0.13+                     , mtl                   >=2.2 && <2.3+                     , transformers          >=0.4 && <0.6+                     , bytestring            >=0.10 && <0.11+                     , lens                  >=4.14 && <4.16 -  -- Directories containing source files.   hs-source-dirs:      src--  -- Base language which the package is written in.   default-language:    Haskell2010  executable example-  buildable:           True-  ghc-prof-options:    -Wall-  hs-source-dirs:      src-  main-is:             Example.hs-  build-depends:       base >=4.6 && <5.0,-                       gelatin -any,-                       linear >=1.18,-                       gl >=0.7,-                       GLFW-b >= 1.4.7.2,-                       FontyFruity >=0.5,-                       JuicyPixels,-                       time >=1.4,-                       async >=2.0,-                       directory >=1.2,-                       containers >=0.5,-                       vector >=0.10,-                       lens,-                       file-embed >= 0.0.8.2,-                       bytestring+  ghc-options:         -Wall +  build-depends:       base                  >=4.8 && <4.11+                     , gelatin+                     , linear                >=1.20 && <1.21+                     , vector                >=0.12 && <0.13+                     , mtl                   >=2.2 && <2.3++  hs-source-dirs:      app+  main-is:             Example.hs   default-language:    Haskell2010
− shaders/2d.frag
@@ -1,16 +0,0 @@-#version 330 core-in vec4 fcolor;-in vec2 fuv;-out vec4 fragColor;--uniform bool hasUV;-uniform sampler2D sampler;---void main() {-    if (hasUV) {-        fragColor = texture(sampler, fuv.st);-    } else {-        fragColor = fcolor;-    }-}
− shaders/2d.vert
@@ -1,18 +0,0 @@-#version 330 core-layout(location = 0) in vec2 position;-layout(location = 1) in vec4 color;-layout(location = 2) in vec2 uv;--uniform mat4 projection;-uniform mat4 modelview;-uniform bool hasUV;-uniform sampler2D sampler;--out vec4 fcolor;-out vec2 fuv;--void main() {-    fcolor = color;-    fuv = uv;-    gl_Position = projection * modelview * vec4(position.xy, 0.0, 1.0);-}
− shaders/bezier.frag
@@ -1,47 +0,0 @@-// Loop-Blinn curve rendering--#version 330 core-in vec3 fbez;-in vec4 fcolor;-in vec2 fuv;-out vec4 fragColor;--uniform bool hasUV;-uniform sampler2D sampler;--void main() {-    vec2 p = fbez.xy;-    // When cw is true, winding is clockwise and we're drawing outside the-    // curve.-    bool cw = bool(fbez.z);-    // Gradients-    vec2 px = dFdx(p);-    vec2 py = dFdy(p);-    // Chain rule-    float fx = (2*p.x)*px.x - px.y;-    float fy = (2*p.x)*py.x - py.y;-    // Signed distance-    float sd = (p.x*p.x - p.y) / sqrt(fx*fx + fy*fy);-    //Linear alpha-    float alpha = 0.5 - sd;-    alpha = cw ? 1 - alpha : alpha;-    // Find the resulting fragment color-    float a = 0;--    if (alpha > 1) {-        a = 1;-    } else if (alpha < 0) {-        discard;-    } else {-        // We are right on the boundary, interpolate the color intensity.-        a = alpha;-    }--    vec4 color = vec4(0);-    if (hasUV) {-        color = texture(sampler, fuv.st);-    } else {-        color = fcolor;-    }-    fragColor = vec4(color.rgb, color.a * a);-}
− shaders/bezier.vert
@@ -1,22 +0,0 @@-// Loop-Blinn curve rendering--#version 330 core--layout(location = 0) in vec2 position;-layout(location = 1) in vec4 color;-layout(location = 2) in vec2 uv;-layout(location = 3) in vec3 bez;--uniform mat4 projection;-uniform mat4 modelview;--out vec3 fbez;-out vec4 fcolor;-out vec2 fuv;--void main() {-    fbez = bez;-    fuv = uv;-    fcolor = color;-    gl_Position = projection * modelview * vec4(position.xy, 0.0, 1.0);-}
− shaders/mask.frag
@@ -1,13 +0,0 @@-#version 330 core-uniform sampler2D mainTex;-uniform sampler2D maskTex;--in vec2 fuv;--out vec4 fragColor;--void main() {-    vec4 color = texture(mainTex, fuv.st);-    vec4 mask  = texture(maskTex, fuv.st);-    fragColor = vec4(color.rgb, color.a * mask.a);-}
− shaders/mask.vert
@@ -1,15 +0,0 @@-#version 330 core-layout(location = 0) in vec2 position;-layout(location = 2) in vec2 uv;--uniform mat4 projection;-uniform mat4 modelview;-uniform sampler2D mainTex;-uniform sampler2D maskTex;--out vec2 fuv;--void main() {-    fuv = uv;-    gl_Position = projection * modelview * vec4(position.xy, 0.0, 1.0);-}
− src/Example.hs
@@ -1,30 +0,0 @@-module Main where--import System.Environment-import Gelatin.Core.Rendering-import Graphics.UI.GLFW-import Examples.PolylineTest-import Examples.PolylineWinding-import Examples.Masking-import Examples.Text-import Examples.ClipTexture--examples :: [(String, Window -> GeomRenderSource -> BezRenderSource -> IO ())]-examples = [("polylineTest", polylineTest)-           ,("polylineWinding", polylineWinding)-           ,("masking", masking)-           ,("text", text)-           ,("clipTexture", clippingTexture)-           ]--main :: IO ()-main = do-    name:_ <- getArgs-    True   <- initGelatin-    win    <- newWindow 800 600 "Syndeca Mapper" Nothing Nothing-    grs    <- loadGeomRenderSource-    brs    <- loadBezRenderSource--    let Just example = lookup name examples--    example win grs brs
+ src/Gelatin.hs view
@@ -0,0 +1,27 @@+-- |+-- Module:     Gelatin+-- Copyright:  (c) 2017 Schell Scivally+-- License:    MIT+-- Maintainer: Schell Scivally <schell@takt.com>+--+-- [@Core@]+-- Core types and pure functions.+--+-- [@Picture@]+-- Creating pictures.+--+-- [@Compiler@]+-- Shared types for writing backends and compiling pictures.+--+module Gelatin+  ( -- * Re-exports+    module Gelatin.Core+  , module Gelatin.Picture+  , module Gelatin.Compiler+  , module Linear+  ) where++import Gelatin.Core+import Gelatin.Picture+import Gelatin.Compiler+import Linear hiding (rotate)
+ src/Gelatin/Compiler.hs view
@@ -0,0 +1,237 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Gelatin.Compiler where++import qualified Data.Vector as B+import           Data.Vector.Unboxed (Vector)+import           Data.Functor.Identity+import           Data.Foldable (foldl')+import           Linear (V4(..), V2(..), M44, identity, (!*!))+import           Control.Monad.IO.Class++import           Gelatin.Core+import           Gelatin.Picture.Internal+--------------------------------------------------------------------------------+-- Compilation results in a Renderer+--------------------------------------------------------------------------------+data RenderTransform v r s = Spatial (Affine v r)+                           | Special s++extractSpatial :: [RenderTransform v r s] -> [Affine v r]+extractSpatial = concatMap f+  where f (Spatial x) = [x]+        f _ = []++type Renderer v r s = (IO (), [RenderTransform v r s] -> IO ())+--------------------------------------------------------------------------------+-- Renderers can be transformed with many things, but here are some concrete+-- examples.+--------------------------------------------------------------------------------+data Raster = Alpha Float+            | Multiply (V4 Float)+            | ColorReplacement (V4 Float)+            deriving (Show, Eq)++type RenderTransform2 = RenderTransform (V2 Float) Float Raster+type Renderer2        = Renderer        (V2 Float) Float Raster+--------------------------------------------------------------------------------+-- Transformation Helpers+--------------------------------------------------------------------------------+unwrapTransforms :: [RenderTransform2]+                 -> (M44 Float, Float, V4 Float, Maybe (V4 Float))+unwrapTransforms = foldl' f (identity, 1, white, Nothing)+  where f (mv, alph, mlt, rep) (Spatial a) =+          (mv !*! affine2Modelview a, alph, mlt, rep)+        f (mv, alph, mlt, rep) (Special (Alpha a)) =+          (mv, alph * a, mlt, rep)+        f (mv, alph, mlt, rep) (Special (Multiply a)) =+          (mv, alph, mlt * a, rep)+        f (mv, alph, mlt, _) (Special (ColorReplacement a)) =+          (mv, alph, mlt, Just a)+--------------------------------------------------------------------------------+-- Conveniences for creating transformations+--------------------------------------------------------------------------------+move :: Float -> Float -> RenderTransform2+move x y = Spatial $ Translate $ V2 x y++moveV2 :: V2 Float -> RenderTransform2+moveV2 (V2 x y) = move x y++scale :: Float -> Float -> RenderTransform2+scale x y = Spatial $ Scale $ V2 x y++scaleV2 :: V2 Float -> RenderTransform2+scaleV2 (V2 x y) = scale x y++rotate :: Float -> RenderTransform2+rotate = Spatial . Rotate++alpha :: Float -> RenderTransform2+alpha = Special . Alpha++multiply :: Float -> Float -> Float -> Float -> RenderTransform2+multiply r g b a = Special $ Multiply $ V4 r g b a++multiplyV4 :: V4 Float -> RenderTransform2+multiplyV4 (V4 r g b a) = multiply r g b a++redChannelReplacement :: Float -> Float -> Float -> Float -> RenderTransform2+redChannelReplacement r g b a = Special $ ColorReplacement $ V4 r g b a++redChannelReplacementV4 :: V4 Float -> RenderTransform2+redChannelReplacementV4 (V4 r g b a) = redChannelReplacement r g b a+--------------------------------------------------------------------------------+-- Making compiling easier through types+--------------------------------------------------------------------------------+data VertexType = VertexTriangles+                | VertexBeziers+                | VertexStrip+                | VertexFan+                deriving (Show, Eq)++data GeometryCompiler vx v r s = GeometryCompiler+  { compileShapes :: VertexType -> Vector vx -> IO (Renderer v r s)+  , compileLine   :: Stroke     -> Vector vx -> IO (Renderer v r s)+  }++type MakeCompiler z vx v r s = z -> GeometryCompiler vx v r s+--------------------------------------------------------------------------------+-- Specifying the backend+--------------------------------------------------------------------------------+data BackendOps tex event = BackendOps+  { backendOpGetFramebufferSize :: IO (V2 Int)+  , backendOpGetWindowSize      :: IO (V2 Int)+  , backendOpClearWindow        :: IO ()+  , backendOpUpdateWindow       :: IO ()+  , backendOpSetClearColor      :: V4 Float -> IO ()+  , backendOpAllocTexture       :: FilePath -> IO (Maybe (tex, V2 Int))+  , backendOpBindTextures       :: [tex] -> IO () -> IO ()+  , backendOpGetEvents          :: IO [event]+  }+data BackendCompiler vert spatial rot rast = BackendComp+  { backendCompApplyOption :: Renderer spatial rot rast -> RenderingOption+                           -> Renderer spatial rot rast+  , backendCompCompiler    :: GeometryCompiler vert spatial rot rast+  }+data Backend tex event vert spatial rot rast = Backend+  { backendOps      :: BackendOps tex event+  , backendCompiler :: BackendCompiler vert spatial rot rast+  }++compiler :: Backend tex event vert spatial rot rast+         -> GeometryCompiler vert spatial rot rast+compiler = backendCompCompiler . backendCompiler++applyCompilerOption :: Backend tex event vert spatial rot rast+                    -> Renderer spatial rot rast+                    -> RenderingOption+                    -> Renderer spatial rot rast+applyCompilerOption b = backendCompApplyOption $ backendCompiler b++bindTextures :: Backend tex event vert spatial rot rast -> [tex] -> IO () -> IO ()+bindTextures b = backendOpBindTextures $ backendOps b++allocTexture :: Backend tex event vert spatial rot rast -> FilePath+                   -> IO (Maybe (tex, V2 Int))+allocTexture b = backendOpAllocTexture $ backendOps b++clearWindow :: Backend tex event vert spatial rot rast -> IO ()+clearWindow = backendOpClearWindow . backendOps++updateWindow :: Backend tex event vert spatial rot rast -> IO ()+updateWindow = backendOpUpdateWindow . backendOps++getEvents :: Backend tex event vert spatial rot rast -> IO [event]+getEvents = backendOpGetEvents . backendOps+--------------------------------------------------------------------------------+-- Compiling Concrete Picture Types+--------------------------------------------------------------------------------+compilePictureT :: MonadIO m+                => Backend tex event vert spatial rot rast+                -> PictureT tex vert m a+                -> m (a, Renderer spatial rot rast)+compilePictureT b pic = do+  (a, dat) <- runPictureT pic+  glr      <- compilePictureData b dat+  return (a, glr)++compilePicture :: MonadIO m+               => Backend tex event vert spatial rot rast+               -> Picture tex vert a+               -> m (a, Renderer spatial rot rast)+compilePicture b pic = do+  let (a, dat) = runIdentity $ runPictureT pic+  glr <- compilePictureData b dat+  return (a, glr)++--extractTransformData :: PictureData t (V2 Float) Float v -> [RenderTransform]+--extractTransformData PictureData{..} =+--  let afs = map Spatial _picDataAffine+--      ts  = Alpha _picDataAlpha : Multiply _picDataMultiply : afs+--  in case _picDataReplaceColor of+--       Nothing -> ts+--       Just c  -> ColorReplacement c : ts+--+compileGeometry :: GeometryCompiler vx v r s -> [StrokeAttr] -> RawGeometry vx+                -> IO (Renderer v r s)+compileGeometry GeometryCompiler{..} _ (RawTriangles v) =+  compileShapes VertexTriangles v+compileGeometry GeometryCompiler{..} _ (RawBeziers v) =+  compileShapes VertexBeziers v+compileGeometry GeometryCompiler{..} _ (RawTriangleStrip v) =+  compileShapes VertexStrip v+compileGeometry GeometryCompiler{..} _ (RawTriangleFan v) =+  compileShapes VertexFan v+compileGeometry GeometryCompiler{..} ss (RawLine v) =+  compileLine (strokeWith ss) v++compilePictureData :: MonadIO m+                   => Backend tex event vert spatial rot rast+                   -> PictureData tex vert+                   -> m (Renderer spatial rot rast)+compilePictureData b PictureData{..} = do+  let compile = liftIO . compileGeometry (compiler b) _picDataStroke+  glrs <- B.mapM compile _picDataGeometry+  let render rs = bindTextures b _picDataTextures $ mapM_ (($ rs) . snd) glrs+      clean = mapM_ fst glrs+      glr   = foldl (applyCompilerOption b) (clean, render) _picDataOptions+  return glr++--compileColorPictureData :: Rez -> ColorPictureData -> IO Renderer+--compileColorPictureData = compilePictureData rgbaCompiler+--+--compileTexturePictureData :: Rez -> TexturePictureData -> IO Renderer+--compileTexturePictureData = compilePictureData uvCompiler+----------------------------------------------------------------------------------+---- Top level compilation functions+----------------------------------------------------------------------------------+--compileColorPictureT :: MonadIO m => Rez -> ColorPictureT m a -> m (a, Renderer)+--compileColorPictureT rz pic = do+--  (a, dat) <- runPictureT pic+--  glr <- liftIO $ compileColorPictureData rz dat+--  return (a,glr)+--+--compileTexturePictureT :: MonadIO m => Rez -> TexturePictureT m a -> m (a, Renderer)+--compileTexturePictureT rz pic = do+--  (a, dat) <- runPictureT pic+--  glr <- liftIO $ compileTexturePictureData rz dat+--  return (a,glr)+--+--compileColorPicture :: MonadIO m => Rez -> ColorPicture a -> m (a, Renderer)+--compileColorPicture rz pic = do+--  let (a, dat) = runPicture pic+--  glr <- liftIO $ compileColorPictureData rz dat+--  return (a,glr)+--+--compileTexturePicture :: MonadIO m => Rez -> TexturePicture a -> m (a, Renderer)+--compileTexturePicture rz pic = do+--  let (a, dat) = runPicture pic+--  glr <- liftIO $ compileTexturePictureData rz dat+--  return (a,glr)+--------------------------------------------------------------------------------+-- Specifying a proper backend.+--------------------------------------------------------------------------------+
+ src/Gelatin/Core.hs view
@@ -0,0 +1,46 @@+-- | In this module you'll find the types and functions used throughout gelatin.+--+-- [@Bezier@]+-- Inner and outer beziers.+--+-- [@Bounds@]+-- Working with bounding boxes.+--+-- [@Color@]+-- All the nifty named css colors.+--+-- [@Polyline@]+-- Creating smooth, anti-aliased lines with end caps.+--+-- [@Stroke@]+-- Helpers for stroking polylines.+--+-- [@Transform@]+-- Affine transformations (and more).+--+-- [@Triangle@]+-- Most likely not used - contains triangles.+--+-- [@Utils@]+-- Various utilities.+module Gelatin.Core (+    module Gelatin.Core.Bezier+  , module Gelatin.Core.Bounds+  , module Gelatin.Core.Color+--  , module Gelatin.Core.Font+  , module Gelatin.Core.Polyline+  , module Gelatin.Core.Utils+  , module Gelatin.Core.Stroke+  , module Gelatin.Core.Transform+  , module Gelatin.Core.Triangle+) where++import Gelatin.Core.Bezier+import Gelatin.Core.Bounds+import Gelatin.Core.Color+--import Gelatin.Core.Font+import Gelatin.Core.Polyline+import Gelatin.Core.Utils+import Gelatin.Core.Stroke+import Gelatin.Core.Transform+import Gelatin.Core.Triangle
+ src/Gelatin/Core/Bezier.hs view
@@ -0,0 +1,356 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- | Here is a simple bezier algebra.+-- To better server drawing beziers the 'Bezier' type's first+-- record is a boolean representing its fill direction (inner or outer).+module Gelatin.Core.Bezier (+  -- * Types+  Bezier,+  QuadraticBezier,+  CubicBezier,+  -- * Smart Constructors+  bezier,+  bez3,+  bez4,+  -- * Special helpers+  fmapBezier,+  fmapQuadraticBezier,+  fmapCubicBezier,+  transformBezier,+  transformQuadraticBezier,+  transformCubicBezier,+  triangleArea,+  -- * Conversion+  bezToBez3,+  bez3ToBez,+  bez3ToBezInner,+  bez3ToBezOuter,+  bez4ToBez,+  bez4ToBezInner,+  bez4ToBezOuter,+  bez4sToPath,+  flipBez4,+  demoteCubic,+  -- * Subdivision+  deCasteljau,+  subdivideAdaptive,+  subdivideAdaptive3,+  subdivideAdaptive4,+  cleanSeqDupes,+  -- * Shapes+  arcBez4,+  arcBez3,+  ellipseBez4,+  ellipseBez3,+  cornerBez4,+  cornerBez3+) where++import           Gelatin.Core.Transform+import           Linear+import qualified Data.Vector.Unboxed as V+import           Data.Vector.Unboxed (Vector, Unbox)++-- | A bezier that fills internally or externally.+type Bezier a = (Bool, a, a, a)++-- | A simple quadratic bezier with no explicit fill direction.+type QuadraticBezier a = (a, a, a)++-- | A simple cubic bezier with no explicit fill direction.+type CubicBezier a = (a, a, a, a)++fmapBezier :: (a -> b) -> Bezier a -> Bezier b+fmapBezier f (o, a, b, c) = (o, f a, f b, f c)++fmapQuadraticBezier :: (a -> b) -> QuadraticBezier a -> QuadraticBezier b+fmapQuadraticBezier f (a, b, c) = (f a, f b, f c)++fmapCubicBezier :: (a -> b) -> CubicBezier a -> CubicBezier b+fmapCubicBezier f (a, b, c, d) = (f a, f b, f c, f d)++transformBezier :: Num a => M44 a -> Bezier (V2 a) -> Bezier (V2 a)+transformBezier = fmapBezier . transformV2++transformQuadraticBezier :: Num a => M44 a -> QuadraticBezier (V2 a)+                         -> QuadraticBezier (V2 a)+transformQuadraticBezier = fmapQuadraticBezier . transformV2++transformCubicBezier :: Num a => M44 a -> CubicBezier (V2 a)+                     -> CubicBezier (V2 a)+transformCubicBezier = fmapCubicBezier . transformV2++-- | Create a bezier primitive. The area of the triangle formed by the+-- bezier's three points will be used to determine the orientation.+bezier :: (Ord a, Fractional a) => V2 a -> V2 a -> V2 a -> Bezier (V2 a)+bezier a b c = (triangleArea a b c > 0, a, b, c)++triangleArea :: Num a => V2 a -> V2 a -> V2 a -> a+triangleArea (V2 x2 y2) (V2 x0 y0) (V2 x1 y1) =+        (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)++--bezToPath :: (RealFloat a, Unbox a) => Bezier (V2 a) -> Path (V2 a)+--bezToPath = Path . subdivideAdaptive 100 0 . bezToBez3++-- | Create a quadratic bezier. This is an alias of 'QuadraticBezier'.+bez3 :: V2 a -> V2 a -> V2 a -> QuadraticBezier (V2 a)+bez3 = (,,)++-- | Convert a Bezier to a QuadraticBezier.+bezToBez3 :: Bezier a -> QuadraticBezier a+bezToBez3 (_,a,b,c) = (a,b,c)++-- | Create a cubic bezier. This is an alias of 'CubicBezier'.+bez4 :: V2 a -> V2 a -> V2 a -> V2 a -> CubicBezier (V2 a)+bez4 = (,,,)++flipBez4 :: CubicBezier a -> CubicBezier a+flipBez4 (a,b,c,d) = (d,c,b,a)++-- | Convert a quadratic bezier into a bezier primitive and derives the winding+-- (which determines drawing an inner or outer bez) from the order of control+-- points.+bez3ToBez :: (Ord a, Fractional a, Unbox a)+          => QuadraticBezier (V2 a) -> Bezier (V2 a)+bez3ToBez (a,b,c) = bezier a b c++-- | Convert a quadratic bezier into a bezier primitive that fills outer.+bez3ToBezOuter :: (Ord a, Fractional a, Unbox a)+               => QuadraticBezier (V2 a) -> Bezier (V2 a)+bez3ToBezOuter qbz =+    case bez3ToBez qbz of+        z@(True,_,_,_) -> z+        (_,a,b,c) -> bezier c b a++-- | Convert a quadratic bezier into a bezier primitive that fills inner.+bez3ToBezInner :: (Ord a, Fractional a, Unbox a)+               => QuadraticBezier (V2 a) -> Bezier (V2 a)+bez3ToBezInner qbz =+    case bez3ToBez qbz of+        (True,a,b,c) -> bezier c b a+        b -> b++-- | Convert a cubic bezier into a list of drawable bezier primitives.+bez4ToBez :: (Ord a, Fractional a, Unbox a)+          => CubicBezier (V2 a) -> Vector (Bezier (V2 a))+bez4ToBez = V.map bez3ToBez . demoteCubic++-- | Convert a cubic bezier into a list of drawable bezier primitives that+-- fill the inner bezier.+bez4ToBezInner :: (Ord a, Fractional a, Unbox a)+               => CubicBezier (V2 a) -> Vector (Bezier (V2 a))+bez4ToBezInner = V.map bez3ToBezInner . demoteCubic++-- | Convert a cubic bezier into a list of drawable bezier primitives that+-- fill the inner bezier.+bez4ToBezOuter :: (Ord a, Fractional a, Unbox a)+               => CubicBezier (V2 a) -> Vector (Bezier (V2 a))+bez4ToBezOuter = V.map bez3ToBezOuter . demoteCubic++-- | Convert a list of cubic beziers into a smooth path.+bez4sToPath :: (RealFloat a, Unbox a)+            => a -> a -> Vector (CubicBezier (V2 a)) -> Vector (V2 a)+bez4sToPath mScale mAngle =+  cleanSeqDupes . V.concatMap (subdivideAdaptive4 mScale mAngle)++-- | Compute the point at `t` along an N-bezier curve.+deCasteljau :: (Additive f, R1 f, R2 f, Num a) => a -> [f a] -> f a+deCasteljau _ [b] = b+deCasteljau t coefs = deCasteljau t reduced+  where reduced = zipWith (flip (lerp t)) coefs (Prelude.tail coefs)++curveCollinearityEpsilon :: Double+curveCollinearityEpsilon = 1e-30++curveAngleToleranceEpsilon :: Double+curveAngleToleranceEpsilon = 0.01++curveRecursionLimit :: Int+curveRecursionLimit = 32++-- | Approximate a cubic bezier with a list of four quadratic beziers.+--+-- <<docimages/demoteCubic.png>>+demoteCubic :: (Fractional a, Unbox a)+            => CubicBezier (V2 a) -> Vector (QuadraticBezier (V2 a))+demoteCubic (a,b,c,d) = V.fromList [q1,q2,q3,q4]+    where mid = lerp 0.5+          m1 = mid a b+          m2 = mid b c+          m3 = mid c d+          m1m2 = mid m1 m2+          m2m3 = mid m2 m3+          mam1 = mid a m1+          h1 = mid mam1 m1+          p2 = mid m1m2 m2m3+          m1m2p2 = mid m1m2 p2+          h2 = mid m1m2 m1m2p2+          mp2m2m3 = mid p2 m2m3+          h3 = mid mp2m2m3 m2m3+          mdm3 = mid d m3+          h4 = mid mdm3 m3+          p1 = mid h1 h2+          --p2 = mid h2 h3+          p3 = mid h3 h4+          q1 = bez3 a h1 p1+          q2 = bez3 p1 h2 p2+          q3 = bez3 p2 h3 p3+          q4 = bez3 p3 h4 d++-- | Adaptively subdivide the quadratic bezier into a series of points (line+-- segments).+-- i.e. Generate more points along the part of the curve with greater curvature.+-- @see http://www.antigrain.com/research/adaptive_bezier/index.html+-- and http://www.antigrain.com/__code/src/agg_curves.cpp.html+subdivideAdaptive,subdivideAdaptive3 :: (RealFloat a, Unbox a)+                                     => a -> a -> QuadraticBezier (V2 a)+                                     -> Vector (V2 a)+subdivideAdaptive3 = subdivideAdaptive+subdivideAdaptive mScale mAngle (va,vb,vc) =+    let mDistanceToleranceSquare = (0.5 / mScale) ** 2+        vs = subdivide mDistanceToleranceSquare mAngle 0 va vb vc+    in va `V.cons` vs V.++ V.singleton vc++-- | Adaptively subdivide the cubic bezier into a series of points (line+-- segments).+subdivideAdaptive4 :: (RealFloat a, Unbox a)+                   => a -> a -> CubicBezier (V2 a) -> Vector (V2 a)+subdivideAdaptive4 s a = cleanSeqDupes . V.concatMap (subdivideAdaptive s a) . demoteCubic++-- | Removes sequential duplicates from a vector.+cleanSeqDupes :: (Eq a, Unbox a) => Vector a -> Vector a+cleanSeqDupes vs+  | V.length vs > 1 = vs1 `V.snoc` V.last vs+  | otherwise = vs+  where vs1 = V.map fst $ V.filter (uncurry (/=)) $ V.zip vs (V.drop 1 vs)++subdivide :: (RealFloat a, Unbox a)+          => a -> a -> Int -> V2 a -> V2 a -> V2 a -> Vector (V2 a)+subdivide mDistanceToleranceSquare mAngleTolerance level+          v1@(V2 x1 y1) v2@(V2 x2 y2) v3@(V2 x3 y3)+    | level > curveRecursionLimit = V.empty+    | otherwise =+            -- calculate the midpoints of the line segments+        let v12 = (v1 + v2) / 2+            v23 = (v2 + v3) / 2+            v123= (v12 + v23) / 2+            V2 dx dy = v3 - v1+            d = abs $ (x2 - x3) * dy - (y2 - y3) * dx+            subdivideFurther = subdivide mDistanceToleranceSquare+                                         mAngleTolerance+                                         (level + 1)+                                         v1 v12 v123+                               V.+++                               subdivide mDistanceToleranceSquare+                                         mAngleTolerance+                                         (level + 1)+                                         v123 v23 v3+        in if d > realToFrac curveCollinearityEpsilon+           then -- test regular case+               if (d * d) <= (mDistanceToleranceSquare * (dx*dx + dy*dy))+               then -- if the curvature is within our distance tolerance then+                    -- we're done subdividing+                    if mAngleTolerance < realToFrac curveAngleToleranceEpsilon+                    then V.singleton v123+                    else -- test angle and cusp condition+                         let preDA = abs (atan2 (y3 - y2) (x3 - x2) -+                                     atan2 (y2 - y1) (x2 - x1))+                             da = if preDA >= pi then 2*pi - preDA else preDA+                         in if da < mAngleTolerance+                            then V.singleton v123+                            else subdivideFurther+               else subdivideFurther+           else -- test collinear case+                let da = dx*dx + dy*dy+                    f a b = if quadrance (a - b) < mDistanceToleranceSquare+                            then V.singleton v2+                            else subdivideFurther+                in if da == 0+                   then f v1 v2+                   else let d' = ((x2 - x1) * dx + (y2 - y1) * dy) / da+                        in if d' > 0 && d' < 1+                           then -- this is the simple collinear case, 1-2-3+                                V.empty+                           else f v2 $ if d' <= 0+                                then v1+                                else if d' >= 1+                                     then v3+                                     else V2 (x1 + d'*dx) (y1 + d'*dy)+--------------------------------------------------------------------------------+-- Shapes with beziers+--------------------------------------------------------------------------------+kappa :: Fractional a => a+kappa = 0.5522847498307936++cornerBez4 :: RealFloat a => a -> a -> CubicBezier (V2 a)+cornerBez4 xr yr = bez4 (V2 0 yr) (V2 0 y) (V2 x 0) (V2 xr 0)+    where x = xr * kappa+          y = yr * kappa++cornerBez3 :: (RealFloat a, Unbox a)+           => a -> a -> Vector (QuadraticBezier (V2 a))+cornerBez3 xr yr = demoteCubic $ cornerBez4 xr yr++-- | Generate a cubic Bezier representing an arc on the unit circle of total+-- angle `size` radians, beginning `start` radians above the x-axis. Up to four+-- of these curves are combined to make a full arc.+-- See www.joecridge.me/bezier.pdf for an explanation of the method.+acuteArc :: RealFloat a => a -> a -> CubicBezier (V2 a)+acuteArc start size = bez4 a b c d+    where [a,b,c,d] = [V2 ax ay, V2 bx by, V2 cx cy, V2 dx dy]+          ax = cos start+          ay = sin start+          bx = lambda * cosPhi + mu * sinPhi+          by = lambda * sinPhi - mu * cosPhi+          cx = lambda * cosPhi - mu * sinPhi+          cy = lambda * sinPhi + mu * cosPhi+          dx = cos (start + size)+          dy = sin (start + size)+          alpha = size / 2+          cosAlpha = cos alpha+          sinAlpha = sin alpha+          cotAlpha = 1 / tan alpha+          phi = start + alpha+          cosPhi = cos phi+          sinPhi = sin phi+          lambda = (4 - cosAlpha) / 3+          mu = sinAlpha + (cosAlpha - lambda) * cotAlpha++curveEpsilon :: Fractional a => a+curveEpsilon = 0.00001++-- | Create a list of cubic beziers representing an arc along an ellipse with+-- width `w`, height `h` and total angle `stop - start` radians, beginning+-- `start` radians above the x-axis.+arcBez4,arc' :: (Epsilon a, RealFloat a)+             => a -> a -> a -> a -> [CubicBezier (V2 a)]+arcBez4 w h start stop = if stop - start >= 2*pi+                     then close $ arc' w h start (start + 2*pi)+                     else arc' w h start stop+        -- This is a full arc so make sure the first and last points are equal+  where close [c1@(d,_,_,_) ,c2,c3,(a,b,c,_)] =+            [c1,c2,c3,(a,b,c,d)]+        close cs = cs++arc' w h start stop+    | (stop - start) > curveEpsilon = a : arcBez4 w h (start + arcToDraw) stop+    | otherwise = []+        where arcToDraw = min (stop - start) (pi/2)+              mv = affine2Modelview $ Scale (realToFrac <$> V2 w h)+              a = transformCubicBezier mv $ acuteArc start arcToDraw++arcBez3 :: (Epsilon a, RealFloat a, Unbox a)+        => a -> a -> a -> a -> Vector (QuadraticBezier (V2 a))+arcBez3 w h start stop = V.concat $ map demoteCubic $ arcBez4 w h start stop++-- | Create a list of cubic beziers that represent an entire closed+-- ellipse.+ellipseBez4 :: (Epsilon a, RealFloat a) => a -> a -> [CubicBezier (V2 a)]+ellipseBez4 xr yr = arcBez4 xr yr 0 (2*pi)++ellipseBez3 :: (Epsilon a, RealFloat a, Unbox a)+            => a -> a -> Vector (QuadraticBezier (V2 a))+ellipseBez3 xr yr = V.concat $ map demoteCubic $ ellipseBez4 xr yr
+ src/Gelatin/Core/Bounds.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies          #-}+module Gelatin.Core.Bounds where++import           Control.Arrow          (Arrow, first, second, (>>>))+import           Data.Vector.Unboxed    (Unbox, Vector)+import qualified Data.Vector.Unboxed    as V+import           Gelatin.Core.Transform+import           Linear++type BBox = (V2 Float, V2 Float)++type BCube = (V3 Float, V3 Float)++--------------------------------------------------------------------------------+-- 3d+--------------------------------------------------------------------------------+boundingCube :: (Unbox a, Real a) => Vector (V3 a) -> BCube+boundingCube vs+  | V.null vs = (0,0)+  | otherwise = V.foldl' f (br,tl) vs+  where mn a = min a . realToFrac+        mx a = max a . realToFrac+        f (a, b) c = (mn <$> a <*> c, mx <$> b <*> c)+        inf = 1/0+        ninf = (-1)/0+        tl = V3 ninf ninf ninf+        br = V3 inf inf inf++listToCube :: [V3 Float] -> BCube+listToCube = boundingCube . V.fromList++foldIntoCube :: Vector BCube -> BCube+foldIntoCube = boundingCube . uncurry (V.++) . V.unzip++pointInCube :: V2 Float -> BBox -> Bool+pointInCube (V2 px py) (V2 minx miny, V2 maxx maxy) =+  (px >= minx && px <= maxx) && (py >= miny && py <= maxy)++applyTfrmToCube :: M44 Float -> BBox -> BBox+applyTfrmToCube t (tl,br) = listToBox [transformV2 t tl, transformV2 t br]+--------------------------------------------------------------------------------+-- 2d+--------------------------------------------------------------------------------+both :: Arrow a => a d c -> a (d, d) (c, c)+both f = first f >>> second f++boundingBox :: (Unbox a, Real a) => Vector (V2 a) -> BBox+boundingBox = second demoteV3 . first demoteV3 . boundingCube . V.map promoteV2++listToBox :: [V2 Float] -> BBox+listToBox = boundingBox . V.fromList++foldIntoBox :: Vector BBox -> BBox+foldIntoBox = boundingBox . uncurry (V.++) . V.unzip++pointInBox :: V2 Float -> BBox -> Bool+pointInBox (V2 px py) (V2 minx miny, V2 maxx maxy) =+  (px >= minx && px <= maxx) && (py >= miny && py <= maxy)++applyTfrmToBox :: M44 Float -> BBox -> BBox+applyTfrmToBox t (tl,br) = listToBox [transformV2 t tl, transformV2 t br]
src/Gelatin/Core/Color.hs view
@@ -1,446 +1,447 @@+-- | CSS style colors! Also includes 'withAlpha' and 'fromHex', for+-- convenience. module Gelatin.Core.Color where -import Linear-import Data.Bits-import Gelatin.Core.Rendering.Types (Fill(..))+import           Data.Bits+import           Linear -solid :: V4 Float -> Fill-solid = FillColor . const+type Color = V4 Float -maroon :: (Num a, Fractional a) => V4 a+maroon :: Fractional a => V4 a maroon = V4 (128/255) (0/255) (0/255) 1 -red :: (Num a, Fractional a) => V4 a+red :: Fractional a => V4 a red = V4 (255/255) (0/255) (0/255) 1 -orange :: (Num a, Fractional a) => V4 a+orange :: Fractional a => V4 a orange = V4 (255/255) (165/255) (0/255) 1 -yellow :: (Num a, Fractional a) => V4 a+yellow,canary :: Fractional a => V4 a yellow = V4 (255/255) (255/255) (0/255) 1+canary = yellow -olive :: (Num a, Fractional a) => V4 a+olive :: Fractional a => V4 a olive = V4 (128/255) (128/255) (0/255) 1 -green :: (Num a, Fractional a) => V4 a+green :: Fractional a => V4 a green = V4 0 (128/255) (0/255) 1 -purple :: (Num a, Fractional a) => V4 a+purple :: Fractional a => V4 a purple = V4 (128/255) (0/255) (128/255) 1 -fuchsia :: (Num a, Fractional a) => V4 a+fuchsia :: Fractional a => V4 a fuchsia = V4 (255/255) (0/255) (255/255) 1 -lime :: (Num a, Fractional a) => V4 a+lime :: Fractional a => V4 a lime = V4 0 (255/255) (0/255) 1 -teal :: (Num a, Fractional a) => V4 a+teal :: Fractional a => V4 a teal = V4 0 (128/255) (128/255) 1 -aqua :: (Num a, Fractional a) => V4 a+aqua :: Fractional a => V4 a aqua = V4 0 (255/255) (255/255) 1 -blue :: (Num a, Fractional a) => V4 a+blue :: Fractional a => V4 a blue = V4 0 (0/255) (255/255) 1 -navy :: (Num a, Fractional a) => V4 a+navy :: Fractional a => V4 a navy = V4 0 (0/255) (128/255) 1 -black :: (Num a, Fractional a) => V4 a+black :: Fractional a => V4 a black = V4 0 (0/255) (0/255) 1 -gray :: (Num a, Fractional a) => V4 a+gray :: Fractional a => V4 a gray = V4 (128/255) (128/255) (128/255) 1 -grey :: (Num a, Fractional a) => V4 a+grey :: Fractional a => V4 a grey = gray -silver :: (Num a, Fractional a) => V4 a+silver :: Fractional a => V4 a silver = V4 (192/255) (192/255) (192/255) 1 -white :: (Num a, Fractional a) => V4 a+white :: Fractional a => V4 a white = V4 (255/255) (255/255) (255/255) 1 -indianRed :: (Num a, Fractional a) => V4 a+indianRed :: Fractional a => V4 a indianRed = V4 (205/255) (92/255) (92/255) 1 -lightCoral :: (Num a, Fractional a) => V4 a+lightCoral :: Fractional a => V4 a lightCoral = V4 (240/255) (128/255) (128/255) 1 -salmon :: (Num a, Fractional a) => V4 a+salmon :: Fractional a => V4 a salmon = V4 (250/255) (128/255) (114/255) 1 -darkSalmon :: (Num a, Fractional a) => V4 a+darkSalmon :: Fractional a => V4 a darkSalmon = V4 (233/255) (150/255) (122/255) 1 -lightSalmon :: (Num a, Fractional a) => V4 a+lightSalmon :: Fractional a => V4 a lightSalmon = V4 (255/255) (160/255) (122/255) 1 -crimson :: (Num a, Fractional a) => V4 a+crimson :: Fractional a => V4 a crimson = V4 (220/255) (20/255) (60/255) 1 -fireBrick :: (Num a, Fractional a) => V4 a+fireBrick :: Fractional a => V4 a fireBrick = V4 (178/255) (34/255) (34/255) 1 -darkRed :: (Num a, Fractional a) => V4 a+darkRed :: Fractional a => V4 a darkRed = V4 (139/255) (0/255) (0/255) 1 -pink :: (Num a, Fractional a) => V4 a+pink :: Fractional a => V4 a pink = V4 (255/255) (192/255) (203/255) 1 -lightPink :: (Num a, Fractional a) => V4 a+lightPink :: Fractional a => V4 a lightPink = V4 (255/255) (182/255) (193/255) 1 -hotPink :: (Num a, Fractional a) => V4 a+hotPink :: Fractional a => V4 a hotPink = V4 (255/255) (105/255) (180/255) 1 -deepPink :: (Num a, Fractional a) => V4 a+deepPink :: Fractional a => V4 a deepPink = V4 (255/255) (20/255) (147/255) 1 -mediumVioletRed :: (Num a, Fractional a) => V4 a+mediumVioletRed :: Fractional a => V4 a mediumVioletRed = V4 (199/255) (21/255) (133/255) 1 -paleVioletRed :: (Num a, Fractional a) => V4 a+paleVioletRed :: Fractional a => V4 a paleVioletRed = V4 (219/255) (112/255) (147/255) 1 -coral :: (Num a, Fractional a) => V4 a+coral :: Fractional a => V4 a coral = V4 (255/255) (127/255) (80/255) 1 -tomato :: (Num a, Fractional a) => V4 a+tomato :: Fractional a => V4 a tomato = V4 (255/255) (99/255) (71/255) 1 -orangeRed :: (Num a, Fractional a) => V4 a+orangeRed :: Fractional a => V4 a orangeRed = V4 (255/255) (69/255) (0/255) 1 -darkOrange :: (Num a, Fractional a) => V4 a+darkOrange :: Fractional a => V4 a darkOrange = V4 (255/255) (140/255) (0/255) 1 -gold :: (Num a, Fractional a) => V4 a+gold :: Fractional a => V4 a gold = V4 (255/255) (215/255) (0/255) 1 -lightYellow :: (Num a, Fractional a) => V4 a+lightYellow :: Fractional a => V4 a lightYellow = V4 (255/255) (255/255) (224/255) 1 -lemonChiffon :: (Num a, Fractional a) => V4 a+lemonChiffon :: Fractional a => V4 a lemonChiffon = V4 (255/255) (250/255) (205/255) 1 -lightGoldenrodYellow :: (Num a, Fractional a) => V4 a+lightGoldenrodYellow :: Fractional a => V4 a lightGoldenrodYellow = V4 (250/255) (250/255) (210/255) 1 -papayaWhip :: (Num a, Fractional a) => V4 a+papayaWhip :: Fractional a => V4 a papayaWhip = V4 (255/255) (239/255) (213/255) 1 -moccasin :: (Num a, Fractional a) => V4 a+moccasin :: Fractional a => V4 a moccasin = V4 (255/255) (228/255) (181/255) 1 -peachPuff :: (Num a, Fractional a) => V4 a+peachPuff :: Fractional a => V4 a peachPuff = V4 (255/255) (218/255) (185/255) 1 -paleGoldenrod :: (Num a, Fractional a) => V4 a+paleGoldenrod :: Fractional a => V4 a paleGoldenrod = V4 (238/255) (232/255) (170/255) 1 -khaki :: (Num a, Fractional a) => V4 a+khaki :: Fractional a => V4 a khaki = V4 (240/255) (230/255) (140/255) 1 -darkKhaki :: (Num a, Fractional a) => V4 a+darkKhaki :: Fractional a => V4 a darkKhaki = V4 (189/255) (183/255) (107/255) 1 -lavender :: (Num a, Fractional a) => V4 a+lavender :: Fractional a => V4 a lavender = V4 (230/255) (230/255) (250/255) 1 -thistle :: (Num a, Fractional a) => V4 a+thistle :: Fractional a => V4 a thistle = V4 (216/255) (191/255) (216/255) 1 -plum :: (Num a, Fractional a) => V4 a+plum :: Fractional a => V4 a plum = V4 (221/255) (160/255) (221/255) 1 -violet :: (Num a, Fractional a) => V4 a+violet :: Fractional a => V4 a violet = V4 (238/255) (130/255) (238/255) 1 -orchid :: (Num a, Fractional a) => V4 a+orchid :: Fractional a => V4 a orchid = V4 (218/255) (112/255) (214/255) 1 -magenta :: (Num a, Fractional a) => V4 a+magenta :: Fractional a => V4 a magenta = V4 (255/255) (0/255) (255/255) 1 -mediumOrchid :: (Num a, Fractional a) => V4 a+mediumOrchid :: Fractional a => V4 a mediumOrchid = V4 (186/255) (85/255) (211/255) 1 -mediumPurple :: (Num a, Fractional a) => V4 a+mediumPurple :: Fractional a => V4 a mediumPurple = V4 (147/255) (112/255) (219/255) 1 -amethyst :: (Num a, Fractional a) => V4 a+amethyst :: Fractional a => V4 a amethyst = V4 (153/255) (102/255) (204/255) 1 -blueViolet :: (Num a, Fractional a) => V4 a+blueViolet :: Fractional a => V4 a blueViolet = V4 (138/255) (43/255) (226/255) 1 -darkViolet :: (Num a, Fractional a) => V4 a+darkViolet :: Fractional a => V4 a darkViolet = V4 (148/255) (0/255) (211/255) 1 -darkOrchid :: (Num a, Fractional a) => V4 a+darkOrchid :: Fractional a => V4 a darkOrchid = V4 (153/255) (50/255) (204/255) 1 -darkMagenta :: (Num a, Fractional a) => V4 a+darkMagenta :: Fractional a => V4 a darkMagenta = V4 (139/255) (0/255) (139/255) 1 -indigo :: (Num a, Fractional a) => V4 a+indigo :: Fractional a => V4 a indigo = V4 (75/255) (0/255) (130/255) 1 -slateBlue :: (Num a, Fractional a) => V4 a+slateBlue :: Fractional a => V4 a slateBlue = V4 (106/255) (90/255) (205/255) 1 -darkSlateBlue :: (Num a, Fractional a) => V4 a+darkSlateBlue :: Fractional a => V4 a darkSlateBlue = V4 (72/255) (61/255) (139/255) 1 -mediumSlateBlue :: (Num a, Fractional a) => V4 a+mediumSlateBlue :: Fractional a => V4 a mediumSlateBlue = V4 (123/255) (104/255) (238/255) 1 -greenYellow :: (Num a, Fractional a) => V4 a+greenYellow :: Fractional a => V4 a greenYellow = V4 (173/255) (255/255) (47/255) 1 -chartreuse :: (Num a, Fractional a) => V4 a+chartreuse :: Fractional a => V4 a chartreuse = V4 (127/255) (255/255) (0/255) 1 -lawnGreen :: (Num a, Fractional a) => V4 a+lawnGreen :: Fractional a => V4 a lawnGreen = V4 (124/255) (252/255) (0/255) 1 -limeGreen :: (Num a, Fractional a) => V4 a+limeGreen :: Fractional a => V4 a limeGreen = V4 (50/255) (205/255) (50/255) 1 -paleGreen :: (Num a, Fractional a) => V4 a+paleGreen :: Fractional a => V4 a paleGreen = V4 (152/255) (251/255) (152/255) 1 -lightGreen :: (Num a, Fractional a) => V4 a+lightGreen :: Fractional a => V4 a lightGreen = V4 (144/255) (238/255) (144/255) 1 -mediumSpringGreen :: (Num a, Fractional a) => V4 a+mediumSpringGreen :: Fractional a => V4 a mediumSpringGreen = V4 0 (250/255) (154/255) 1 -springGreen :: (Num a, Fractional a) => V4 a+springGreen :: Fractional a => V4 a springGreen = V4 0 (255/255) (127/255) 1 -mediumSeaGreen :: (Num a, Fractional a) => V4 a+mediumSeaGreen :: Fractional a => V4 a mediumSeaGreen = V4 (60/255) (179/255) (113/255) 1 -seaGreen :: (Num a, Fractional a) => V4 a+seaGreen :: Fractional a => V4 a seaGreen = V4 (46/255) (139/255) (87/255) 1 -forestGreen :: (Num a, Fractional a) => V4 a+forestGreen :: Fractional a => V4 a forestGreen = V4 (34/255) (139/255) (34/255) 1 -darkGreen :: (Num a, Fractional a) => V4 a+darkGreen :: Fractional a => V4 a darkGreen = V4 0 (100/255) (0/255) 1 -yellowGreen :: (Num a, Fractional a) => V4 a+yellowGreen :: Fractional a => V4 a yellowGreen = V4 (154/255) (205/255) (50/255) 1 -oliveDrab :: (Num a, Fractional a) => V4 a+oliveDrab :: Fractional a => V4 a oliveDrab = V4 (107/255) (142/255) (35/255) 1 -darkOliveGreen :: (Num a, Fractional a) => V4 a+darkOliveGreen :: Fractional a => V4 a darkOliveGreen = V4 (85/255) (107/255) (47/255) 1 -mediumAquamarine :: (Num a, Fractional a) => V4 a+mediumAquamarine :: Fractional a => V4 a mediumAquamarine = V4 (102/255) (205/255) (170/255) 1 -darkSeaGreen :: (Num a, Fractional a) => V4 a+darkSeaGreen :: Fractional a => V4 a darkSeaGreen = V4 (143/255) (188/255) (143/255) 1 -lightSeaGreen :: (Num a, Fractional a) => V4 a+lightSeaGreen :: Fractional a => V4 a lightSeaGreen = V4 (32/255) (178/255) (170/255) 1 -darkCyan :: (Num a, Fractional a) => V4 a+darkCyan :: Fractional a => V4 a darkCyan = V4 0 (139/255) (139/255) 1 -cyan :: (Num a, Fractional a) => V4 a+cyan :: Fractional a => V4 a cyan = V4 0 (255/255) (255/255) 1 -lightCyan :: (Num a, Fractional a) => V4 a+lightCyan :: Fractional a => V4 a lightCyan = V4 (224/255) (255/255) (255/255) 1 -paleTurquoise :: (Num a, Fractional a) => V4 a+paleTurquoise :: Fractional a => V4 a paleTurquoise = V4 (175/255) (238/255) (238/255) 1 -aquamarine :: (Num a, Fractional a) => V4 a+aquamarine :: Fractional a => V4 a aquamarine = V4 (127/255) (255/255) (212/255) 1 -turquoise :: (Num a, Fractional a) => V4 a+turquoise :: Fractional a => V4 a turquoise = V4 (64/255) (224/255) (208/255) 1 -mediumTurquoise :: (Num a, Fractional a) => V4 a+mediumTurquoise :: Fractional a => V4 a mediumTurquoise = V4 (72/255) (209/255) (204/255) 1 -darkTurquoise :: (Num a, Fractional a) => V4 a+darkTurquoise :: Fractional a => V4 a darkTurquoise = V4 0 (206/255) (209/255) 1 -cadetBlue :: (Num a, Fractional a) => V4 a+cadetBlue :: Fractional a => V4 a cadetBlue = V4 (95/255) (158/255) (160/255) 1 -steelBlue :: (Num a, Fractional a) => V4 a+steelBlue :: Fractional a => V4 a steelBlue = V4 (70/255) (130/255) (180/255) 1 -lightSteelBlue :: (Num a, Fractional a) => V4 a+lightSteelBlue :: Fractional a => V4 a lightSteelBlue = V4 (176/255) (196/255) (222/255) 1 -powderBlue :: (Num a, Fractional a) => V4 a+powderBlue :: Fractional a => V4 a powderBlue = V4 (176/255) (224/255) (230/255) 1 -lightBlue :: (Num a, Fractional a) => V4 a+lightBlue :: Fractional a => V4 a lightBlue = V4 (173/255) (216/255) (230/255) 1 -skyBlue :: (Num a, Fractional a) => V4 a+skyBlue :: Fractional a => V4 a skyBlue = V4 (135/255) (206/255) (235/255) 1 -lightSkyBlue :: (Num a, Fractional a) => V4 a+lightSkyBlue :: Fractional a => V4 a lightSkyBlue = V4 (135/255) (206/255) (250/255) 1 -deepSkyBlue :: (Num a, Fractional a) => V4 a+deepSkyBlue :: Fractional a => V4 a deepSkyBlue = V4 0 (191/255) (255/255) 1 -dodgerBlue :: (Num a, Fractional a) => V4 a+dodgerBlue :: Fractional a => V4 a dodgerBlue = V4 (30/255) (144/255) (255/255) 1 -cornflowerBlue :: (Num a, Fractional a) => V4 a+cornflowerBlue :: Fractional a => V4 a cornflowerBlue = V4 (100/255) (149/255) (237/255) 1 -royalBlue :: (Num a, Fractional a) => V4 a+royalBlue :: Fractional a => V4 a royalBlue = V4 (65/255) (105/255) (225/255) 1 -mediumBlue :: (Num a, Fractional a) => V4 a+mediumBlue :: Fractional a => V4 a mediumBlue = V4 0 (0/255) (205/255) 1 -darkBlue :: (Num a, Fractional a) => V4 a+darkBlue :: Fractional a => V4 a darkBlue = V4 0 (0/255) (139/255) 1 -midnightBlue :: (Num a, Fractional a) => V4 a+midnightBlue :: Fractional a => V4 a midnightBlue = V4 (25/255) (25/255) (112/255) 1 -cornsilk :: (Num a, Fractional a) => V4 a+cornsilk :: Fractional a => V4 a cornsilk = V4 (255/255) (248/255) (220/255) 1 -blanchedAlmond :: (Num a, Fractional a) => V4 a+blanchedAlmond :: Fractional a => V4 a blanchedAlmond = V4 (255/255) (235/255) (205/255) 1 -bisque :: (Num a, Fractional a) => V4 a+bisque :: Fractional a => V4 a bisque = V4 (255/255) (228/255) (196/255) 1 -navajoWhite :: (Num a, Fractional a) => V4 a+navajoWhite :: Fractional a => V4 a navajoWhite = V4 (255/255) (222/255) (173/255) 1 -wheat :: (Num a, Fractional a) => V4 a+wheat :: Fractional a => V4 a wheat = V4 (245/255) (222/255) (179/255) 1 -burlyWood :: (Num a, Fractional a) => V4 a+burlyWood :: Fractional a => V4 a burlyWood = V4 (222/255) (184/255) (135/255) 1 -tan :: (Num a, Fractional a) => V4 a+tan :: Fractional a => V4 a tan = V4 (210/255) (180/255) (140/255) 1 -rosyBrown :: (Num a, Fractional a) => V4 a+rosyBrown :: Fractional a => V4 a rosyBrown = V4 (188/255) (143/255) (143/255) 1 -sandyBrown :: (Num a, Fractional a) => V4 a+sandyBrown :: Fractional a => V4 a sandyBrown = V4 (244/255) (164/255) (96/255) 1 -goldenrod :: (Num a, Fractional a) => V4 a+goldenrod :: Fractional a => V4 a goldenrod = V4 (218/255) (165/255) (32/255) 1 -darkGoldenrod :: (Num a, Fractional a) => V4 a+darkGoldenrod :: Fractional a => V4 a darkGoldenrod = V4 (184/255) (134/255) (11/255) 1 -peru :: (Num a, Fractional a) => V4 a+peru :: Fractional a => V4 a peru = V4 (205/255) (133/255) (63/255) 1 -chocolate :: (Num a, Fractional a) => V4 a+chocolate :: Fractional a => V4 a chocolate = V4 (210/255) (105/255) (30/255) 1 -saddleBrown :: (Num a, Fractional a) => V4 a+saddleBrown :: Fractional a => V4 a saddleBrown = V4 (139/255) (69/255) (19/255) 1 -sienna :: (Num a, Fractional a) => V4 a+sienna :: Fractional a => V4 a sienna = V4 (160/255) (82/255) (45/255) 1 -brown :: (Num a, Fractional a) => V4 a+brown :: Fractional a => V4 a brown = V4 (165/255) (42/255) (42/255) 1 -snow :: (Num a, Fractional a) => V4 a+snow :: Fractional a => V4 a snow = V4 (255/255) (250/255) (250/255) 1 -honeydew :: (Num a, Fractional a) => V4 a+honeydew :: Fractional a => V4 a honeydew = V4 (240/255) (255/255) (240/255) 1 -mintCream :: (Num a, Fractional a) => V4 a+mintCream :: Fractional a => V4 a mintCream = V4 (245/255) (255/255) (250/255) 1 -azure :: (Num a, Fractional a) => V4 a+azure :: Fractional a => V4 a azure = V4 (240/255) (255/255) (255/255) 1 -aliceBlue :: (Num a, Fractional a) => V4 a+aliceBlue :: Fractional a => V4 a aliceBlue = V4 (240/255) (248/255) (255/255) 1 -ghostWhite :: (Num a, Fractional a) => V4 a+ghostWhite :: Fractional a => V4 a ghostWhite = V4 (248/255) (248/255) (255/255) 1 -whiteSmoke :: (Num a, Fractional a) => V4 a+whiteSmoke :: Fractional a => V4 a whiteSmoke = V4 (245/255) (245/255) (245/255) 1 -seashell :: (Num a, Fractional a) => V4 a+seashell :: Fractional a => V4 a seashell = V4 (255/255) (245/255) (238/255) 1 -beige :: (Num a, Fractional a) => V4 a+beige :: Fractional a => V4 a beige = V4 (245/255) (245/255) (220/255) 1 -oldLace :: (Num a, Fractional a) => V4 a+oldLace :: Fractional a => V4 a oldLace = V4 (253/255) (245/255) (230/255) 1 -floralWhite :: (Num a, Fractional a) => V4 a+floralWhite :: Fractional a => V4 a floralWhite = V4 (255/255) (250/255) (240/255) 1 -ivory :: (Num a, Fractional a) => V4 a+ivory :: Fractional a => V4 a ivory = V4 (255/255) (255/255) (240/255) 1 -antiqueWhite :: (Num a, Fractional a) => V4 a+antiqueWhite :: Fractional a => V4 a antiqueWhite = V4 (250/255) (235/255) (215/255) 1 -linen :: (Num a, Fractional a) => V4 a+linen :: Fractional a => V4 a linen = V4 (250/255) (240/255) (230/255) 1 -lavenderBlush :: (Num a, Fractional a) => V4 a+lavenderBlush :: Fractional a => V4 a lavenderBlush = V4 (255/255) (240/255) (245/255) 1 -mistyRose :: (Num a, Fractional a) => V4 a+mistyRose :: Fractional a => V4 a mistyRose = V4 (255/255) (228/255) (225/255) 1 -gainsboro :: (Num a, Fractional a) => V4 a+gainsboro :: Fractional a => V4 a gainsboro = V4 (220/255) (220/255) (220/255) 1 -lightGrey :: (Num a, Fractional a) => V4 a+lightGrey :: Fractional a => V4 a lightGrey = V4 (211/255) (211/255) (211/255) 1 -darkGray :: (Num a, Fractional a) => V4 a+darkGray :: Fractional a => V4 a darkGray = V4 (169/255) (169/255) (169/255) 1 -dimGray :: (Num a, Fractional a) => V4 a+dimGray :: Fractional a => V4 a dimGray = V4 (105/255) (105/255) (105/255) 1 -lightSlateGray :: (Num a, Fractional a) => V4 a+lightSlateGray :: Fractional a => V4 a lightSlateGray = V4 (119/255) (136/255) (153/255) 1 -slateGray :: (Num a, Fractional a) => V4 a+slateGray :: Fractional a => V4 a slateGray = V4 (112/255) (128/255) (144/255) 1 -darkSlateGray :: (Num a, Fractional a) => V4 a+darkSlateGray :: Fractional a => V4 a darkSlateGray = V4 (47/255) (79/255) (79/255) 1 -transparent :: (Num a, Fractional a) => V4 a+transparent :: Fractional a => V4 a transparent = V4 0 0 0 0 -alpha :: (Num a, Fractional a) => V4 a -> a -> V4 a-alpha (V4 r g b _) a = V4 r g b a+withAlpha :: V4 a -> a -> V4 a+withAlpha (V4 r g b _) = V4 r g b -hex :: (Num b, Fractional b) => Int -> V4 b-hex n = fmap ((/255) . fromIntegral) $ V4 r g b a+fromHex :: Fractional b => Int -> V4 b+fromHex n = ((/255) . fromIntegral) <$> V4 r g b a     where r = n `shiftR` 24           g = n `shiftR` 16 .&. 0xFF           b = n `shiftR` 8 .&. 0xFF
+ src/Gelatin/Core/Polyline.hs view
@@ -0,0 +1,95 @@+-- | This module is planned to disappear in favor of a stateful polyline+-- drawing mode. It's still here for various renderers.+module Gelatin.Core.Polyline where++import           Data.List           (unzip5)+import           Data.Vector.Unboxed (Unbox, Vector)+import qualified Data.Vector.Unboxed as V+import           Linear              hiding (trace)+++type PolylineData f =+  ( Vector (V2 Float)+  , Vector (f Float)+  , Vector (V2 Float)+  , Vector (V2 Float)+  , Vector (V2 Float)+  , Float+  )++expandPolyline :: Unbox (f Float)+               => Vector (V2 Float) -> Vector (f Float) -> Float -> Float+               -> Maybe (PolylineData f)+expandPolyline verts colors thickness feather+    | Just (v1,v2) <- (,) <$> (verts V.!? 0) <*> (verts V.!? 1)+    , Just c1  <- colors V.!? 0+    , Just (v3,v3n) <- (,) <$> (verts V.!? (V.length verts -1))+                           <*> (verts V.!? (V.length verts -2))+    , Just c3 <- colors V.!? (V.length verts -1) =+    let -- clamp the lower bound of our thickness to 1+        absthick = max thickness 1+        d = fromIntegral (ceiling $ absthick + 2.5 * feather :: Integer)+        lens = 0 `V.cons` V.zipWith distance verts (V.drop 1 verts)+        totalLen = V.foldl' (+) 0 lens+        totalEnd = totalLen + d+        seqfunc (total,ts) len = (total + len,ts V.++ V.singleton (total + len))+        seqLens  = snd $ V.foldl' seqfunc (0,mempty) lens+        isClosed = distance v1 v3 <= 0.00001+        -- if the polyline is closed return a miter with the last point+        startCap = ( V.fromList [cap,cap]+                   , V.fromList [c1,c1]+                   , uvs+                   , V.fromList [v2,v2]+                   , V.fromList [prev,prev]+                   )+            where (uvs,cap,prev) = if isClosed+                                   -- no cap+                                   then (V.fromList [V2 0 d, V2 0 (-d)],v1,v3n)+                                   -- cap+                                   else let c = d *^ signorm (v2 - v1)+                                        in ( V.fromList [V2 (-d) d, V2 (-d) (-d)]+                                           , v1 - c+                                           , v1 - 2*c)+        endCap = ( V.fromList [cap,cap]+                 , V.fromList [c3,c3]+                 , uvs+                 , V.fromList [next,next]+                 , V.fromList [v3n,v3n]+                 )+            where (uvs,cap,next) = if isClosed+                                   -- no cap+                                   then ( V.fromList [ V2 totalLen d+                                                     , V2 totalLen (-d)+                                                     ]+                                        , v3+                                        , v2+                                        )+                                   -- cap+                                   else let c = d *^ signorm (v3 - v3n)+                                        in (V.fromList [ V2 totalEnd d+                                                       , V2 totalEnd (-d)+                                                       ]+                                           , v3 + c+                                           , v3 + 2*c+                                           )+        vcs  = V.toList $ V.zip3 verts colors seqLens+        zs   = zipWith3 strp vcs (drop 1 vcs) (drop 2 vcs)+        -- Expand the line into a triangle strip+        strp :: Unbox (f Float)+             => (V2 Float, f Float, Float) -> (V2 Float, f Float, Float)+             -> (V2 Float, f Float, Float) -> (Vector (V2 Float)+                                              ,Vector (f Float)+                                              ,Vector (V2 Float)+                                              ,Vector (V2 Float)+                                              ,Vector (V2 Float)+                                              )+        strp (a,_,_) (b,bc,l) (c,_,_) =+          ( V.fromList [b,b]+          , V.fromList [bc,bc]+          , V.fromList [V2 l d,V2 l (-d)]+          , V.fromList [c,c]+          , V.fromList [a,a]+          )+        (vs,cs,us,ns,ps) = unzip5 $ startCap : zs ++ [endCap]+      in Just (V.concat vs, V.concat cs, V.concat us, V.concat ns, V.concat ps, totalLen)+    | otherwise = Nothing
− src/Gelatin/Core/Rendering.hs
@@ -1,642 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}-module Gelatin.Core.Rendering (-    module R,-    initGelatin,-    newWindow,-    loadGeomRenderSource,-    loadBezRenderSource,-    loadMaskRenderSource,-    loadRenderSource,-    loadTexture,-    loadTextureUnit,-    unloadTexture,-    loadImageAsTexture,-    filledTriangleRendering,-    colorRendering,-    colorBezRendering,-    colorFontRendering,-    textureRendering,-    textureUnitRendering,-    maskRendering,-    transformRendering,-    stencilMask,-    alphaMask,-    toTexture,-    toTextureUnit,-    clipTexture,-    calculateDpi-) where--import Gelatin.Core.Shader-import Gelatin.Core.Rendering.Types as R-import Gelatin.Core.Rendering.Polylines as R-import Gelatin.Core.Rendering.Geometrical as R-import Gelatin.Core.Rendering.Font as R-import Linear-import Graphics.Text.TrueType-import Graphics.GL.Core33-import Graphics.GL.Types-import Graphics.UI.GLFW as GLFW hiding (Image(..))-import Codec.Picture.Types-import Codec.Picture (readImage)-import Foreign.Marshal.Array-import Foreign.Marshal.Utils-import Foreign.C.String-import Foreign.Storable-import Foreign.Ptr-import Data.Monoid-import Data.Maybe-import Data.Vector.Storable (Vector,unsafeWith)-import Control.Monad-import System.Directory-import System.IO-import System.Exit-import qualified Data.ByteString.Char8 as B-import qualified Data.Foldable as F-import GHC.Stack---- | Initializes the system. This must be called before creating a window.--- Returns True when initialization was successful.-initGelatin :: IO Bool-initGelatin = do-    setErrorCallback $ Just $ \_ -> hPutStrLn stderr-    GLFW.init---- | Creates a window. This can only be called after initializing with--- `initGelatin`.-newWindow :: Int -- ^ Width-          -> Int -- ^ Height-          -> String -- ^ Title-          -> Maybe Monitor -- ^ The monitor to fullscreen into.-          -> Maybe Window -- ^ A window to share OpenGL contexts with.-          -> IO Window-newWindow ww wh ws mmon mwin = do-    defaultWindowHints-    windowHint $ WindowHint'OpenGLDebugContext True-    windowHint $ WindowHint'OpenGLProfile OpenGLProfile'Core-    windowHint $ WindowHint'OpenGLForwardCompat True-    windowHint $ WindowHint'ContextVersionMajor 3-    windowHint $ WindowHint'ContextVersionMinor 3-    windowHint $ WindowHint'DepthBits 16-    mwin' <- createWindow ww wh ws mmon mwin-    makeContextCurrent mwin'-    window <- case mwin' of-                  Nothing  -> do putStrLn "could not create window"-                                 exitFailure-                  Just win -> return win-    return window------------------------------------------------------------------------------------- Renderings------------------------------------------------------------------------------------ | Creates and returns a renderer that renders a given string of--- triangles with the given filling.-filledTriangleRendering :: Window -> GeomRenderSource -> [Triangle (V2 Float)]-                       -> Fill -> IO Rendering-filledTriangleRendering win grs ts fill = do-    let vs = trisToComp ts-    mfr <- getFillResult fill vs-    case mfr of-        Just (FillResultColor cs) -> colorRendering win grs GL_TRIANGLES vs cs-        Just (FillResultTexture _ uvs) -> textureRendering win grs GL_TRIANGLES-                                                                  vs uvs-        _ -> do putStrLn "Could not create a filledTriangleRendering."-                return $ Rendering (const $ putStrLn "Non op renderer.") (return ())---- | Applies a fill to a list of points to create a fill result. If the--- Fill is a texture then the texture's image will be loaded.-getFillResult :: Fill -> [V2 Float] -> IO (Maybe FillResult)-getFillResult (FillColor f) vs = return $ Just $ FillResultColor $ map f vs-getFillResult (FillTexture fp f) vs = do-    mtex <- loadImageAsTexture fp-    return $ case mtex of-        Nothing  -> Nothing-        Just tex -> Just $ FillResultTexture tex $ map f vs---- | TODO: textureFontRendering and then fontRendering.---- | Creates and returns a renderer that renders a given FontString.-colorFontRendering :: Window -> GeomRenderSource -> BezRenderSource-                  -> FontString -> (V2 Float -> V4 Float) -> IO Rendering-colorFontRendering window grs brs fstr clrf = do-    dpi <- calculateDpi-    let (bs,ts) = fontGeom dpi fstr-        vs = concatMap (\(Triangle a b c) -> [a,b,c]) ts-        cs = map clrf vs-    Rendering fg cg <- colorRendering window grs GL_TRIANGLES vs cs--    let bcs = map ((\(Bezier _ a b c) -> Triangle a b c) . fmap clrf) bs-    Rendering fb cb <- colorBezRendering window brs bs bcs--    let s t  = stencilMask (fg t) (fg t)-        gs t = s t >> fb t-    return $ Rendering gs (cg >> cb)---- | Creates and returns a renderer that renders the given colored--- geometry.-colorRendering :: Window -> GeomRenderSource -> GLuint -> [V2 Float]-              -> [V4 Float] -> IO Rendering-colorRendering window grs mode vs gs = do-    let (GRS src) = grs-        srcs = [src]--    withVAO $ \vao -> withBuffers 2 $ \[pbuf,cbuf] -> do-        let ps = map realToFrac $ concatMap F.toList vs :: [GLfloat]-            cs = map realToFrac $ concatMap F.toList $ take (length vs) gs :: [GLfloat]--        glDisableVertexAttribArray uvLoc-        glEnableVertexAttribArray colorLoc--        bufferAttrib positionLoc 2 pbuf ps-        bufferAttrib colorLoc 4 cbuf cs-        glBindVertexArray 0--        let num = fromIntegral $ length vs-            renderFunction t = do-                withUniform "hasUV" srcs $ \p huv -> do-                    glUseProgram p-                    glUniform1i huv 0-                withUniform "projection" srcs $ setOrthoWindowProjection window-                withUniform "modelview" srcs $ setModelview t-                drawBuffer (rsProgram src) vao mode num-            cleanupFunction = do-                withArray [pbuf, cbuf] $ glDeleteBuffers 2-                withArray [vao] $ glDeleteVertexArrays 1-        return $ Rendering renderFunction cleanupFunction---- | Creates and returns a renderer that renders a textured--- geometry using the texture bound to GL_TEXTURE0.-textureRendering :: Window -> GeomRenderSource -> GLuint -> [V2 Float]-                -> [V2 Float] -> IO Rendering-textureRendering = textureUnitRendering Nothing---- | Creates and returns a renderer that renders the given textured--- geometry using the specified texture binding.-textureUnitRendering :: (Maybe GLint) -> Window -> GeomRenderSource -> GLuint-                    -> [V2 Float] -> [V2 Float] -> IO Rendering-textureUnitRendering Nothing w gs md vs uvs =-    textureUnitRendering (Just 0) w gs md vs uvs-textureUnitRendering (Just u) win grs mode vs uvs = do-    let (GRS src) = grs-        srcs = [src]--    withVAO $ \vao -> withBuffers 2 $ \[pbuf,cbuf] -> do-        let f xs = map realToFrac $ concatMap F.toList xs :: [GLfloat]-            ps = f vs-            cs = f $ take (length vs) uvs--        glDisableVertexAttribArray colorLoc-        glEnableVertexAttribArray uvLoc--        bufferAttrib positionLoc 2 pbuf ps-        bufferAttrib uvLoc 2 cbuf cs-        glBindVertexArray 0--        let num = fromIntegral $ length vs-            renderFunction tfrm = do-                withUniform "hasUV" srcs $ \p huv -> do-                    glUseProgram p-                    glUniform1i huv 1-                withUniform "sampler" srcs $ \p smp -> do-                    glUseProgram p-                    glUniform1i smp u-                withUniform "projection" srcs $ setOrthoWindowProjection win-                withUniform "modelview" srcs $ setModelview tfrm-                drawBuffer (rsProgram src) vao mode num-            cleanupFunction = do-                withArray [pbuf, cbuf] $ glDeleteBuffers 2-                withArray [vao] $ glDeleteVertexArrays 1-        return $ Rendering renderFunction cleanupFunction---- | Creates and returns a renderer that renders the given colored beziers.-colorBezRendering :: Window -> BezRenderSource -> [Bezier (V2 Float)]-                 -> [Triangle (V4 Float)] -> IO Rendering-colorBezRendering window (BRS src) bs ts =-    withVAO $ \vao -> withBuffers 3 $ \[pbuf, tbuf, cbuf] -> do-        let vs = concatMap (\(Bezier _ a b c) -> [a,b,c]) bs-            cvs = concatMap (\(Triangle a b c) -> [a,b,c]) $ take (length bs) ts-            ps = map realToFrac $ concatMap F.toList vs :: [GLfloat]-            cs = map realToFrac $ concatMap F.toList cvs :: [GLfloat]-            ws = concatMap (\(Bezier w _ _ _) -> let w' = fromBool $ w == LT-                                                 in [ 0, 0, w'-                                                    , 0.5, 0, w'-                                                    , 1, 1, w'-                                                    ])-                           bs :: [GLfloat]--        glDisableVertexAttribArray uvLoc-        glEnableVertexAttribArray colorLoc-        bufferAttrib positionLoc 2 pbuf ps-        bufferAttrib bezLoc 3 tbuf ws-        bufferAttrib colorLoc 4 cbuf cs-        glBindVertexArray 0--        let cleanupFunction = do-                withArray [pbuf, tbuf, cbuf] $ glDeleteBuffers 3-                withArray [vao] $ glDeleteVertexArrays 1-            num = fromIntegral $ length vs-            srcs = [src]-            renderFunction t = do-                withUniform "hasUV" srcs $ \p huv -> do-                    glUseProgram p-                    glUniform1i huv 0-                withUniform "projection" srcs $ setOrthoWindowProjection window-                withUniform "modelview" srcs $ setModelview t-                drawBuffer (rsProgram src) vao GL_TRIANGLES num-        return $ Rendering renderFunction cleanupFunction---- | Creates and returns a renderer that masks a textured rectangular area with--- another texture.-maskRendering :: Window -> MaskRenderSource -> GLuint -> [V2 Float]-             -> [V2 Float] -> IO Rendering-maskRendering win (MRS src) mode vs uvs =-    withVAO $ \vao -> withBuffers 2 $ \[pbuf, uvbuf] -> do-        let vs'  = map realToFrac $ concatMap F.toList vs :: [GLfloat]-            uvs' = map realToFrac $ concatMap F.toList uvs :: [GLfloat]--        glDisableVertexAttribArray colorLoc-        glEnableVertexAttribArray positionLoc-        glEnableVertexAttribArray uvLoc-        bufferAttrib positionLoc 2 pbuf vs'-        bufferAttrib uvLoc 2 uvbuf uvs'-        glBindVertexArray 0--        let cleanup = do withArray [pbuf, uvbuf] $ glDeleteBuffers 2-                         withArray [vao] $ glDeleteVertexArrays 1-            num = fromIntegral $ length vs-            render t = do-                withUniform "projection" [src] $ setOrthoWindowProjection win-                withUniform "modelview" [src] $ setModelview t-                withUniform "mainTex" [src] $ \p smp -> do-                    glUseProgram p-                    glUniform1i smp 0-                withUniform "maskTex" [src] $ \p smp -> do-                    glUseProgram p-                    glUniform1i smp 1-                drawBuffer (rsProgram src) vao mode num-        return $ Rendering render cleanup---- | Creates a rendering that masks an IO () drawing computation with the alpha--- value of another.-alphaMask :: Window -> MaskRenderSource -> IO () -> IO () -> IO Rendering-alphaMask win mrs r2 r1 = do-    mainTex <- toTextureUnit (Just GL_TEXTURE0) win r2-    maskTex <- toTextureUnit (Just GL_TEXTURE1) win r1-    (w,h)   <- getWindowSize win-    let vs = map (fmap fromIntegral) [V2 0 0, V2 w 0, V2 w h, V2 0 h]-        uvs = [V2 0 1, V2 1 1, V2 1 0, V2 0 0]-    Rendering f c <- maskRendering win mrs GL_TRIANGLE_FAN vs uvs-    let f' _ = do glActiveTexture GL_TEXTURE0-                  glBindTexture GL_TEXTURE_2D mainTex-                  glActiveTexture GL_TEXTURE1-                  glBindTexture GL_TEXTURE_2D maskTex-        c'    = withArray [mainTex,maskTex] $ glDeleteTextures 2-        f'' _ = do glActiveTexture GL_TEXTURE0-                   glBindTexture GL_TEXTURE_2D 0-                   glActiveTexture GL_TEXTURE1-                   glBindTexture GL_TEXTURE_2D 0-    return $ Rendering (\t -> f' t >> f t >> f'' t) (c >> c')---- | Creates an IO () drawing computation that masks an IO () drawing--- computation with another using a stencil test.-stencilMask :: IO () -> IO () -> IO ()-stencilMask r2 r1  = do-    glClear GL_DEPTH_BUFFER_BIT-    -- Enable stencil testing-    glEnable GL_STENCIL_TEST-    -- Disable writing frame buffer color components-    glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE-    -- Disable writing into the depth buffer-    glDepthMask GL_FALSE-    -- Enable writing to all bits of the stencil mask-    glStencilMask 0xFF-    -- Clear the stencil buffer-    glClear GL_STENCIL_BUFFER_BIT-    glStencilFunc GL_NEVER 0 1-    glStencilOp GL_INVERT GL_INVERT GL_INVERT-    r1--    glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE-    glDepthMask GL_TRUE-    glStencilFunc GL_EQUAL 1 1-    glStencilOp GL_ZERO GL_ZERO GL_ZERO-    r2-    glDisable GL_STENCIL_TEST---transformRendering :: Transform -> Rendering -> Rendering-transformRendering t (Rendering r c) = Rendering (r . (t <>)) c------------------------------------------------------------------------------------ Updating uniforms----------------------------------------------------------------------------------withUniform :: String -> [RenderSource] -> (GLuint -> GLint -> IO ()) -> IO ()-withUniform name srcs f = mapM_ update srcs-    where update (RenderSource p ls) = case lookup name ls of-                                           Nothing -> return ()-                                           Just u  -> do f p u--setOrthoWindowProjection :: Window -> GLuint -> GLint -> IO ()-setOrthoWindowProjection window program pju = do-    pj <- orthoWindowProjection window-    glUseProgram program-    with pj $ glUniformMatrix4fv pju 1 GL_TRUE . castPtr--setModelview :: Transform -> GLuint -> GLint -> IO ()-setModelview (Transform (V2 x y) (V2 w h) r) program uniform = do-    let mv = mat4Translate txy !*! rot !*! mat4Scale sxy :: M44 GLfloat-        sxy = V3 w h 1-        txy = V3 x y 0-        rxy = V3 0 0 1-        rot = if r /= 0 then mat4Rotate r rxy else identity-    glUseProgram program-    with mv $ glUniformMatrix4fv uniform 1 GL_TRUE . castPtr--orthoWindowProjection :: Window -> IO (M44 GLfloat)-orthoWindowProjection window = do-    (ww, wh) <- getWindowSize window-    let (hw,hh) = (fromIntegral ww, fromIntegral wh)-    return $ ortho 0 hw hh 0 0 1------------------------------------------------------------------------------------ Loading resources and things------------------------------------------------------------------------------------- | Loads a new shader program and attributes for rendering geometry.-loadGeomRenderSource :: IO GeomRenderSource-loadGeomRenderSource = do-    let def = RenderDefBS [(vertSourceGeom, GL_VERTEX_SHADER)-                          ,(fragSourceGeom, GL_FRAGMENT_SHADER)-                          ] ["projection", "modelview", "sampler", "hasUV"]-    GRS <$> loadRenderSource def---- | Loads a new shader progarm and attributes for rendering beziers.-loadBezRenderSource :: IO BezRenderSource-loadBezRenderSource = do-    let def = RenderDefBS [(vertSourceBezier, GL_VERTEX_SHADER)-                          ,(fragSourceBezier, GL_FRAGMENT_SHADER)-                          ] ["projection", "modelview", "sampler", "hasUV"]-    BRS <$> loadRenderSource def---- | Loads a new shader program and attributes for masking textures.-loadMaskRenderSource :: IO MaskRenderSource-loadMaskRenderSource = do-    let def = RenderDefBS [(vertSourceMask, GL_VERTEX_SHADER)-                          ,(fragSourceMask, GL_FRAGMENT_SHADER)-                          ] ["projection","modelview","mainTex","maskTex"]-    MRS <$> loadRenderSource def--loadRenderSource :: RenderDef -> IO RenderSource-loadRenderSource (RenderDefBS ss uniforms) = do-    shaders <- mapM (uncurry compileShader) ss-    program <- compileProgram shaders-    glUseProgram program-    locs <- forM uniforms $ \attr -> do-        loc <- withCString attr $ glGetUniformLocation program-        return $ if loc == (-1)-                 then Nothing-                 else Just (attr, loc)-    print locs-    return $ RenderSource program $ catMaybes locs-loadRenderSource (RenderDefFP fps uniforms) = do-    cwd <- getCurrentDirectory-    srcs <- forM fps $ \(fp, shaderType) -> do-        src <- B.readFile $ cwd ++ "/" ++ fp-        return (src, shaderType)-    loadRenderSource $ RenderDefBS srcs uniforms------------------------------------------------------------------------------------ Working with textures.----------------------------------------------------------------------------------loadImageAsTexture :: FilePath -> IO (Maybe GLuint)-loadImageAsTexture fp = do-    eStrOrImg <- readImage fp-    case eStrOrImg of-        Left err -> putStrLn err >> return Nothing-        Right i  -> loadTexture i >>= return . Just--loadTexture :: DynamicImage -> IO GLuint-loadTexture = loadTextureUnit Nothing--loadTextureUnit :: Maybe GLuint -> DynamicImage -> IO GLuint-loadTextureUnit Nothing img = loadTextureUnit (Just GL_TEXTURE0) img-loadTextureUnit (Just u) img = do-    [t] <- allocaArray 1 $ \ptr -> do-        glGenTextures 1 ptr-        peekArray 1 ptr-    glActiveTexture u-    glBindTexture GL_TEXTURE_2D t-    loadJuicy img-    glGenerateMipmap GL_TEXTURE_2D  -- Generate mipmaps now!!!-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_REPEAT-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_REPEAT-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST_MIPMAP_NEAREST-    glBindTexture GL_TEXTURE_2D 0-    return t--unloadTexture :: GLuint -> IO ()-unloadTexture t = withArray [t] $ glDeleteTextures 1--loadJuicy :: DynamicImage -> IO ()-loadJuicy (ImageY8 (Image w h d)) = bufferImageData w h d GL_RED GL_UNSIGNED_BYTE-loadJuicy (ImageY16 (Image w h d)) = bufferImageData w h d GL_RED GL_UNSIGNED_SHORT-loadJuicy (ImageYF (Image w h d)) = bufferImageData w h d GL_RED GL_FLOAT-loadJuicy (ImageYA8 i) = loadJuicy $ ImageRGB8 $ promoteImage i-loadJuicy (ImageYA16 i) = loadJuicy $ ImageRGBA16 $ promoteImage i-loadJuicy (ImageRGB8 (Image w h d)) = bufferImageData w h d GL_RGB GL_UNSIGNED_BYTE-loadJuicy (ImageRGB16 (Image w h d)) = bufferImageData w h d GL_RGB GL_UNSIGNED_SHORT-loadJuicy (ImageRGBF (Image w h d)) = bufferImageData w h d GL_RGB GL_FLOAT-loadJuicy (ImageRGBA8 (Image w h d)) = bufferImageData w h d GL_RGBA GL_UNSIGNED_BYTE-loadJuicy (ImageRGBA16 (Image w h d)) = bufferImageData w h d GL_RGBA GL_UNSIGNED_SHORT-loadJuicy (ImageYCbCr8 i) = loadJuicy $ ImageRGB8 $ convertImage i-loadJuicy (ImageCMYK8 i) = loadJuicy $ ImageRGB8 $ convertImage i-loadJuicy (ImageCMYK16 i) = loadJuicy $ ImageRGB16 $ convertImage i---toTexture :: Window -> IO () -> IO GLuint-toTexture = toTextureUnit Nothing--toTextureUnit :: Maybe GLuint -> Window -> IO () -> IO GLuint-toTextureUnit Nothing win r = toTextureUnit (Just GL_TEXTURE0) win r-toTextureUnit (Just u) win r = do-    [fb] <- allocaArray 1 $ \ptr -> do-        glGenFramebuffers 1 ptr-        peekArray 1 ptr-    glBindFramebuffer GL_FRAMEBUFFER fb--    [t] <- allocaArray 1 $ \ptr -> do-        glGenTextures 1 ptr-        peekArray 1 ptr-    glActiveTexture u-    glBindTexture GL_TEXTURE_2D t-    (w,h) <- getWindowSize win-    let [w',h'] = map fromIntegral [w,h]-    glTexImage2D GL_TEXTURE_2D-                 0-                 GL_RGBA-                 w'-                 h'-                 0-                 GL_RGBA-                 GL_UNSIGNED_BYTE-                 nullPtr-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST--    glFramebufferTexture GL_FRAMEBUFFER GL_COLOR_ATTACHMENT0 t 0-    withArray [GL_COLOR_ATTACHMENT0] $ glDrawBuffers 1--    status <- glCheckFramebufferStatus GL_FRAMEBUFFER-    if status /= GL_FRAMEBUFFER_COMPLETE-    then putStrLn "incomplete framebuffer!"-    else do glClearColor 0 0 0 0-            glClear GL_COLOR_BUFFER_BIT-            --ww <- (fromIntegral . fst) <$> getWindowSize win--            --let s = floor (fbw/ww :: Double)-            --print s-            glViewport 0 0 w' h' --fbw' fbh'-            r-            glBindFramebuffer GL_FRAMEBUFFER 0-            with fb $ glDeleteFramebuffers 1-            (fbw, fbh) <- getFramebufferSize win-            glViewport 0 0 (fromIntegral fbw) (fromIntegral fbh)-    return t---- | Sub-samples a texture using the given coordinate box and creates a new--- texture. Keep in mind that OpenGL texture coordinates are flipped from--- 'normal' graphics coordinates (y = 0 is the bottom of the texture). That--- fact has bitten the author a number of times while clipping a texture--- created with `toTexture` and `toUnitTexture`.-clipTexture :: GLuint -> ClippingArea -> IO GLuint-clipTexture rtex ((V2 x1 y1), (V2 x2 y2)) = do-    -- Create our framebuffers-    [fbread,fbwrite] <- allocaArray 2 $ \ptr -> do-        glGenFramebuffers 2 ptr-        peekArray 2 ptr-    -- Bind our read frame buffer and attach the input texture to it-    glBindFramebuffer GL_READ_FRAMEBUFFER fbread-    glFramebufferTexture2D GL_READ_FRAMEBUFFER GL_COLOR_ATTACHMENT0 GL_TEXTURE_2D rtex 0-    clearErrors "clipTexture bind read framebuffer"-    -- Generate a new texture and bind our write framebuffer to it-    [wtex] <- allocaArray 1 $ \ptr -> do-        glGenTextures 1 ptr-        peekArray 1 ptr-    glActiveTexture GL_TEXTURE0-    glBindTexture GL_TEXTURE_2D wtex-    let [x1',y1',x2',y2',w',h'] = map fromIntegral-                                      [x1,y1,x2,y2,(abs $ x2 - x1)-                                                  ,(abs $ y2 - y1)]-    glTexImage2D GL_TEXTURE_2D-                 0-                 GL_RGBA-                 w'-                 h'-                 0-                 GL_RGBA-                 GL_UNSIGNED_BYTE-                 nullPtr-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST-    glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST-    glBindFramebuffer GL_DRAW_FRAMEBUFFER fbwrite-    glFramebufferTexture2D GL_DRAW_FRAMEBUFFER GL_COLOR_ATTACHMENT0 GL_TEXTURE_2D wtex 0-    clearErrors "clipTexture bind write framebuffer"-    -- Check our frame buffer stati-    forM_ [GL_READ_FRAMEBUFFER,GL_DRAW_FRAMEBUFFER] $ \fb -> do-        status <- glCheckFramebufferStatus fb-        when (status /= GL_FRAMEBUFFER_COMPLETE) $ do-            putStrLn "incomplete framebuffer!"-            exitFailure-    -- Blit the read framebuffer into the write framebuffer-    glBlitFramebuffer x1' y1' x2' y2' 0 0 w' h' GL_COLOR_BUFFER_BIT GL_NEAREST-    clearErrors "clipTexture blit framebuffers"-    -- Cleanup-    glBindFramebuffer GL_FRAMEBUFFER 0-    withArray [fbread,fbwrite] $ glDeleteFramebuffers 2-    glBindTexture GL_TEXTURE_2D 0-    return wtex--calculateDpi :: IO Dpi-calculateDpi = do-    mMonitor <- getPrimaryMonitor--    -- Calculate the dpi of the primary monitor.-    case mMonitor of-        -- I've choosen 128 as the default DPI because of my macbook 15"-        Nothing -> return 128-        Just m  -> do (w, h) <- getMonitorPhysicalSize m-                      mvmode <- getVideoMode m-                      case mvmode of-                          Nothing -> return 128-                          Just (VideoMode vw vh _ _ _ _) -> do-                              let mm2 = fromIntegral $ w*h :: Double-                                  px  = sqrt $ (fromIntegral vw :: Double)*(fromIntegral vh)-                                  inches = sqrt $ mm2 / (25.4 * 25.4)-                              let dpi = floor $ px / inches-                              return dpi------------------------------------------------------------------------------------ Buffering, Vertex Array Objects, Uniforms, etc.----------------------------------------------------------------------------------bufferImageData :: forall a a1 a2. (Storable a2, Integral a1, Integral a) => a -> a1 -> Vector a2 -> GLenum -> GLenum -> IO ()-bufferImageData w h dat imgfmt pxfmt = unsafeWith dat $ \ptr -> do-    --glTexStorage2D GL_TEXTURE_2D 1 GL_RGBA8 (fromIntegral w) (fromIntegral h)-    --glTexSubImage2D GL_TEXTURE_2D 0 0 0 (fromIntegral w) (fromIntegral h) GL_RGBA GL_UNSIGNED_BYTE (castPtr ptr)-    glTexImage2D-        GL_TEXTURE_2D-        0-        GL_RGBA-        (fromIntegral w)-        (fromIntegral h)-        0-        imgfmt-        pxfmt-        (castPtr ptr)-    err <- glGetError-    when (err /= 0) $ putStrLn $ "glTexImage2D Error: " ++ show err--withVAO :: (GLuint -> IO b) -> IO b-withVAO f = do-    [vao] <- allocaArray 1 $ \ptr -> do-        glGenVertexArrays 1 ptr-        peekArray 1 ptr-    glBindVertexArray vao-    r <- f vao-    glBindVertexArray vao-    return r--withBuffers :: Int -> ([GLuint] -> IO b) -> IO b-withBuffers n f = do-    bufs <- allocaArray n $ \ptr -> do-        glGenBuffers (fromIntegral n) ptr-        peekArray (fromIntegral n) ptr-    f bufs--bufferAttrib :: Storable a => GLuint -> GLint -> GLuint -> [a] -> IO ()-bufferAttrib loc n buf as = do-    let asize = length as * glFloatSize-    glBindBuffer GL_ARRAY_BUFFER buf-    withArray as $ \ptr ->-        glBufferData GL_ARRAY_BUFFER (fromIntegral asize) (castPtr ptr) GL_STATIC_DRAW-    glEnableVertexAttribArray loc-    glVertexAttribPointer loc n GL_FLOAT GL_FALSE 0 nullPtr--drawBuffer :: GLuint-           -> GLuint-           -> GLenum-           -> GLsizei-           -> IO ()-drawBuffer program vao mode num = do-    glUseProgram program-    glBindVertexArray vao-    clearErrors "glBindVertex"-    glDrawArrays mode 0 num-    clearErrors "glDrawArrays"--clearErrors :: String -> IO ()-clearErrors str = do-    err' <- glGetError-    when (err' /= 0) $ errorWithStackTrace $ unwords [str, show err']--glFloatSize :: Int-glFloatSize = sizeOf (undefined :: GLfloat)
− src/Gelatin/Core/Rendering/Font.hs
@@ -1,112 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE GADTs #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Gelatin.Core.Rendering.Font (-    compileFontCache,-    fontGeom,-    findFont,-    allFonts,-    withFontAsync,-    withFont,-    concaveTriangles-) where--import Gelatin.Core.Rendering.Types-import Gelatin.Core.Rendering.Geometrical-import Prelude hiding (init)-import Control.Concurrent.Async-import Linear-import Graphics.Text.TrueType-import qualified Data.Vector.Unboxed as UV--compileFontCache :: IO (Async FontCache)-compileFontCache = async $ do-    putStrLn "Loading font cache."-    a <- buildCache-    putStrLn "Font cache loaded."-    return a--findFont :: Async FontCache -> FontDescriptor -> IO (Maybe FilePath)-findFont afCache desc = do-    -- Get the font cache from our async container-    mfCache <- poll afCache-    -- If it has loaded check if the font in question exists-    return $ do efCache <- mfCache-                case efCache of-                    Left _      -> Nothing-                    Right cache -> findFontInCache cache desc--allFonts :: Async FontCache -> IO (Maybe [FontDescriptor])-allFonts afcache = do-    mfcache <- poll afcache-    return $ do efcache <- mfcache-                case efcache of-                    Left _ -> Nothing-                    Right fcache -> Just $ enumerateFonts fcache--withFontAsync :: Async FontCache -> FontDescriptor -> (Font -> IO a) -> IO (Maybe a)-withFontAsync afcache desc f = do-    mPath <- findFont afcache desc-    case mPath of-        Nothing -> return Nothing-        Just path -> do ef <- loadFontFile path-                        case ef of-                            Left err   -> putStrLn err >> return Nothing-                            Right font -> Just `fmap` f font--withFont :: FontCache -> FontDescriptor -> (Font -> IO a) -> IO (Maybe a)-withFont cache desc f = do-    case findFontInCache cache desc of-        Nothing -> return Nothing-        Just fp -> do ef <- loadFontFile fp-                      case ef of-                          Left err   -> putStrLn err >> return Nothing-                          Right font -> Just `fmap` f font-------------------------------------------------------------------------------------- Decomposition into triangles and beziers------------------------------------------------------------------------------------ | Ephemeral types for creating polygons from font outlines.--- Fonty gives us a [[Vector (Float, Float)]] for an entire string, which breaks down to-type Contours = [Bezier (V2 Float)] -- Beziers-type CharacterOutline = [Contours]-type StringOutline = [CharacterOutline]---- | Merges poly a into poly b by "cutting" a and inserting b.---cutMerge :: Poly -> Poly -> Poly---cutMerge as bs = (take (ndx + 1) as) ++ bs ++ [head bs] ++ (drop ndx as)---    where (ndx, _) = head $ sortBy (\a b -> snd a `compare` snd b) $---                         zip [0..] $ map (`distance` (head bs)) as--fontGeom :: Dpi -> FontString -> ([Bezier (V2 Float)], [Triangle (V2 Float)])-fontGeom dpi (FontString font px offset str) =-    let sz  = pixelSizeInPointAtDpi px dpi-        cs  = getStringCurveAtPoint dpi offset [(font, sz, str)]-        bs  = beziers cs-        ts  = concatMap (concatMap (concaveTriangles . onContourPoints)) bs-    in (concat $ concat bs,ts)--fromFonty :: (UV.Unbox b1, Functor f1, Functor f) => ([V2 b1] -> b) -> f (f1 (UV.Vector (b1, b1))) -> f (f1 b)-fromFonty f = fmap $ fmap $ f . UV.toList . UV.map (uncurry V2)--beziers :: [[UV.Vector (Float, Float)]] -> StringOutline-beziers = fromFonty (toBeziers . (fmap (fmap realToFrac)))---- | Turns a polygon into a list of triangles that can be rendered using the--- Concave Polygon Stencil Test--- @see http://www.glprogramming.com/red/chapter14.html#name13-concaveTriangles :: [a] -> [Triangle a]-concaveTriangles [] = []-concaveTriangles (a:as) = tris a as-    where tris p (p':p'':ps) = Triangle p p' p'' : tris p (p'':ps)-          tris _ _ = []---- | Collects the points that lie directly on the contour of the font--- outline.-onContourPoints :: [Bezier a] -> [a]-onContourPoints [] = []-onContourPoints ((Bezier LT a b c):bs) = [a,b,c] ++ onContourPoints bs-onContourPoints ((Bezier _ a _ c):bs) = [a,c] ++ onContourPoints bs
− src/Gelatin/Core/Rendering/Geometrical.hs
@@ -1,103 +0,0 @@-module Gelatin.Core.Rendering.Geometrical (-    bez,-    toLines,-    toArrows,-    toBeziers,-    trisToComp,-    triPoints,-    transform,-    transformV2,-    transformPoly,-    scale,-    translate,-    rotate,-    mat4Translate,-    mat4Rotate,-    mat4Scale-) where--import Gelatin.Core.Triangulation.Common-import Gelatin.Core.Rendering.Types-import Linear hiding (rotate)--toLines :: [a] -> [Line a]-toLines (a:b:cs) = Line a b : toLines (b:cs)-toLines _ = []--toArrows :: Floating a => [V2 a] -> [Line (V2 a)]-toArrows (a:b:cs) = arrow ++ toArrows (b:cs)-    where arrow = [ Line a b-                  , Line (b - u*l + n * w) b-                  , Line (b - u*l + n * (-w)) b-                  ]-            where n = signorm $ perp $ b - a-                  u = signorm $ b - a-                  l = 5 -- head length-                  w = 3 -- head width-toArrows _ = []--toBeziers :: (Fractional a, Ord a) => [V2 a] -> [Bezier (V2 a)]-toBeziers (a:b:c:ps) = bez a b c : toBeziers (c:ps)-toBeziers _ = []--bez :: (Ord a, Fractional a) => V2 a -> V2 a -> V2 a -> Bezier (V2 a)-bez a b c = Bezier (compare (triangleArea a b c) 0) a b c--trisToComp :: [Triangle (V2 a)] -> [V2 a]-trisToComp = concatMap triPoints--triPoints :: Triangle (V2 a) -> [V2 a]-triPoints (Triangle a b c) = [a, b, c]------------------------------------------------------------------------------------- Transformation helpers----------------------------------------------------------------------------------toM44 :: Transform -> M44 Float-toM44 (Transform (V2 x y) (V2 w h) r) = mv-    where mv = mat4Translate txy !*! rot !*! mat4Scale sxy-          sxy = V3 w h 1-          txy = V3 x y 0-          rxy = V3 0 0 1-          rot = if r /= 0 then mat4Rotate r rxy else identity--transformPoly :: Transform -> Poly -> Poly-transformPoly t p = map (transformV2 t) p--transformV2 :: Transform -> V2 Float -> V2 Float-transformV2 t (V2 x y) = V2 x' y'-    where V3 x' y' _ = transform t $ V3 x y 1--transform :: Transform -> V3 Float -> V3 Float-transform t (V3 x y z) = V3 x' y' z'-    where V4 (V1 x') (V1 y') (V1 z') _ = t' !*! V4 (V1 x) (V1 y) (V1 z) (V1 1)-          t' = toM44 t--scale :: RealFrac a => a -> a -> Transform -> Transform-scale sx sy t@Transform{tfrmScale = V2 x y} =-    t{tfrmScale = V2 (sx'*x) (sy'*y)}-        where [sx',sy'] = map realToFrac [sx,sy]--translate :: RealFrac a => a -> a -> Transform -> Transform-translate tx ty t@Transform{tfrmTranslation = V2 x y} =-    t{tfrmTranslation = V2 (x+tx') (y+ty')}-        where [tx',ty'] = map realToFrac [tx,ty]--rotate :: RealFrac a => a -> Transform -> Transform-rotate r' t@Transform{tfrmRotation = r} = t{tfrmRotation = r + realToFrac r'}------------------------------------------------------------------------------------- Matrix helpers----------------------------------------------------------------------------------mat4Translate :: Num a => V3 a -> M44 a-mat4Translate = mkTransformationMat identity--mat4Rotate :: (Num a, Epsilon a, Floating a) => a -> V3 a -> M44 a-mat4Rotate phi v = mkTransformation (axisAngle v phi) (V3 0 0 0)--mat4Scale :: Num a => V3 a -> M44 a-mat4Scale (V3 x y z) =-    V4 (V4 x 0 0 0)-       (V4 0 y 0 0)-       (V4 0 0 z 0)-       (V4 0 0 0 1)-
− src/Gelatin/Core/Rendering/Polylines.hs
@@ -1,216 +0,0 @@-module Gelatin.Core.Rendering.Polylines where--import Gelatin.Core.Rendering.Types-import Gelatin.Core.Triangulation.Common (triangleArea)-import Linear hiding (trace)-import Debug.Trace--polygonExpand :: Float -> [V2 Float] -> [V2 Float]-polygonExpand t ps = trace (show (length ps, length vs, length poly)) poly-    where poly  = zipWith f ps vs-          f p v = p + (v ^* t)-          bows  = zip3 ps' (tail ps') (tail $ tail ps')-          vs    = map (\(a,b,c) -> perp $ tangentOf a b c) bows-          ps'   = start ++ ps ++ end-          start = case ps of-                      x:_ -> [x]-                      _   -> []-          end   = case reverse ps of-                      x:_ -> [x]-                      _   -> []---- | The polyline outline of another polyline drawn at a given thickness.-outlinePolyline :: EndCap -> LineJoin -> Float -> [V2 Float] -> [V2 Float]-outlinePolyline c j t ps = scap ++ ptans ++ ecap ++ reverse ntans ++ h-    where js = joints c j t ps-          (ptans,ntans) = both concat $ unzip $ map tangentPoints js-          both f (a,b) = (f a, f b)-          scap = case js of-                     (Cap _ xs:_) -> reverse xs-                     _            -> []-          ecap = case reverse js of-                     (Cap _ xs:_) -> reverse xs-                     _            -> []--          h = case scap of-                  h':_ -> [h']-                  _    -> []--polyline :: EndCap -> LineJoin -> Float -> [V2 Float] -> [Triangle (V2 Float)]-polyline c j t ps = triangulate $ joints c j t ps--triangulate :: [Joint] -> [Triangle (V2 Float)]--- start-triangulate (j@Cap{}:j':js) = cap ++ arm ++ (triangulate $ j':js)-    where cap   = triangulateCap j-          arm   = triangulateArm j j'--- end-triangulate [j, j'@Cap{}] = arm ++ bow ++ cap-    where arm = triangulateArm j j'-          bow = triangulateElbow j-          cap = triangulateCap j'-triangulate (j:j':js) = arm ++ bow ++ (triangulate $ j':js)-    where arm   = triangulateArm j j'-          bow   = triangulateElbow j-triangulate _ = []---- | Returns the points in a joint separated by the line's winding--- direction. Points on the side of the line in the positive tangent direction--- are `fst` and points in the negative tangent direction are `snd`.-tangentPoints :: Joint -> ([V2 Float], [V2 Float])--- There isn't enough info in a cap to provide this.-tangentPoints (Cap _ _) = ([], [])-tangentPoints (Elbow _ (p,n) []) = ([p],[n])-tangentPoints (Elbow Clockwise (p,_) ps) = ([p],ps)-tangentPoints (Elbow CounterCW (_,n) ps) = (ps,[n])--exitLine :: Joint -> (V2 Float, V2 Float)-exitLine (Cap _ ps) = (head ps, head $ reverse ps)-exitLine (Elbow _ l []) = l-exitLine (Elbow Clockwise (p,_) ps) = (p, head $ reverse ps)-exitLine (Elbow CounterCW (_,n) ps) = (head $ reverse ps, n)--entryLine :: Joint -> (V2 Float, V2 Float)-entryLine (Cap _ ps) = (head $ reverse ps, head ps)-entryLine (Elbow _ l []) = l-entryLine (Elbow Clockwise (p,_) ps) = (p, head ps)-entryLine (Elbow CounterCW (_,n) ps) = (head ps, n)--triangulateElbow :: Joint -> [Triangle (V2 Float)]-triangulateElbow (Elbow Clockwise (p,_) ps) = map (uncurry $ Triangle p) $ zip ps $ tail ps-triangulateElbow (Elbow CounterCW (_,n) ps) = map (uncurry $ Triangle n) $ zip ps $ tail ps-triangulateElbow _ = []--triangulateArm :: Joint -> Joint -> [Triangle (V2 Float)]-triangulateArm j j' = [Triangle a b c, Triangle b c d]-    where (a,b) = exitLine j-          (c,d) = entryLine j'--triangulateCap :: Joint -> [Triangle (V2 Float)]--- This is a butt cap so do nothing.-triangulateCap (Cap p ps) = map (uncurry $ Triangle p) $ zip ps $ tail ps-triangulateCap _ = []--joints :: EndCap -> LineJoin -> Float -> [V2 Float] -> [Joint]-joints _ _ _ [] = []-joints _ _ _ [_] = []-joints c j t ps@(a:b:_) = start : mid ++ [end]-    where start = capFunc c t a b-          end   = capFunc c t z y-          mid   = miters j t ps-          [z,y] = take 2 $ reverse ps--capFunc :: EndCap -> Float -> V2 Float -> V2 Float -> Joint-capFunc EndCapButt t a b = Cap a [lp,hp]-    where (lp,hp) = miterLine (capJoin t a b) a-capFunc EndCapBevel t a b = Cap a [lp,p,hp]-    where (lp,hp) = miterLine (capJoin t a b) a-          p       = a + (signorm $ a - b) ^* t-capFunc EndCapSquare t a b = Cap a [lp,p'',p',hp]-    where (lp,hp) = miterLine (capJoin t a b) a-          p       = a + (signorm $ a - b) ^* t-          p'      = p + ((signorm $ hp - a) ^* t)-          p''     = p + ((signorm $ lp - a) ^* t)-capFunc EndCapRound t a b = Cap a ps-    where ps     = map f [(pi/2) + r + (d * pi/180) | d <- [0..180]]-          V2 x y = signorm $ b - a-          r      = atan2 y x-          f th   = a + (V2 (cos th) (sin th) ^* t)--miters :: LineJoin -> Float -> [V2 Float] -> [Joint]-miters j t (a:b:c:ps) = miterFunc j t a b c : (miters j t $ b:c:ps)-miters _ _ _ = []--miterFunc :: LineJoin -> Float -> V2 Float -> V2 Float -> V2 Float -> Joint-miterFunc LineJoinMiter = miterJoint-miterFunc LineJoinBevel = bevelJoint---miterFunc LineJoinRound = roundJoint------roundJoint :: Float -> V2 Float -> V2 Float -> V2 Float -> Joint---roundJoint t a b c =---    if triangleArea a b c > 0---    then Elbow Clockwise (p,n) ps---    else Elbow CounterCW (p,n) $ reverse ps---    where j       = join t a b c---          (p,n)   = miterLine j b---          v'      = t *^ (perp ab)---          v''     = t *^ (perp bc)---          ps     = map f [r + d | d <- [0, pi/2, pi]]---          V2 x y = signorm $ v'' - v'---          r      = atan2 y x---          f th   = b + (V2 (cos th) (sin th) ^* (0.5 * distance v'' v'))---          ab     = signorm $ b - a---          bc     = signorm $ c - b--bevelJoint :: Float -> V2 Float -> V2 Float -> V2 Float -> Joint-bevelJoint t a b c =-    if triangleArea a b c >= 0-    then Elbow Clockwise (p,n) [b - v', b - v'']-    else Elbow CounterCW (p,n) [b + v', b + v'']-    where j       = join t a b c-          (p,n) = miterLine j b-          v'      = t *^ (perp ab)-          v''     = t *^ (perp bc)-          ab      = signorm $ b - a-          bc      = signorm $ c - b--miterJoint :: Float -> V2 Float -> V2 Float -> V2 Float -> Joint-miterJoint t a b c =-    if triangleArea a b c >= 0-    then Elbow Clockwise (ptan,ntan) []-    else Elbow CounterCW (ptan,ntan) []-    where j = join t a b c-          (ptan,ntan) = miterLine j b---- | Finds the miter line through a midpoint for a given join.-miterLine :: Join -> V2 Float -> (V2 Float, V2 Float)-miterLine (Join v l) p = (ptan,ntan)-    -- ptan is the point on the miterline in the direction the-    -- perpendicular tangent is pointing. ntan is in the opposite-    -- direction. This means that for clockwise winding elbows ptan-    -- will lie within the bend, on the inside of the elbow, while-    -- ntan will lie outside. This is reversed for elbows winding-    -- counter-clockwise.-    where ptan = p + v'-          ntan = p - v'-          v'   = (v ^* l)---- | Finds the joint of three points with a thickness.--- A join with a positive angle denotes an elbow that bends--- counter-clockwise. A join with a negative angle denotes an elbow that--- bends clockwise.--- The join with an angle == 0 is the join of two parallel lines.--- The join with an angle == pi is the join of two opposite but parallel--- lines, which is used to denote a line cap.-join :: Float -> V2 Float -> V2 Float -> V2 Float -> Join-join t a b c = Join v ln-    where tgnt = tangentOf a b c-          v = perp tgnt-          ln = min d $ t / (v `dot` n)-          n = signorm $ perp $ b - a-          d = min (distance (c - b) zero) (distance (b - a) zero)---- | Finds the join of a start or end line with a thickness.-capJoin :: Float -> V2 Float -> V2 Float -> Join-capJoin t a b = Join v t-    where v = signorm $ perp $ b - a---- | Finds the tangent of an elbow.-tangentOf :: V2 Float -> V2 Float -> V2 Float -> V2 Float-tangentOf a b c = signorm $ (signorm l2) + (signorm l1)-    where l1 = b - a-          l2 = c - b---- | Finds the angle between two vectors.-angleBetween :: V2 Float -> V2 Float -> Float-angleBetween v1 v2 = a - b-    where V2 x1 y1 = signorm v1-          V2 x2 y2 = signorm v2-          a = atan2 y1 x1-          b = atan2 y2 x2---- | A join is the 'miter line' that runs through the shared point of two lines--- perpendicular to their tangent.-data Join = Join { joinVector :: V2 Float-                 , joinLength :: Float-                 } deriving (Show, Eq)
− src/Gelatin/Core/Rendering/Types.hs
@@ -1,168 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-module Gelatin.Core.Rendering.Types (-    Resources(..),-    runRendering,-    cleanRendering,-    Rendering(..),-    RenderDef(..),-    RenderSource(..),-    GeomRenderSource(..),-    BezRenderSource(..),-    MaskRenderSource(..),-    Transform(..),-    UniformUpdates(..),-    ClippingArea,-    Point(..),-    Line(..),-    Bezier(..),-    Triangle(..),-    FontString(..),-    EndCap(..),-    LineJoin(..),-    Joint(..),-    Winding(..),-    Fill(..),-    FillResult(..)-) where--import Linear as J hiding (rotate)-import Prelude hiding (init)-import Graphics.UI.GLFW-import Graphics.GL.Types-import Graphics.Text.TrueType hiding (CompositeScaling(..))-import Data.Time.Clock-import Data.Typeable-import Data.ByteString.Char8 (ByteString)-import Control.Concurrent.Async-import Data.IntMap (IntMap)-import Data.Map (Map)------------------------------------------------------------------------------------- Text----------------------------------------------------------------------------------data FontString = FontString Font Float (Float,Float) String------------------------------------------------------------------------------------ Coloring----------------------------------------------------------------------------------data Fill = FillColor (V2 Float -> V4 Float)-          | FillTexture FilePath (V2 Float -> V2 Float)--data FillResult = FillResultColor [V4 Float]-                | FillResultTexture GLuint [V2 Float]------------------------------------------------------------------------------------ Polylines----------------------------------------------------------------------------------data LineJoin = LineJoinMiter-              | LineJoinBevel-              deriving (Show, Eq)-data EndCap = EndCapButt-            | EndCapBevel-            | EndCapSquare-            | EndCapRound-            deriving (Show, Eq)-data Winding = Clockwise-             | CounterCW-             deriving (Show, Eq)-data Joint = Cap (V2 Float) [V2 Float]-           | Elbow Winding (V2 Float, V2 Float) [V2 Float]-           deriving (Show, Eq)------------------------------------------------------------------------------------ Drawing Primitives----------------------------------------------------------------------------------data Primitive a = PrimitiveBez (Bezier a)-                 | PrimitiveTri (Triangle a)-                 deriving (Show, Eq)--instance Functor Triangle where-    fmap f (Triangle a b c) = Triangle (f a ) (f b) (f c)--instance Functor Bezier where-    fmap f (Bezier o a b c) = Bezier o (f a) (f b) (f c)--instance Functor Line where-    fmap f (Line a b) = Line (f a) (f b)--instance Functor Point where-    fmap f (Point v) = Point $ f v--data Bezier a = Bezier Ordering a a a deriving (Show, Eq)-data Triangle a = Triangle a a a deriving (Show, Eq)-data Line a = Line a a deriving (Show, Eq)-data Point a = Point a------------------------------------------------------------------------------------ Application Resources----------------------------------------------------------------------------------data Resources = Resources { rsrcFonts     :: Async FontCache-                           , rsrcRenderings :: RenderCache-                           , rsrcSources   :: RenderSources-                           , rsrcWindow    :: Window-                           , rsrcDpi       :: Dpi-                           , rsrcUTC       :: UTCTime-                           } deriving (Typeable)------------------------------------------------------------------------------------ Special Rendering----------------------------------------------------------------------------------type ClippingArea = (V2 Int, V2 Int)------------------------------------------------------------------------------------ General Rendering----------------------------------------------------------------------------------type RenderCache = IntMap Rendering--runRendering :: Transform -> Rendering -> IO ()-runRendering t (Rendering f _) = f t--cleanRendering :: Rendering -> IO ()-cleanRendering (Rendering _ c) = c--instance Monoid Rendering where-    mempty = Rendering (const $ return ()) (return ())-    (Rendering ar ac) `mappend` (Rendering br bc) =-        Rendering (\t -> ar t >> br t) (ac >> bc)--data Rendering = Rendering RenderFunction CleanupFunction-type RenderFunction = Transform -> IO ()--type CleanupFunction = IO ()--data GeomRenderSource = GRS RenderSource-data BezRenderSource = BRS RenderSource-data MaskRenderSource = MRS RenderSource-type RenderSources = Map RenderDef RenderSource--data RenderSource = RenderSource { rsProgram    :: ShaderProgram-                                 , rsAttributes :: [(String, GLint)]-                                 } deriving (Show)--data RenderDef = RenderDefFP { rdShaderPaths :: [(String, GLuint)]-                             -- ^ [("path/to/shader.vert", GL_VERTEX_SHADER)]-                             , rdUniforms :: [String]-                             -- ^ ["projection", "modelview", ..]-                             }-               | RenderDefBS { rdShaderSrcs :: [(ByteString, GLuint)]-                             , rdUniforms :: [String]-                             } deriving (Show, Eq, Ord)------------------------------------------------------------------------------------ Affine Transformation----------------------------------------------------------------------------------instance Monoid Transform where-    mempty = Transform zero (V2 1 1) 0-    (Transform t1 s1 r1) `mappend` (Transform t2 s2 r2) = Transform (t1 + t2) (s1 * s2) (r1 + r2)--data Transform = Transform { tfrmTranslation :: Position-                           , tfrmScale       :: Scale-                           , tfrmRotation    :: Rotation-                           } deriving (Show, Typeable)--type Position = V2 Float-type Scale = V2 Float-type Rotation = Float------------------------------------------------------------------------------------ OpenGL----------------------------------------------------------------------------------type ShaderProgram = GLuint--data UniformUpdates = UniformUpdates { uuProjection :: Maybe GLint-                                     , uuModelview  :: Maybe GLint-                                     , uuSampler    :: (GLint, GLint)-                                     , uuHasUV      :: (GLint, GLint)-                                     }
− src/Gelatin/Core/Shader.hs
@@ -1,115 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-}-module Gelatin.Core.Shader (-    positionLoc,-    colorLoc,-    uvLoc,-    bezLoc,-    compileShader,-    compileProgram,-    vertSourceGeom,-    fragSourceGeom,-    vertSourceBezier,-    fragSourceBezier,-    vertSourceMask,-    fragSourceMask-) where--import Prelude hiding (init)-import Prelude as P-import Graphics.GL.Core33-import Graphics.GL.Types-import Control.Monad-import System.Exit-import Foreign.Ptr-import Foreign.C.String-import Foreign.Marshal.Array-import Foreign.Marshal.Utils-import Foreign.Storable-import Data.ByteString.Char8 as B-import Data.FileEmbed--positionLoc :: GLuint-positionLoc = 0--colorLoc :: GLuint-colorLoc = 1--uvLoc :: GLuint-uvLoc = 2--bezLoc :: GLuint-bezLoc = 3--compileShader :: ByteString -> GLuint -> IO GLuint-compileShader src sh = do-    shader <- glCreateShader sh-    when (shader == 0) $ do-        B.putStrLn "could not create shader"-        exitFailure--    withCString (B.unpack src) $ \ptr ->-       with ptr $ \ptrptr -> glShaderSource shader 1 ptrptr nullPtr--    glCompileShader shader-    success <- with (0 :: GLint) $ \ptr -> do-        glGetShaderiv shader GL_COMPILE_STATUS ptr-        peek ptr--    when (success == GL_FALSE) $ do-        B.putStrLn "could not compile shader:\n"-        B.putStrLn src-        infoLog <- with (0 :: GLint) $ \ptr -> do-            glGetShaderiv shader GL_INFO_LOG_LENGTH ptr-            logsize <- peek ptr-            allocaArray (fromIntegral logsize) $ \logptr -> do-                glGetShaderInfoLog shader logsize nullPtr logptr-                peekArray (fromIntegral logsize) logptr-        P.putStrLn $ P.map (toEnum . fromEnum) infoLog-        exitFailure--    return shader--compileProgram :: [GLuint] -> IO GLuint-compileProgram shaders = do-    program <- glCreateProgram--    forM_ shaders (glAttachShader program)-    glLinkProgram program--    success <- with (0 :: GLint) $ \ptr -> do-        glGetProgramiv program GL_LINK_STATUS ptr-        peek ptr--    when (success == GL_FALSE) $ do-        B.putStrLn "could not link program"-        infoLog <- with (0 :: GLint) $ \ptr -> do-            glGetProgramiv program GL_INFO_LOG_LENGTH ptr-            logsize <- peek ptr-            allocaArray (fromIntegral logsize) $ \logptr -> do-                glGetProgramInfoLog program logsize nullPtr logptr-                peekArray (fromIntegral logsize) logptr-        P.putStrLn $ P.map (toEnum . fromEnum) infoLog-        exitFailure--    forM_ shaders glDeleteShader-    return program---vertSourceGeom :: ByteString-vertSourceGeom = $(embedFile "shaders/2d.vert")--fragSourceGeom :: ByteString-fragSourceGeom = $(embedFile "shaders/2d.frag")--vertSourceBezier :: ByteString-vertSourceBezier = $(embedFile "shaders/bezier.vert")--fragSourceBezier :: ByteString-fragSourceBezier = $(embedFile "shaders/bezier.frag")--vertSourceMask :: ByteString-vertSourceMask = $(embedFile "shaders/mask.vert")--fragSourceMask :: ByteString-fragSourceMask = $(embedFile "shaders/mask.frag")
+ src/Gelatin/Core/Stroke.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE DeriveGeneric #-}+-- | Strokes are used for defining lines and drawing them.+module Gelatin.Core.Stroke where++import           Data.Maybe   (fromMaybe)+import           GHC.Generics (Generic)++data LineCap = LineCapNone+             | LineCapButt+             | LineCapSquare+             | LineCapRound+             | LineCapTriOut+             | LineCapTriIn+             deriving (Show, Ord, Eq, Enum, Generic)++data Stroke = Stroke { strokeWidth    :: Float+                     , strokeFeather  :: Float+                     , strokeLineCaps :: (LineCap,LineCap)+                     } deriving (Show, Eq, Generic)++data StrokeAttr = StrokeNone+                | StrokeWidth Float+                | StrokeFeather Float+                | StrokeCaps (LineCap,LineCap)+                deriving (Show, Eq, Generic)++defaultStroke :: Stroke+defaultStroke = Stroke 1 1 (LineCapRound,LineCapRound)++strokeAttr :: Maybe Stroke -> StrokeAttr -> Maybe Stroke+strokeAttr _ StrokeNone               = Nothing+strokeAttr Nothing c                  = strokeAttr (Just defaultStroke) c+strokeAttr (Just s) (StrokeWidth w)   = Just $ s {strokeWidth = w}+strokeAttr (Just s) (StrokeFeather t) = Just $ s {strokeFeather = t}+strokeAttr (Just s) (StrokeCaps cs)   = Just $ s {strokeLineCaps = cs}++strokeWith :: [StrokeAttr] -> Stroke+strokeWith atts = fromMaybe defaultStroke $ foldl strokeAttr Nothing atts
+ src/Gelatin/Core/Transform.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+-- | Limited spatial transformations in 2 and 3 dimensions.+module Gelatin.Core.Transform where++import           Data.Foldable (foldl')+import           Linear        (Epsilon (..), M44, V1 (..), V2 (..),+                                V3 (..), V4 (..), axisAngle, identity,+                                mkTransformation, mkTransformationMat, (!*!))+--------------------------------------------------------------------------------+-- Affine Transformation+--------------------------------------------------------------------------------+data Affine a r = Translate a+                | Scale a+                | Rotate r+                deriving (Show, Eq)++type Affine2 a = Affine (V2 a) a++type Affine3 a = Affine (V3 a) (a, V3 a)++-- | Promotes a point in R2 to a point in R3 by setting the z coord to '0'.+promoteV2 :: Num a => V2 a -> V3 a+promoteV2 (V2 x y) = V3 x y 0++-- | Demotes a point in R3 to a point in R2 by discarding the z coord.+demoteV3 :: V3 a -> V2 a+demoteV3 (V3 x y _) = V2 x y++-- | Promotes an affine transformation in R2 to one in R3 by using `promoteV2`+-- in case of translation or scaling, and promotes rotation as a rotation about+-- the z axis.+promoteAffine2 :: Num a => Affine2 a -> Affine3 a+promoteAffine2 (Translate v2) = Translate $ promoteV2 v2+promoteAffine2 (Scale v2)     = Scale $ promoteV2 v2+promoteAffine2 (Rotate r)     = Rotate (r, V3 0 0 1)++affine3Modelview :: (Num a, Real a, Floating a, Epsilon a)+                 => Affine3 a -> M44 a+affine3Modelview (Translate v)     = mat4Translate v+affine3Modelview (Scale v)         = mat4Scale v+affine3Modelview (Rotate (r,axis)) = mat4Rotate r axis++affine2Modelview :: (Num a, Real a, Floating a, Epsilon a)+                 => Affine2 a -> M44 a+affine2Modelview = affine3Modelview . promoteAffine2++affine2sModelview :: (Num a, Real a, Floating a, Epsilon a)+                => [Affine2 a] -> M44 a+affine2sModelview = foldl' f identity+    where f mv a = (mv !*!) $ affine2Modelview a++transformV2 :: Num a => M44 a -> V2 a ->  V2 a+transformV2 mv = demoteV3 . m41ToV3 . (mv !*!) . v3ToM41 . promoteV2++transformPoly :: M44 Float -> [V2 Float] -> [V2 Float]+transformPoly t = map (transformV2 t)++transformV3 :: RealFloat a => M44 a -> V3 a -> V3 a+transformV3 t v = m41ToV3 $ t !*! v3ToM41 v++v3ToM41 :: Num a => V3 a -> V4 (V1 a)+v3ToM41 (V3 x y z) = V4 (V1 x) (V1 y) (V1 z) (V1 1)++m41ToV3 :: V4 (V1 a) -> V3 a+m41ToV3 (V4 (V1 x) (V1 y) (V1 z) _) = V3 x y z++rotateAbout :: (Num a, Epsilon a, Floating a) => V3 a -> a -> V3 a -> V3 a+rotateAbout axis phi = m41ToV3 . (mat4Rotate phi axis !*!) . v3ToM41+--------------------------------------------------------------------------------+-- Matrix helpers+--------------------------------------------------------------------------------+mat4Translate :: Num a => V3 a -> M44 a+mat4Translate = mkTransformationMat identity++mat4Rotate :: (Num a, Epsilon a, Floating a) => a -> V3 a -> M44 a+mat4Rotate phi v = mkTransformation (axisAngle v phi) (V3 0 0 0)++mat4Scale :: Num a => V3 a -> M44 a+mat4Scale (V3 x y z) =+    V4 (V4 x 0 0 0)+       (V4 0 y 0 0)+       (V4 0 0 z 0)+       (V4 0 0 0 1)
+ src/Gelatin/Core/Triangle.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies          #-}+module Gelatin.Core.Triangle where++import           Data.Vector.Unboxed (Unbox, Vector)+import qualified Data.Vector.Unboxed as V+import           Gelatin.Core.Bezier+import           Gelatin.Core.Bounds+import           Linear++type Triangle a = (a,a,a)++trisToComp :: Unbox a => Vector (Triangle (V2 a)) -> Vector (V2 a)+trisToComp = V.concatMap triPoints++triPoints :: Unbox a => Triangle (V2 a) -> Vector (V2 a)+triPoints (a,b,c) = V.fromList [a, b, c]++bezToTri :: Bezier a -> Triangle a+bezToTri (_,a,b,c) = (a,b,c)++triToPath :: Unbox a => Triangle a -> Vector a+triToPath (a,b,c) = V.fromList [a,b,c]++fmapTriangle :: (t -> t1) -> (t, t, t) -> (t1, t1, t1)+fmapTriangle f (a,b,c) = (f a, f b, f c)++triBounds :: Triangle (V2 Float) -> BBox+triBounds (a,b,c) = boundingBox $ V.fromList [a,b,c]+--------------------------------------------------------------------------------+-- Decomposing things into triangles+--------------------------------------------------------------------------------+sizeToTris :: V2 Float -> Vector (Triangle (V2 Float))+sizeToTris (V2 w h) = V.fromList [(a,b,c), (a,c,d)]+    where [a,b,c,d] = [V2 (-hw) (-hh), V2 hw (-hh), V2 hw hh, V2 (-hw) hh]+          (hw,hh) = (w/2,h/2)
− src/Gelatin/Core/Triangulation/Common.hs
@@ -1,61 +0,0 @@-module Gelatin.Core.Triangulation.Common where--import Linear-import Control.Lens--type Poly = [V2 Float]--signedArea :: Num a => [V2 a] -> a-signedArea = signedAreaOfPoints--signedAreaOfPoints :: Num a => [V2 a] -> a-signedAreaOfPoints lst =-  sum [x1 * y2 - x2 * y1 | (V2 x1 y1, V2 x2 y2) <- zip lst $ rotateLeft lst]--rotateLeft :: [a] -> [a]-rotateLeft [] = []-rotateLeft (x:xs) = xs ++ [x]---- | returns True iff the first point of the first polygon is inside the second poylgon-insidePoly :: Poly -> Poly -> Bool-insidePoly poly1 poly2 | null poly1 = False-                       | null poly2 = False-                       | otherwise  = and $ map (`pointInside` poly2) poly1---- | A point is inside a polygon if it has an odd number of intersections with the boundary (Jordan Curve theorem)-pointInside :: (V2 Float) -> Poly -> Bool-pointInside = flip pathHasPoint---- | Determine if a point lies within a polygon path using the even/odd--- rule.-pathHasPoint :: (R1 f, R2 f, Ord a, Fractional a) => [f a] -> f a -> Bool-pathHasPoint [] _ = False-pathHasPoint poly@(p1':_) p' = pointInPath' False p' (poly ++ [p1'])-    where pointInPath' :: (R1 f, R2 f, Ord a, Fractional a) => Bool -> f a -> [f a] -> Bool-          pointInPath' c _ []  = c-          pointInPath' c _ [_] = c-          pointInPath' c p (p1:p2:ps) = pointInPath' (test p p1 p2 $ c) p (p2:ps)-          test :: (R2 f, Ord a, Fractional a) => f a -> f a -> f a -> (Bool -> Bool)-          test p p1 p2 = if t1 p p1 p2 && t2 p p1 p2 then not else id-          t1 :: (R2 f, Ord a) => f a -> f a -> f a -> Bool-          t1 p p1 p2 = (y p2 > y p) /= (y p1 > y p)-          t2 :: (R1 f, R2 f, Ord a, Fractional a) => f a -> f a -> f a -> Bool-          t2 p p1 p2 = x p < (x p1 - x p2) * (y p - y p2) / (y p1 - y p2) + x p2-          x v = v ^. _x-          y v = v ^. _y----- |return a list containing lists of every element with its neighbour--- i.e. [e1,e2,e3] -> [ [e1,e2], [e2,e3], [e3, e1] ]-cycleNeighbours :: [a] -> [[a]]-cycleNeighbours xs | null xs = []-                   | otherwise = cycleN (head xs) xs--cycleN :: a -> [a] -> [[a]]-cycleN f xs | length xs >= 2 = cons ([head xs, head (tail xs)]) (cycleN f (tail xs))-            | otherwise      = [[head xs, f]] -- if the upper doesn't match close cycle---triangleArea :: Fractional a => V2 a -> V2 a -> V2 a -> a-triangleArea (V2 x2 y2) (V2 x0 y0) (V2 x1 y1) = (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)-
− src/Gelatin/Core/Triangulation/EarClipping.hs
@@ -1,35 +0,0 @@-module Gelatin.Core.Triangulation.EarClipping where--import Gelatin.Core.Rendering.Types-import Gelatin.Core.Triangulation.Common-import Linear--triangulate :: [V2 Float] -> [Triangle (V2 Float)]-triangulate ps = triangulate' [] $ clean ps-    where triangulate' ts ps'-              | (p1:p2:p3:[]) <- ps' = Triangle p1 p2 p3 :ts-              | (p1:p2:p3:rest) <- ps' =-                  let isReflex = area p1 p2 p3 >= 0-                  in if isReflex && (not $ any (`pointInside` [p1,p2,p3]) rest)-                     then triangulate' (ts ++ [Triangle p1 p2 p3]) $ p1:p3:rest-                     -- Cycle through and check the next triangle-                     else triangulate' ts $ p2:p3:rest ++ [p1]-              | otherwise = ts-          clean = removeHeadTail . removeColinears--removeHeadTail :: Eq a => [a] -> [a]-removeHeadTail [] = []-removeHeadTail xs = if head xs == last xs then Prelude.init xs else xs--removeColinears :: (Fractional a, Eq a) => [V2 a] -> [V2 a]-removeColinears (a:b:c:ds) = if area a b c == 0-                             then a: (removeColinears $ c:ds)-                             else a:b: (removeColinears $ c:ds)-removeColinears vs = vs--area :: Fractional a => V2 a -> V2 a -> V2 a -> a-area (V2 ax ay) (V2 bx by) (V2 cx cy) =-    0.5 * det33 (V3 (V3 ax ay 1)-                    (V3 bx by 1)-                    (V3 cx cy 1))-
− src/Gelatin/Core/Triangulation/KET.hs
@@ -1,77 +0,0 @@--- |--- Module    : Triangulation.KET--- Copyright :(C) 1997, 1998, 2008 Joern Dinkla, www.dinkla.net------ Updates by Schell Scivally------ Triangulation of simple polygons after Kong, Everett, Toussaint 91--- with some changes by T.Vogt: return indices instead of coordinates of triangles and Data.Vector instead of lists------ see---     Joern Dinkla, Geometrische Algorithmen in Haskell, Diploma Thesis,---     University of Bonn, Germany, 1998.-{-# OPTIONS_GHC -fno-warn-missing-signatures #-}-module Gelatin.Core.Triangulation.KET (triangulate) where--import Linear-import Data.Vector (Vector)-import qualified Data.Vector as V-import Data.List ( (\\) )--type V2i = (V2 Float,Int)--toV2 = V.map (\(x,_) -> x)--triangulate :: RealFrac a => [V2 a] -> [(V2 a, V2 a, V2 a)]-triangulate vs = map (\(a,b,c) -> ((vec' V.! a), (vec' V.! b), (vec' V.! c))) ndxs-    where vec' = V.map (fmap realToFrac) vec-          vec  = V.fromList $ map (fmap realToFrac) vs-          ndxs = triangulation vec--triangulation :: Vector (V2 Float) -> [(Int,Int,Int)]-triangulation points | (V.length vertices) > 3 = scan vs stack rs-              | otherwise = []-  where vertices = V.zip points (V.generate (V.length points) id)-        [p1,p2,p3] = V.toList (V.take 3 vertices)-        qs         = V.drop 3 vertices-        vs         = qs V.++ (V.singleton p1)-        stack      = V.fromList [p3, p2, p1, V.last vertices]-        rs         = reflexVertices (angles vertices)--scan :: Vector V2i -> Vector V2i -> Vector V2i -> [(Int,Int,Int)]-scan vs stack rs | V.null vs            = []-                 | V.length vs == 1     = [(snd (V.head stack), snd (V.head (V.tail stack)), snd (V.head vs))]-                 | V.length stack == 3  = scan (V.tail vs) (V.cons (V.head vs) stack) rs-                 | isEar rs x_m x_i x_p = (snd x_p, snd x_i, snd x_m) : (scan vs (V.cons x_p ss') rs')-                 | otherwise            = scan (V.tail vs) (V.cons (V.head vs) stack) rs-  where [x_p, x_i, x_m] = V.toList (V.take 3 stack)-        ss' = V.drop 2 stack-        rs'   = V.fromList $ (V.toList rs) \\ (isConvex x_m x_p (V.head vs) ++-                                               isConvex (V.head (V.tail ss')) x_m x_p)-        isConvex (im,_) (i,ii) (ip,_) = if isLeftTurn im i ip then [(i,ii)] else []--isEar :: Vector V2i -> V2i -> V2i -> V2i -> Bool-isEar rs (m,_) (x,_) (p,_) | V.null rs = True-                           | otherwise = isLeftTurn m x p && not (V.any ( (m,x,p) `containsBNV`) (toV2 rs))--reflexVertices  :: Vector (V2i,V2i,V2i) -> Vector V2i-reflexVertices as | V.null as             = V.empty-                  | isRightTurnOrOn m x p = V.cons (x,xi) $ reflexVertices (V.tail as)-                  | otherwise             =                 reflexVertices (V.tail as)-  where ((m,_),(x,xi),(p,_)) = V.head as--containsBNV (s,t,v) p    = (a==b && b==c)-  where a                = isLeftTurn s t p-        b                = isLeftTurn t v p-        c                = isLeftTurn v s p--angles :: Vector a -> Vector (a,a,a)-angles xs = V.zip3 (rotateR xs) xs (rotateL xs)--rotateL xs = (V.tail xs) V.++ (V.singleton (V.head xs))-rotateR xs = (V.singleton (V.last xs)) V.++ (V.init xs)--isRightTurnOrOn m x p = (area2 m x p) <= 0-isLeftTurn :: (V2 Float) -> (V2 Float) -> (V2 Float) -> Bool-isLeftTurn      m x p = (area2 m x p) > 0-area2 (V2 x2 y2) (V2 x0 y0) (V2 x1 y1) = (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)
+ src/Gelatin/Core/Utils.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies          #-}+module Gelatin.Core.Utils where++import           Data.Vector.Unboxed (Unbox, Vector)+import qualified Data.Vector.Unboxed as V+import           Linear++-- | Determine if a point lies within a polygon path using the even/odd+-- rule.+-- A point is inside a path if it has an odd number of intersections with+-- the boundary (Jordan Curve theorem)+pathHasPoint :: (Ord a, Fractional a, Unbox a) => Vector (V2 a) -> V2 a -> Bool+pathHasPoint vs v = V.foldr' (\s a -> if s then not a else a) False $+  V.zipWith3 f vv vs (V.drop 1 vs)+  where vv = V.replicate (V.length vs) v+        f a b c = t1 a b c && t2 a b c+        t1 p p1 p2 = (y p2 > y p) /= (y p1 > y p)+        t2 p p1 p2 = x p < (x p1 - x p2) * (y p - y p2) / (y p1 - y p2) + x p2+        x (V2 a _) = a+        y (V2 _ b) = b
+ src/Gelatin/Picture.hs view
@@ -0,0 +1,59 @@+module Gelatin.Picture (+  -- * Defining Vertex Data+    VerticesT(..)+  , runVerticesT+  , Vertices+  , runVertices+  , tri+  , bez+  , to+  , addVertexList+  , segment+  , mapVertices+  -- * Making shapes+  , module S+  -- * Defining Geometry (Vertex Data + Drawing Operation)+  , RawGeometry(..)+  , mapRawGeometry+  , GeometryT(..)+  , runGeometryT+  , Geometry+  , runGeometry+  , triangles+  , beziers+  , strip+  , fan+  , line+  , mapGeometry+  -- * The Picture API+  , PictureT+  , runPictureT+  , Picture+  , runPicture+  , setRawGeometry+  , getRawGeometry+  , setGeometry+  , setStroke+  , getStroke+  , setTextures+  , getTextures+  , setRenderingOptions+  , getRenderingOptions+  -- * Measuring Pictures (2d)+  , mapToSpaceVec+  , pictureBounds2+  , pictureSize2+  , pictureOrigin2+  , pictureCenter2+  -- * Measuring Pictures (3d)+  , pictureBounds3+  , pictureSize3+  , pictureOrigin3+  , pictureCenter3+  -- * Underlying PictureData Exported for renderers+  , RenderingOption(..)+  , PictureData(..)+) where++import           Gelatin.Picture.Internal+import           Gelatin.Picture.Shapes   as S
+ src/Gelatin/Picture/Internal.hs view
@@ -0,0 +1,279 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE GADTs                #-}+{-# LANGUAGE LambdaCase           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE TupleSections        #-}+{-# LANGUAGE TypeSynonymInstances #-}+module Gelatin.Picture.Internal where++import           Control.Arrow+import           Control.Lens               hiding (to)+import           Control.Monad.IO.Class+import           Control.Monad.State.Strict+import qualified Data.Vector                as B+import           Data.Vector.Unboxed        (Unbox, Vector)+import qualified Data.Vector.Unboxed        as V+import           Gelatin.Core+import           Linear                     hiding (rotate)++--------------------------------------------------------------------------------+-- A Monad for defining vertex data+--------------------------------------------------------------------------------+newtype VerticesT a m b = Vertices { unVertices :: StateT (Vector a) m b }+type Vertices a = VerticesT a Identity ()++instance Functor m => Functor (VerticesT a m) where+  fmap f (Vertices s) = Vertices $ fmap f s++instance Monad m => Applicative (VerticesT a m) where+  pure = Vertices . pure+  (Vertices f) <*> (Vertices x) = Vertices $ f <*> x++instance Monad m => Monad (VerticesT a m) where+  return = pure+  (Vertices m) >>= f = Vertices $ m >>= unVertices . f++instance MonadTrans (VerticesT a) where+  lift = Vertices . lift++instance MonadIO m => MonadIO (VerticesT a m) where+  liftIO = lift . liftIO+--------------------------------------------------------------------------------+-- Pretty General Operators+--------------------------------------------------------------------------------+snoc3 :: Unbox a => Vector a -> a -> a -> a -> Vector a+snoc3 v a b = V.snoc (V.snoc (V.snoc v a) b)++tri :: (Monad m, Unbox a) => a -> a -> a -> VerticesT a m ()+tri a b c = Vertices $ modify $ \v -> snoc3 v a b c++bez :: (Monad m, Unbox a) => a -> a -> a -> VerticesT a m ()+bez = tri++to :: (Monad m, Unbox a) => a -> VerticesT a m ()+to = Vertices . modify . flip V.snoc++segment :: (Monad m, Unbox a) => a -> a -> VerticesT a m ()+segment a b = to a >> to b++addVertexList :: (Monad m, Unbox a) => [a] -> VerticesT a m ()+addVertexList ys = Vertices $ do+  xs <- get+  put $ xs V.++ V.fromList ys++runVerticesT :: (Monad m, Unbox a) => VerticesT a m b -> m (Vector a)+runVerticesT = flip execStateT V.empty . unVertices++runVertices :: Unbox a => Vertices a -> Vector a+runVertices = runIdentity . runVerticesT++mapVertices :: (Monad m, Unbox a, Unbox c)+            => (a -> c) -> VerticesT a m b -> VerticesT c m ()+mapVertices f s = Vertices $ do+  vs <- lift $ runVerticesT s+  put $ V.map f vs+--------------------------------------------------------------------------------+-- Mixing drawing types and transforming them+--------------------------------------------------------------------------------+data RawGeometry a = RawTriangles (Vector a)+                   | RawBeziers (Vector a)+                   | RawTriangleStrip (Vector a)+                   | RawTriangleFan (Vector a)+                   | RawLine (Vector a)++mapRawGeometry :: (Unbox a, Unbox b) => (a -> b) -> RawGeometry a -> RawGeometry b+mapRawGeometry f (RawTriangles vs)     = RawTriangles $ V.map f vs+mapRawGeometry f (RawBeziers vs)       = RawBeziers $ V.map f vs+mapRawGeometry f (RawTriangleStrip vs) = RawTriangleStrip $ V.map f vs+mapRawGeometry f (RawTriangleFan vs)   = RawTriangleFan $ V.map f vs+mapRawGeometry f (RawLine vs)          = RawLine $ V.map f vs+--------------------------------------------------------------------------------+-- A Monad for defining geometry+--------------------------------------------------------------------------------+newtype GeometryT a m b =+  Geometry { unGeometry :: StateT (B.Vector (RawGeometry a)) m b}+type Geometry a = GeometryT a Identity ()++instance Functor m => Functor (GeometryT a m) where+  fmap f (Geometry s) = Geometry $ fmap f s++instance Monad m => Applicative (GeometryT a m) where+  pure = Geometry . pure+  (Geometry f) <*> (Geometry x) = Geometry $ f <*> x++instance Monad m => Monad (GeometryT a m) where+  return = pure+  (Geometry m) >>= f = Geometry $ m >>= unGeometry . f++instance MonadTrans (GeometryT a) where+  lift = Geometry . lift++instance MonadIO m => MonadIO (GeometryT a m) where+  liftIO = lift . liftIO++add :: Monad m => RawGeometry a -> StateT (B.Vector (RawGeometry a)) m ()+add a = modify (`B.snoc` a)++triangles :: (Unbox a, Monad m) => VerticesT a m () -> GeometryT a m ()+triangles vs = Geometry $ do+  v <- lift $ runVerticesT vs+  add $ RawTriangles v++beziers :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()+beziers vs = Geometry $ do+  v <- lift $ runVerticesT vs+  add $ RawBeziers v++strip :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()+strip vs = Geometry $ do+  v <- lift $ runVerticesT vs+  add $ RawTriangleStrip v++fan :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()+fan vs = Geometry $ do+  v <- lift $ runVerticesT vs+  add $ RawTriangleFan v++line :: (Monad m, Unbox a) => VerticesT a m () -> GeometryT a m ()+line vs = Geometry $ do+  v <- lift $ runVerticesT vs+  add $ RawLine v++runGeometryT :: Monad m => GeometryT a m b -> m (B.Vector (RawGeometry a))+runGeometryT = flip execStateT B.empty . unGeometry++runGeometry :: Geometry a -> B.Vector (RawGeometry a)+runGeometry = runIdentity . runGeometryT++mapGeometry :: (Monad m, Unbox a, Unbox c)+            => (a -> c) -> GeometryT a m b -> GeometryT c m ()+mapGeometry f s = Geometry $ do+  gs <- lift $ runGeometryT s+  put $ B.map (mapRawGeometry f) gs++vertexData :: RawGeometry v -> Vector v+vertexData (RawTriangles vs)     = vs+vertexData (RawBeziers vs)       = vs+vertexData (RawTriangleStrip vs) = vs+vertexData (RawTriangleFan vs)   = vs+vertexData (RawLine vs)          = vs+--------------------------------------------------------------------------------+-- Special Rendering Options+--------------------------------------------------------------------------------+data RenderingOption = StencilMaskOption+--------------------------------------------------------------------------------+-- Picture Data+--------------------------------------------------------------------------------+data PictureData texture vertex =+  PictureData { _picDataGeometry :: B.Vector (RawGeometry vertex)+              -- ^ This picture's vertex data.+              , _picDataStroke   :: [StrokeAttr]+              -- ^ The stroke attributes to use for drawing lines.+              , _picDataTextures :: [texture]+              -- ^ All the textures needed to render this picture's vertex data.+              , _picDataOptions  :: [RenderingOption]+              -- ^ Any special drawing options to apply when rendering this+              -- picture.+              }+makeLenses ''PictureData+--------------------------------------------------------------------------------+-- Helpers for Common Picture Types+--------------------------------------------------------------------------------+emptyPictureData :: PictureData t v+emptyPictureData =+    PictureData { _picDataGeometry   = B.empty+                , _picDataStroke    = []+                , _picDataTextures  = []+                , _picDataOptions   = []+                }++bothToFrac :: (Real a, Fractional b) => (V2 a, V2 a) -> (V2 b, V2 b)+bothToFrac= second (fmap realToFrac) . first (fmap realToFrac)+--------------------------------------------------------------------------------+-- Picture Construction+--------------------------------------------------------------------------------+type PictureT tex vert = StateT (PictureData tex vert)++runPictureT :: PictureT t v m a -> m (a, PictureData t v)+runPictureT = flip runStateT emptyPictureData+--------------------------------------------------------------------------------+-- Identity Parameterized Pictures+--------------------------------------------------------------------------------+type Picture t v = PictureT t v Identity++runPicture :: Picture t v a -> (a, PictureData t v)+runPicture = runIdentity . runPictureT++setRawGeometry :: Monad m => B.Vector (RawGeometry v) -> PictureT t v m ()+setRawGeometry vs = picDataGeometry .= vs++getRawGeometry :: Monad m => PictureT t v m (B.Vector (RawGeometry v))+getRawGeometry = use picDataGeometry++setGeometry :: Monad m => GeometryT v m () -> PictureT t v m ()+setGeometry = (setRawGeometry =<<) . lift . runGeometryT++setStroke :: Monad m => [StrokeAttr] -> PictureT t v m ()+setStroke = (picDataStroke .=)++getStroke :: Monad m => PictureT t v m [StrokeAttr]+getStroke = use picDataStroke++setTextures :: Monad m => [t] -> PictureT t v m ()+setTextures = (picDataTextures .=)++getTextures :: Monad m => PictureT t v m [t]+getTextures = use picDataTextures++setRenderingOptions :: Monad m => [RenderingOption] -> PictureT t v m ()+setRenderingOptions = (picDataOptions .=)++getRenderingOptions :: Monad m => PictureT t v m [RenderingOption]+getRenderingOptions = use picDataOptions+--------------------------------------------------------------------------------+-- Measuring pictures+--------------------------------------------------------------------------------+mapToSpaceVec :: (Monad m, Unbox v, Unbox s)+               => (v -> s) -> PictureT t v m (V.Vector s)+mapToSpaceVec vertToSpace = do+  gs <- use picDataGeometry+  let f = V.map vertToSpace . vertexData . (gs B.!)+  return $ V.concatMap f $ V.enumFromTo 0 (B.length gs - 1)++pictureBounds2 :: (Monad m, Unbox v)+               => (v -> V2 Float) -> PictureT t v m (V2 Float, V2 Float)+pictureBounds2 = (boundingBox <$>) . mapToSpaceVec++pictureBounds3 :: (Monad m, Unbox v)+               => (v -> V3 Float) -> PictureT t v m BCube+pictureBounds3 = (boundingCube <$>) . mapToSpaceVec++pictureSize2 :: (Monad m, Unbox v)+             => (v -> V2 Float) -> PictureT t v m (V2 Float)+pictureSize2 = pictureBounds2 >=> (return . uncurry (flip (-)))++pictureSize3 :: (Monad m, Unbox v)+             => (v -> V3 Float) -> PictureT t v m (V3 Float)+pictureSize3 = pictureBounds3 >=> (return . uncurry (flip (-)))++pictureOrigin2 :: (Monad m, Unbox v)+               => (v -> V2 Float) -> PictureT t v m (V2 Float)+pictureOrigin2 = (fst <$>) . pictureBounds2++pictureOrigin3 :: (Monad m, Unbox v)+               => (v -> V3 Float) -> PictureT t v m (V3 Float)+pictureOrigin3 = (fst <$>) . pictureBounds3++pictureCenter2 :: (Monad m, Unbox v)+               => (v -> V2 Float) -> PictureT t v m (V2 Float)+pictureCenter2 vertToSpace = do+  (tl,br) <- pictureBounds2 vertToSpace+  return $ tl + (br - tl)/2++pictureCenter3 :: (Monad m, Unbox v)+               => (v -> V3 Float) -> PictureT t v m (V3 Float)+pictureCenter3 vertToSpace = do+  (tl,br) <- pictureBounds3 vertToSpace+  return $ tl + (br - tl)/2
+ src/Gelatin/Picture/Shapes.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE TupleSections        #-}+{-# LANGUAGE TypeSynonymInstances #-}+module Gelatin.Picture.Shapes where++import           Control.Monad.State.Strict+import           Data.Vector.Unboxed        (Unbox)+import qualified Data.Vector.Unboxed        as V+import           Gelatin.Core+import           Gelatin.Picture.Internal+import           Linear                     hiding (rotate)+--------------------------------------------------------------------------------+-- Shapes (at the level of Vertices)+--------------------------------------------------------------------------------+curve :: (RealFloat a, Unbox a, Monad m)+      => V2 a -> V2 a -> V2 a+      -> VerticesT (V2 a) m ()+curve a b c =+  let vs  = subdivideAdaptive 100 0 $ bez3 a b c+  in Vertices $ modify (V.++ vs)++corner :: (RealFloat a, Unbox a, Monad m)+      => a -> a -> VerticesT (V2 a) m ()+corner xr yr =+  let vs = cleanSeqDupes $ V.concatMap (subdivideAdaptive 100 0) $ cornerBez3 xr yr+  in Vertices $ modify (V.++ vs)++arc :: (Unbox a, Epsilon a, RealFloat a, Monad m)+    => a -> a -> a -> a -> VerticesT (V2 a) m ()+arc w h start stop =+  let vs = cleanSeqDupes $ V.concatMap (subdivideAdaptive 100 0) $ arcBez3 w h start stop+  in Vertices $ modify (V.++ vs)++rectangle :: (Unbox a, Monad m)+          => V2 a -> V2 a -> VerticesT (V2 a) m ()+rectangle tl@(V2 tlx tly) br@(V2 brx bry) = do+  to tl+  to $ V2 brx tly+  to br+  to $ V2 tlx bry