1{-# LANGUAGE DeriveGeneric #-}
2{-# LANGUAGE DeriveAnyClass #-}
3
4module Graphics.Vty.Attributes.Color
5  ( Color(..)
6
7  -- ** Fixed Colors
8  -- | Standard 8-color ANSI terminal color codes.
9  --
10  -- Note that these map to colors in the terminal's custom palette. For
11  -- instance, `white` maps to whatever the terminal color theme uses for
12  -- white.
13  --
14  -- Use these functions if you want to make apps that fit the terminal theme.
15  -- If you want access to more/stronger colors use `rgbColor`
16  , black
17  , red
18  , green
19  , yellow
20  , blue
21  , magenta
22  , cyan
23  , white
24
25  -- | Bright/Vivid variants of the standard 8-color ANSI
26  , brightBlack
27  , brightRed
28  , brightGreen
29  , brightYellow
30  , brightBlue
31  , brightMagenta
32  , brightCyan
33  , brightWhite
34  -- ** Creating Colors From RGB
35  , rgbColor
36  , module Graphics.Vty.Attributes.Color240
37  )
38where
39
40import Data.Word
41import GHC.Generics
42import Control.DeepSeq
43
44import Graphics.Vty.Attributes.Color240
45
46-- | Abstract data type representing a color.
47--
48-- Currently the foreground and background color are specified as points
49-- in either a:
50--
51--  * 16 color palette. Where the first 8 colors are equal to the 8
52--  colors of the ISO 6429 (ANSI) 8 color palette and the second 8
53--  colors are bright/vivid versions of the first 8 colors.
54--
55--  * 240 color palette. This palette is a regular sampling of the full
56--  RGB colorspace for the first 224 colors. The remaining 16 colors is
57--  a greyscale palette.
58--
59-- The 8 ISO 6429 (ANSI) colors are as follows:
60--
61--      0. black
62--
63--      1. red
64--
65--      2. green
66--
67--      3. yellow
68--
69--      4. blue
70--
71--      5. magenta
72--
73--      6. cyan
74--
75--      7. white
76--
77-- The mapping from points in the 240 color palette to colors actually
78-- displayable by the terminal depends on the number of colors the
79-- terminal claims to support. Which is usually determined by the
80-- terminfo "colors" property. If this property is not being accurately
81-- reported then the color reproduction will be incorrect.
82--
83-- If the terminal reports <= 16 colors then the 240 color palette
84-- points are only mapped to the 8 color pallete. I'm not sure of
85-- the RGB points for the "bright" colors which is why they are not
86-- addressable via the 240 color palette.
87--
88-- If the terminal reports > 16 colors then the 240 color palette
89-- points are mapped to the nearest points in a ("color count" - 16)
90-- subsampling of the 240 color palette.
91--
92-- All of this assumes the terminals are behaving similarly to xterm and
93-- rxvt when handling colors. And that the individual colors have not
94-- been remapped by the user. There may be a way to verify this through
95-- terminfo but I don't know it.
96--
97-- Seriously, terminal color support is INSANE.
98data Color = ISOColor !Word8 | Color240 !Word8
99    deriving ( Eq, Show, Read, Generic, NFData )
100
101black, red, green, yellow, blue, magenta, cyan, white :: Color
102black  = ISOColor 0
103red    = ISOColor 1
104green  = ISOColor 2
105yellow = ISOColor 3
106blue   = ISOColor 4
107magenta= ISOColor 5
108cyan   = ISOColor 6
109white  = ISOColor 7
110
111brightBlack, brightRed, brightGreen, brightYellow :: Color
112brightBlue, brightMagenta, brightCyan, brightWhite :: Color
113brightBlack  = ISOColor 8
114brightRed    = ISOColor 9
115brightGreen  = ISOColor 10
116brightYellow = ISOColor 11
117brightBlue   = ISOColor 12
118brightMagenta= ISOColor 13
119brightCyan   = ISOColor 14
120brightWhite  = ISOColor 15
121
122
123-- | Create a Vty 'Color' (in the 240 color set) from an RGB triple.
124-- This function is lossy in the sense that we only internally support 240 colors but the
125-- #RRGGBB format supports 16^3 colors.
126rgbColor :: Integral i => i -> i -> i -> Color
127rgbColor r g b = Color240 (rgbColorToColor240 r g b)
128