module Data.Colour.Internal where
import Data.List (foldl1')
import qualified Data.Colour.Chan as Chan
import Data.Colour.Chan (Chan(Chan))
data Red = Red
data Green = Green
data Blue = Blue
data Colour a = RGB !(Chan Red a) !(Chan Green a) !(Chan Blue a)
deriving (Colour a -> Colour a -> Bool
forall a. Eq a => Colour a -> Colour a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Colour a -> Colour a -> Bool
$c/= :: forall a. Eq a => Colour a -> Colour a -> Bool
== :: Colour a -> Colour a -> Bool
$c== :: forall a. Eq a => Colour a -> Colour a -> Bool
Eq)
colourConvert :: (Fractional b, Real a) => Colour a -> Colour b
colourConvert :: forall b a. (Fractional b, Real a) => Colour a -> Colour b
colourConvert (RGB Chan Red a
r Chan Green a
g Chan Blue a
b) =
forall a. Chan Red a -> Chan Green a -> Chan Blue a -> Colour a
RGB (forall b a p. (Fractional b, Real a) => Chan p a -> Chan p b
Chan.convert Chan Red a
r) (forall b a p. (Fractional b, Real a) => Chan p a -> Chan p b
Chan.convert Chan Green a
g) (forall b a p. (Fractional b, Real a) => Chan p a -> Chan p b
Chan.convert Chan Blue a
b)
black :: (Num a) => Colour a
black :: forall a. Num a => Colour a
black = forall a. Chan Red a -> Chan Green a -> Chan Blue a -> Colour a
RGB forall a p. Num a => Chan p a
Chan.empty forall a p. Num a => Chan p a
Chan.empty forall a p. Num a => Chan p a
Chan.empty
instance (Num a) => Semigroup (Colour a) where
(RGB Chan Red a
r1 Chan Green a
g1 Chan Blue a
b1) <> :: Colour a -> Colour a -> Colour a
<> (RGB Chan Red a
r2 Chan Green a
g2 Chan Blue a
b2) =
forall a. Chan Red a -> Chan Green a -> Chan Blue a -> Colour a
RGB (Chan Red a
r1 forall a p. Num a => Chan p a -> Chan p a -> Chan p a
`Chan.add` Chan Red a
r2) (Chan Green a
g1 forall a p. Num a => Chan p a -> Chan p a -> Chan p a
`Chan.add` Chan Green a
g2) (Chan Blue a
b1 forall a p. Num a => Chan p a -> Chan p a -> Chan p a
`Chan.add` Chan Blue a
b2)
instance (Num a) => Monoid (Colour a) where
mempty :: Colour a
mempty = forall a. Num a => Colour a
black
mconcat :: [Colour a] -> Colour a
mconcat [Colour a]
l = forall a. Chan Red a -> Chan Green a -> Chan Blue a -> Colour a
RGB (forall a p. Num a => [Chan p a] -> Chan p a
Chan.sum [Chan Red a]
lr) (forall a p. Num a => [Chan p a] -> Chan p a
Chan.sum [Chan Green a]
lg) (forall a p. Num a => [Chan p a] -> Chan p a
Chan.sum [Chan Blue a]
lb)
where
([Chan Red a]
lr,[Chan Green a]
lg,[Chan Blue a]
lb) = forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 (forall a b. (a -> b) -> [a] -> [b]
map forall {a}. Colour a -> (Chan Red a, Chan Green a, Chan Blue a)
toRGB [Colour a]
l)
toRGB :: Colour a -> (Chan Red a, Chan Green a, Chan Blue a)
toRGB (RGB Chan Red a
r Chan Green a
g Chan Blue a
b) = (Chan Red a
r,Chan Green a
g,Chan Blue a
b)
data Alpha = Alpha
data AlphaColour a = RGBA !(Colour a) !(Chan Alpha a) deriving (AlphaColour a -> AlphaColour a -> Bool
forall a. Eq a => AlphaColour a -> AlphaColour a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AlphaColour a -> AlphaColour a -> Bool
$c/= :: forall a. Eq a => AlphaColour a -> AlphaColour a -> Bool
== :: AlphaColour a -> AlphaColour a -> Bool
$c== :: forall a. Eq a => AlphaColour a -> AlphaColour a -> Bool
Eq)
transparent :: (Num a) => AlphaColour a
transparent :: forall a. Num a => AlphaColour a
transparent = forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (forall a. Chan Red a -> Chan Green a -> Chan Blue a -> Colour a
RGB forall a p. Num a => Chan p a
Chan.empty forall a p. Num a => Chan p a
Chan.empty forall a p. Num a => Chan p a
Chan.empty) forall a p. Num a => Chan p a
Chan.empty
alphaColourConvert :: (Fractional b, Real a) =>
AlphaColour a -> AlphaColour b
alphaColourConvert :: forall b a.
(Fractional b, Real a) =>
AlphaColour a -> AlphaColour b
alphaColourConvert (RGBA Colour a
c Chan Alpha a
a) = forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (forall b a. (Fractional b, Real a) => Colour a -> Colour b
colourConvert Colour a
c) (forall b a p. (Fractional b, Real a) => Chan p a -> Chan p b
Chan.convert Chan Alpha a
a)
opaque :: (Num a) => Colour a -> AlphaColour a
opaque :: forall a. Num a => Colour a -> AlphaColour a
opaque Colour a
c = forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA Colour a
c forall a p. Num a => Chan p a
Chan.full
dissolve :: (Num a) => a -> AlphaColour a -> AlphaColour a
dissolve :: forall a. Num a => a -> AlphaColour a -> AlphaColour a
dissolve a
o (RGBA Colour a
c Chan Alpha a
a) = forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (forall (f :: * -> *) a. (ColourOps f, Num a) => a -> f a -> f a
darken a
o Colour a
c) (forall a p. Num a => a -> Chan p a -> Chan p a
Chan.scale a
o Chan Alpha a
a)
withOpacity :: (Num a) => Colour a -> a -> AlphaColour a
Colour a
c withOpacity :: forall a. Num a => Colour a -> a -> AlphaColour a
`withOpacity` a
o = forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (forall (f :: * -> *) a. (ColourOps f, Num a) => a -> f a -> f a
darken a
o Colour a
c) (forall p a. a -> Chan p a
Chan a
o)
class AffineSpace f where
affineCombo :: (Num a) => [(a,f a)] -> f a -> f a
blend :: (Num a, AffineSpace f) => a -> f a -> f a -> f a
blend :: forall a (f :: * -> *).
(Num a, AffineSpace f) =>
a -> f a -> f a -> f a
blend a
weight f a
c1 f a
c2 = forall (f :: * -> *) a.
(AffineSpace f, Num a) =>
[(a, f a)] -> f a -> f a
affineCombo [(a
weight,f a
c1)] f a
c2
instance AffineSpace Colour where
affineCombo :: forall a. Num a => [(a, Colour a)] -> Colour a -> Colour a
affineCombo [(a, Colour a)]
l Colour a
z =
forall a. (a -> a -> a) -> [a] -> a
foldl1' forall a. Monoid a => a -> a -> a
mappend [forall (f :: * -> *) a. (ColourOps f, Num a) => a -> f a -> f a
darken a
w Colour a
a | (a
w,Colour a
a) <- (a
1forall a. Num a => a -> a -> a
-a
total,Colour a
z)forall a. a -> [a] -> [a]
:[(a, Colour a)]
l]
where
total :: a
total = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(a, Colour a)]
l
instance AffineSpace AlphaColour where
affineCombo :: forall a.
Num a =>
[(a, AlphaColour a)] -> AlphaColour a -> AlphaColour a
affineCombo [(a, AlphaColour a)]
l AlphaColour a
z =
forall a. (a -> a -> a) -> [a] -> a
foldl1' forall {a}.
Num a =>
AlphaColour a -> AlphaColour a -> AlphaColour a
rgbaAdd [forall a. Num a => a -> AlphaColour a -> AlphaColour a
dissolve a
w AlphaColour a
a | (a
w,AlphaColour a
a) <- (a
1forall a. Num a => a -> a -> a
-a
total,AlphaColour a
z)forall a. a -> [a] -> [a]
:[(a, AlphaColour a)]
l]
where
total :: a
total = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(a, AlphaColour a)]
l
class ColourOps f where
over :: (Num a) => AlphaColour a -> f a -> f a
darken :: (Num a) => a -> f a -> f a
instance ColourOps Colour where
(RGBA (RGB Chan Red a
r0 Chan Green a
g0 Chan Blue a
b0) (Chan a
a0)) over :: forall a. Num a => AlphaColour a -> Colour a -> Colour a
`over` (RGB Chan Red a
r1 Chan Green a
g1 Chan Blue a
b1) =
forall a. Chan Red a -> Chan Green a -> Chan Blue a -> Colour a
RGB (forall {a} {p}. Num a => Chan p a -> a -> Chan p a -> Chan p a
Chan.over Chan Red a
r0 a
a0 Chan Red a
r1)
(forall {a} {p}. Num a => Chan p a -> a -> Chan p a -> Chan p a
Chan.over Chan Green a
g0 a
a0 Chan Green a
g1)
(forall {a} {p}. Num a => Chan p a -> a -> Chan p a -> Chan p a
Chan.over Chan Blue a
b0 a
a0 Chan Blue a
b1)
darken :: forall a. Num a => a -> Colour a -> Colour a
darken a
s (RGB Chan Red a
r Chan Green a
g Chan Blue a
b) = forall a. Chan Red a -> Chan Green a -> Chan Blue a -> Colour a
RGB (forall a p. Num a => a -> Chan p a -> Chan p a
Chan.scale a
s Chan Red a
r)
(forall a p. Num a => a -> Chan p a -> Chan p a
Chan.scale a
s Chan Green a
g)
(forall a p. Num a => a -> Chan p a -> Chan p a
Chan.scale a
s Chan Blue a
b)
instance ColourOps AlphaColour where
c0 :: AlphaColour a
c0@(RGBA Colour a
_ a0 :: Chan Alpha a
a0@(Chan a
a0')) over :: forall {a}.
Num a =>
AlphaColour a -> AlphaColour a -> AlphaColour a
`over` (RGBA Colour a
c1 Chan Alpha a
a1) =
forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (AlphaColour a
c0 forall (f :: * -> *) a.
(ColourOps f, Num a) =>
AlphaColour a -> f a -> f a
`over` Colour a
c1) (forall {a} {p}. Num a => Chan p a -> a -> Chan p a -> Chan p a
Chan.over Chan Alpha a
a0 a
a0' Chan Alpha a
a1)
darken :: forall a. Num a => a -> AlphaColour a -> AlphaColour a
darken a
s (RGBA Colour a
c Chan Alpha a
a) = forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (forall (f :: * -> *) a. (ColourOps f, Num a) => a -> f a -> f a
darken a
s Colour a
c) Chan Alpha a
a
instance (Num a) => Semigroup (AlphaColour a) where
<> :: AlphaColour a -> AlphaColour a -> AlphaColour a
(<>) = forall (f :: * -> *) a.
(ColourOps f, Num a) =>
AlphaColour a -> f a -> f a
over
instance (Num a) => Monoid (AlphaColour a) where
mempty :: AlphaColour a
mempty = forall a. Num a => AlphaColour a
transparent
atop :: (Fractional a) => AlphaColour a -> AlphaColour a -> AlphaColour a
atop :: forall a.
Fractional a =>
AlphaColour a -> AlphaColour a -> AlphaColour a
atop (RGBA Colour a
c0 (Chan a
a0)) (RGBA Colour a
c1 (Chan a
a1)) =
forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (forall (f :: * -> *) a. (ColourOps f, Num a) => a -> f a -> f a
darken a
a1 Colour a
c0 forall a. Monoid a => a -> a -> a
`mappend` forall (f :: * -> *) a. (ColourOps f, Num a) => a -> f a -> f a
darken (a
1forall a. Num a => a -> a -> a
-a
a0) Colour a
c1) (forall p a. a -> Chan p a
Chan a
a1)
quantize :: (RealFrac a1, Integral a, Bounded a) => a1 -> a
quantize :: forall a1 a. (RealFrac a1, Integral a, Bounded a) => a1 -> a
quantize a1
x | a1
x forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral a
l = a
l
| forall a b. (Integral a, Num b) => a -> b
fromIntegral a
h forall a. Ord a => a -> a -> Bool
<= a1
x = a
h
| Bool
otherwise = forall a b. (RealFrac a, Integral b) => a -> b
round a1
x
where
l :: a
l = forall a. Bounded a => a
minBound
h :: a
h = forall a. Bounded a => a
maxBound
alphaChannel :: AlphaColour a -> a
alphaChannel :: forall a. AlphaColour a -> a
alphaChannel (RGBA Colour a
_ (Chan a
a)) = a
a
colourChannel :: (Fractional a) => AlphaColour a -> Colour a
colourChannel :: forall a. Fractional a => AlphaColour a -> Colour a
colourChannel (RGBA Colour a
c (Chan a
a)) = forall (f :: * -> *) a. (ColourOps f, Num a) => a -> f a -> f a
darken (forall a. Fractional a => a -> a
recip a
a) Colour a
c
rgbaAdd :: AlphaColour a -> AlphaColour a -> AlphaColour a
rgbaAdd (RGBA Colour a
c1 Chan Alpha a
a1) (RGBA Colour a
c2 Chan Alpha a
a2) =
forall a. Colour a -> Chan Alpha a -> AlphaColour a
RGBA (Colour a
c1 forall a. Monoid a => a -> a -> a
`mappend` Colour a
c2) (Chan Alpha a
a1 forall a p. Num a => Chan p a -> Chan p a -> Chan p a
`Chan.add` Chan Alpha a
a2)