{-# LANGUAGE TypeSynonymInstances, TypeOperators, FlexibleInstances , GeneralizedNewtypeDeriving, TypeFamilies , MultiParamTypeClasses, UndecidableInstances #-} {-# OPTIONS_GHC -Wall #-} ---------------------------------------------------------------------- -- | -- Module : Shady.Color -- Copyright : (c) Conal Elliott 2009 -- License : AGPLv3 -- -- Maintainer : conal@conal.net -- Stability : experimental -- -- Simple colors ---------------------------------------------------------------------- module Shady.Color ( -- * Basics Color, colorToR4, r4ToColor, rgba, rgb, colorR, colorG, colorB, colorA -- * Color operations , overC, over -- * Some colors , black, white, red, green, blue, clear, grey, gray -- * Conversion to color , HasColor(..) ) where import Data.Monoid (Monoid(..)) import Control.Applicative (liftA2) import Control.Compose ((~>)) import Data.VectorSpace import Data.NumInstances () import Data.Boolean import Shady.Misc (Unop, Binop) import Shady.Language.Exp -- TODO: Vector space instance {-------------------------------------------------------------------- Basics --------------------------------------------------------------------} type Float4E = (FloatE,FloatE,FloatE,FloatE) -- | Color, as RGBA newtype Color = C { unC :: Float4E } deriving ( Eq,Ord,Show,Num,Fractional,Floating , AdditiveGroup, InnerSpace ) -- VectorSpace has an associated type, which @deriving@ currently doesn't handle. instance VectorSpace Color where type Scalar Color = Scalar (Float4E) (*^) s = inC ((*^) s) -- | Representation conversion colorToR4 :: Color -> R4E colorToR4 (C (r,g,b,a)) = vec4 r g b a -- | Representation conversion r4ToColor :: R4E -> Color r4ToColor = C . un4 inC :: Unop (Float4E) -> Unop Color inC = unC ~> C inC2 :: Binop (Float4E) -> Binop Color inC2 = unC ~> inC -- | Color from red, green, blue, alpha components rgba :: R1 :=> R1 :=> R1 :=> R1 :=> Color rgba r g b a = C (r,g,b,a) -- | Color from red, green, blue components rgb :: R1 :=> R1 :=> R1 :=> Color rgb r g b = rgba r g b 1 -- | Extract the red component colorR :: Color -> FloatE colorR (C (r,_,_,_)) = r -- | Extract the green component colorG :: Color -> FloatE colorG (C (_,g,_,_)) = g -- | Extract the blue component colorB :: Color -> FloatE colorB (C (_,_,b,_)) = b -- | Extract the alpha component colorA :: Color -> FloatE colorA (C (_,_,_,a)) = a {-------------------------------------------------------------------- Color operations --------------------------------------------------------------------} -- | Overlay on two colors overC :: Binop Color overC top bot = top ^+^ (1 - colorA top) *^ bot -- | Pointwise 'overC', e.g., for images. over :: Binop (p->Color) over = liftA2 overC {-------------------------------------------------------------------- Some colors --------------------------------------------------------------------} -- | Some colors black, white, red, green, blue, clear :: Color black = grey 0 white = grey 1 red = rgb 1 0 0 green = rgb 0 1 0 blue = rgb 0 0 1 clear = rgba 0 0 0 0 -- | Shade of grey grey, gray :: R1 :=> Color grey x = rgb x x x gray = grey {-------------------------------------------------------------------- Instances --------------------------------------------------------------------} instance Monoid Color where mempty = clear mappend = overC instance IfB BoolE Color where ifB = inC2 . ifB {-------------------------------------------------------------------- Conversion to color --------------------------------------------------------------------} class HasColor a where toColor :: a -> Color instance HasColor Color where toColor = id instance HasColor BoolE where toColor = boolean nonWhite white nonWhite :: Color nonWhite = clear -- rgb 0 0.2 0 -- dark green -- clear -- black