clutterhs-0.1: Graphics/UI/Clutter/Color.chs
-- -*-haskell-*-
-- Clutter Color
--
-- Author : Matthew Arsenault
--
-- Created: 4 Sep 2009
--
-- Copyright (C) 2009 Matthew Arsenault
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 3 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
{-# LANGUAGE ForeignFunctionInterface #-}
#include <clutter/clutter.h>
{# context lib="clutter" prefix="clutter" #}
-- | Colors — Color management and manipulation.
module Graphics.UI.Clutter.Color (
-- * Types
Color(..),
-- * Description
-- | 'Color' is a simple type for representing colors in Clutter.
--
-- A 'Color is expressed as a group of 4 alues ranging from zero to
-- 255, one for each color channel plus one for the alpha.
--
colorFromString,
colorToString,
colorFromHls,
colorToHls,
colorFromPixel,
colorToPixel,
colorAdd,
colorSubtract,
colorLighten,
colorDarken,
colorShade
) where
{# import Graphics.UI.Clutter.Types #}
{# import Graphics.UI.Clutter.Utility #}
import C2HS
import Data.Word
-- | Parses a string definition of a color, filling the red, green,
-- blue and alpha channels of color. If alpha is not specified it
-- will be set full opaque.
--
-- The color may be defined by any of the formats understood by
-- Pango.colorFromString; these include literal color names, like Red
-- or DarkSlateGray, or hexadecimal specifications like #3050b2 or
-- #333.
--
-- * Since 1.0
--
colorFromString :: String -- ^ a string specifiying a color (named color or RRGGBBAA)
-> Maybe Color -- ^ @Just@ a color, or @Nothing@ if parsing failed
colorFromString name = unsafePerformIO $ withCString name $ \cstr ->
alloca $ \colptr ->
if cToBool ({# call pure unsafe color_from_string #} colptr cstr)
then peek colptr >>= return . Just
else return Prelude.Nothing
-- | Returns a textual specification of color in the hexadecimal form
-- #rrggbbaa, where r, g, b and a are hex digits representing the
-- red, green, blue and alpha components respectively.
--
-- [@color@] a 'Color'
--
-- [@Returns@] a text string describing the color
--
-- * Since 0.2
--
{# fun pure unsafe color_to_string as ^ { withColor* `Color' } -> `String' peekNFreeString* #}
-- | Converts a color expressed in HLS (hue, luminance and saturation)
-- values into a 'Color'.
--
-- [@hue@] hue value, in the 0 .. 360 range
--
-- [@luminance@] luminance value, in the 0 .. 1 range
--
-- [@saturation@] saturation value, in the 0 .. 1 range
--
-- [@Returns@] a 'Color'
--
{# fun pure unsafe color_from_hls as ^
{ alloca- `Color' peek*, `Float', `Float', `Float' } -> `()' #}
-- | Converts color to the HLS format.
--
-- The hue value is in the 0 .. 360 range. The luminance and
-- saturation values are in the 0 .. 1 range.
--
-- [@color@] a 'Color'
--
-- [@Returns@] (hue, luminance, saturation)
--
{# fun pure unsafe color_to_hls as ^
{ withColor*`Color',
alloca- `Float' peekFloatConv*,
alloca- `Float' peekFloatConv*,
alloca- `Float' peekFloatConv* } -> `()' #}
-- | Converts pixel from the packed representation of a four 8 bit
-- channel color to a 'Color'.
--
-- [@pixel@] a 32 bit packed integer containing a color
--
-- [@Returns@] a 'Color'
--
{# fun pure unsafe color_from_pixel as ^ { alloca- `Color' peek*, `Word32' } -> `()' #}
-- | Converts color into a packed 32 bit integer, containing all the
-- four 8 bit channels used by 'Color'.
--
-- [@color@] a 'Color'
--
-- [@Returns@] a packed color
--
{# fun pure unsafe color_to_pixel as ^ { withColor* `Color' } -> `Word32' #}
clamp low high x | x > high = high
| x < low = low
| otherwise = x
-- | Adds a to b and saves the resulting color inside result.
--
-- The alpha channel of result is set as as the maximum value between
-- the alpha channels of a and b.
--
-- [@a@] a 'Color'
--
-- [@b@] a 'Color'
--
-- [@Returns@] Result
--
colorAdd (Color ra ga ba aa) (Color rb gb bb ab) = let lim = clamp 0 255
r = lim (ra + rb)
g = lim (ga + gb)
b = lim (ba + bb)
in Color r g b (max aa ab)
--There's no point in marshalling all this stuff just for this
--{# fun pure unsafe color_add as ^
-- { withColor* `Color', withColor* `Color', alloca- `Color' peek* } -> `()' #}
-- | Subtracts b from a
--
-- This function assumes that the components of a are greater than the
-- components of b; the result is, otherwise, undefined.
--
-- The alpha channel of result is set as the minimum value between the
-- alpha channels of a and b.
--
-- [@a@] a 'Color'
--
-- [@b@] a 'Color'
--
-- [@Returns@] Result
--
colorSubtract (Color ra ga ba aa) (Color rb gb bb ab) = let lim = clamp 0 255
r = lim (ra - rb)
g = lim (ga - gb)
b = lim (ba - bb)
in Color r g b (min aa ab)
--{# fun pure unsafe color_subtract as ^
-- { withColor* `Color', withColor* `Color', alloca- `Color' peek* } -> `()' #}
-- | Lightens color by a fixed amount
--
-- [@color@] a 'Color'
--
-- [@Returns@] the lighter color
--
{# fun pure unsafe color_lighten as ^
{ withColor* `Color', alloca- `Color' peek* } -> `()' #}
-- | Darkens color by a fixed amount, and saves the changed color in result.
--
-- [@color@] a 'Color'
--
-- [@Returns@] the darker color.
--
{# fun pure unsafe color_darken as ^
{ withColor* `Color', alloca- `Color' peek* } -> `()' #}
-- | Shades color by factor and saves the modified color into result.
--
-- [@color@] a 'Color'
--
-- [@factor@] the shade factor to apply
--
-- [@result@] the shaded color
--
{# fun pure unsafe color_shade as ^
{ withColor* `Color', `Double', alloca- `Color' peek* } -> `()' #}
-- TODO: ClutterParamSpecColor stuff