{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
module Graphics.Color.Model.HSL
( HSL
, pattern ColorHSL
, pattern ColorHSLA
, pattern ColorH360SL
, Color
, ColorModel(..)
, hc2rgb
, hsl2rgb
, rgb2hsl
) where
import Foreign.Storable
import Graphics.Color.Model.HSV (hc2rgb)
import Graphics.Color.Model.Internal
import Graphics.Color.Model.RGB
data HSL
newtype instance Color HSL e = HSL (V3 e)
pattern ColorHSL :: e -> e -> e -> Color HSL e
pattern $bColorHSL :: e -> e -> e -> Color HSL e
$mColorHSL :: forall r e. Color HSL e -> (e -> e -> e -> r) -> (Void# -> r) -> r
ColorHSL h s l = HSL (V3 h s l)
{-# COMPLETE ColorHSL #-}
pattern ColorHSLA :: e -> e -> e -> e -> Color (Alpha HSL) e
pattern $bColorHSLA :: e -> e -> e -> e -> Color (Alpha HSL) e
$mColorHSLA :: forall r e.
Color (Alpha HSL) e -> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
ColorHSLA h s l a = Alpha (ColorHSL h s l) a
{-# COMPLETE ColorHSLA #-}
pattern ColorH360SL :: Fractional e => e -> e -> e -> Color HSL e
pattern $bColorH360SL :: e -> e -> e -> Color HSL e
$mColorH360SL :: forall r e.
Fractional e =>
Color HSL e -> (e -> e -> e -> r) -> (Void# -> r) -> r
ColorH360SL h s l <- ColorHSL ((* 360) -> h) s l where
ColorH360SL e
h e
s e
l = e -> e -> e -> Color HSL e
forall e. e -> e -> e -> Color HSL e
ColorHSL (e
h e -> e -> e
forall a. Fractional a => a -> a -> a
/ e
360) e
s e
l
{-# COMPLETE ColorH360SL #-}
deriving instance Eq e => Eq (Color HSL e)
deriving instance Ord e => Ord (Color HSL e)
deriving instance Functor (Color HSL)
deriving instance Applicative (Color HSL)
deriving instance Foldable (Color HSL)
deriving instance Traversable (Color HSL)
deriving instance Storable e => Storable (Color HSL e)
instance Elevator e => Show (Color HSL e) where
showsPrec :: Int -> Color HSL e -> ShowS
showsPrec Int
_ = Color HSL e -> ShowS
forall cs e. ColorModel cs e => Color cs e -> ShowS
showsColorModel
instance Elevator e => ColorModel HSL e where
type Components HSL e = (e, e, e)
toComponents :: Color HSL e -> Components HSL e
toComponents (ColorHSL e
h e
s e
l) = (e
h, e
s, e
l)
{-# INLINE toComponents #-}
fromComponents :: Components HSL e -> Color HSL e
fromComponents (h, s, l) = e -> e -> e -> Color HSL e
forall e. e -> e -> e -> Color HSL e
ColorHSL e
h e
s e
l
{-# INLINE fromComponents #-}
hsl2rgb :: RealFrac e => Color HSL e -> Color RGB e
hsl2rgb :: Color HSL e -> Color RGB e
hsl2rgb (ColorHSL e
h e
s e
l) = (e -> e -> e
forall a. Num a => a -> a -> a
+ e
m) (e -> e) -> Color RGB e -> Color RGB e
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> e -> e -> Color RGB e
forall e. RealFrac e => e -> e -> Color RGB e
hc2rgb e
h e
c
where
!c :: e
c = (e
1 e -> e -> e
forall a. Num a => a -> a -> a
- e -> e
forall a. Num a => a -> a
abs (e
2 e -> e -> e
forall a. Num a => a -> a -> a
* e
l e -> e -> e
forall a. Num a => a -> a -> a
- e
1)) e -> e -> e
forall a. Num a => a -> a -> a
* e
s
!m :: e
m = e
l e -> e -> e
forall a. Num a => a -> a -> a
- e
c e -> e -> e
forall a. Fractional a => a -> a -> a
/ e
2
{-# INLINE hsl2rgb #-}
rgb2hsl :: (Ord e, Floating e) => Color RGB e -> Color HSL e
rgb2hsl :: Color RGB e -> Color HSL e
rgb2hsl (ColorRGB e
r e
g e
b) = e -> e -> e -> Color HSL e
forall e. e -> e -> e -> Color HSL e
ColorHSL e
h e
s e
l
where
!max' :: e
max' = e -> e -> e
forall a. Ord a => a -> a -> a
max e
r (e -> e -> e
forall a. Ord a => a -> a -> a
max e
g e
b)
!min' :: e
min' = e -> e -> e
forall a. Ord a => a -> a -> a
min e
r (e -> e -> e
forall a. Ord a => a -> a -> a
min e
g e
b)
!h' :: e
h' | e
max' e -> e -> Bool
forall a. Eq a => a -> a -> Bool
== e
r = ( (e
g e -> e -> e
forall a. Num a => a -> a -> a
- e
b) e -> e -> e
forall a. Fractional a => a -> a -> a
/ (e
max' e -> e -> e
forall a. Num a => a -> a -> a
- e
min')) e -> e -> e
forall a. Fractional a => a -> a -> a
/ e
6
| e
max' e -> e -> Bool
forall a. Eq a => a -> a -> Bool
== e
g = (e
2 e -> e -> e
forall a. Num a => a -> a -> a
+ (e
b e -> e -> e
forall a. Num a => a -> a -> a
- e
r) e -> e -> e
forall a. Fractional a => a -> a -> a
/ (e
max' e -> e -> e
forall a. Num a => a -> a -> a
- e
min')) e -> e -> e
forall a. Fractional a => a -> a -> a
/ e
6
| e
max' e -> e -> Bool
forall a. Eq a => a -> a -> Bool
== e
b = (e
4 e -> e -> e
forall a. Num a => a -> a -> a
+ (e
r e -> e -> e
forall a. Num a => a -> a -> a
- e
g) e -> e -> e
forall a. Fractional a => a -> a -> a
/ (e
max' e -> e -> e
forall a. Num a => a -> a -> a
- e
min')) e -> e -> e
forall a. Fractional a => a -> a -> a
/ e
6
| Bool
otherwise = e
0
!h :: e
h
| e
h' e -> e -> Bool
forall a. Ord a => a -> a -> Bool
< e
0 = e
h' e -> e -> e
forall a. Num a => a -> a -> a
+ e
1
| Bool
otherwise = e
h'
!s :: e
s
| e
max' e -> e -> Bool
forall a. Eq a => a -> a -> Bool
== e
0 Bool -> Bool -> Bool
|| e
min' e -> e -> Bool
forall a. Eq a => a -> a -> Bool
== e
1 = e
0
| Bool
otherwise = (e
max' e -> e -> e
forall a. Num a => a -> a -> a
- e
l) e -> e -> e
forall a. Fractional a => a -> a -> a
/ e -> e -> e
forall a. Ord a => a -> a -> a
min e
l (e
1 e -> e -> e
forall a. Num a => a -> a -> a
- e
l)
!l :: e
l = (e
max' e -> e -> e
forall a. Num a => a -> a -> a
+ e
min') e -> e -> e
forall a. Fractional a => a -> a -> a
/ e
2
{-# INLINE rgb2hsl #-}