-- | Color handling. -- {-# LANGUAGE DeriveDataTypeable, NoImplicitPrelude #-} module Graphics.Caramia.Color ( -- * Types Color() -- * Constructing colors , rgba -- * Lenses , rgbaL , redL , greenL , blueL , alphaL -- * Views , viewRgba , viewRed , viewGreen , viewBlue , viewAlpha ) where import Graphics.Caramia.Prelude import Graphics.Caramia.Internal.Lens import Foreign.Storable import Foreign.Ptr -- | The color data type. -- -- This data type says nothing about the color space these values are in. The -- color space depends on the usage; for example, a framebuffer with sRGB -- textures attached uses sRGB color space in these color values. data Color = Color { viewRed :: !Float , viewGreen :: !Float , viewBlue :: !Float , viewAlpha :: !Float } deriving ( Eq, Ord, Show, Read, Typeable ) -- | Construct a color from rgba values. rgba :: Float -> Float -> Float -> Float -> Color rgba = Color {-# INLINE rgba #-} -- | View rgba in a tuple. viewRgba :: Color -> (Float, Float, Float, Float) viewRgba (Color r g b a) = (r, g, b, a) {-# INLINE viewRgba #-} -- | Lens to all components. rgbaL :: Lens' Color (Float, Float, Float, Float) rgbaL = lens viewRgba (\old (r, g, b, a) -> old { viewRed = r , viewGreen = g , viewBlue = b , viewAlpha = a }) -- | Lens to red component. redL :: Lens' Color Float redL = lens viewRed (\old new -> old { viewRed = new }) -- | Lens to green component. greenL :: Lens' Color Float greenL = lens viewGreen (\old new -> old { viewGreen = new }) -- | Lens to blue component. blueL :: Lens' Color Float blueL = lens viewBlue (\old new -> old { viewBlue = new }) -- | Lens to alpha component. alphaL :: Lens' Color Float alphaL = lens viewAlpha (\old new -> old { viewAlpha = new }) instance Storable Color where sizeOf _ = sizeOf (undefined :: Float) * 4 alignment _ = alignment (undefined :: Float) * 4 peek ptr = do r <- peekElemOff cptr 0 :: IO Float g <- peekElemOff cptr 1 :: IO Float b <- peekElemOff cptr 2 :: IO Float a <- peekElemOff cptr 3 :: IO Float return $ Color r g b a where cptr = castPtr ptr :: Ptr Float {-# INLINE peek #-} poke ptr (Color r g b a) = do pokeElemOff cptr 0 r pokeElemOff cptr 1 g pokeElemOff cptr 2 b pokeElemOff cptr 3 a where cptr = castPtr ptr :: Ptr Float {-# INLINE poke #-}