packages feed

diagrams (empty) → 0.1

raw patch · 11 files changed

+2532/−0 lines, 11 filesdep +basedep +cairodep +mtlsetup-changed

Dependencies added: base, cairo, mtl

Files

+ Graphics/Rendering/Diagrams.hs view
@@ -0,0 +1,182 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Rendering.Diagrams+-- Copyright   :  (c) Brent Yorgey 2008+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  byorgey@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- An embedded domain-specific language (EDSL) for creating simple+-- diagrams, built on top of the Cairo rendering engine.+--+-----------------------------------------------------------------------------++module Graphics.Rendering.Diagrams+  (++  -- * Introduction++  -- $intro++  -- * Primitives++    Diagram, nil++  -- ** Shapes++  , circle+  , poly+  , rect+  , shape++  -- ** Spacers++  , hspace+  , vspace+  , empty++  -- * Combinators+  -- $comb++  -- ** Union++  , (##), union, unionA++  -- ** Lists++  , (<>), (//)+  , hcat, vcat+  , hcatA, vcatA+  , hsep, vsep+  , hsepA, vsepA+  , hdistrib, vdistrib+  , hdistribA, vdistribA++  , VAlignment+  , top, vcenter, bottom+  , HAlignment+  , left, hcenter, right++  -- * Transformations+  -- $transf++  , stretch, scale, scaleX, scaleY+  , translate, translateX, translateY+  , rotate, rotateR++  , view++  -- * Attributes+  -- $attr++  , fillColor, fc+  , fillTransparency, ft+  , lineColor, lc+  , lineWidth, lw++  , Color+  , rgb+  , rgba+  , module Graphics.Rendering.Diagrams.Colors+++  -- * Rendering++  , renderToPng+  , compose++  ) where++import Graphics.Rendering.Diagrams.Types+import Graphics.Rendering.Diagrams.Shapes+import Graphics.Rendering.Diagrams.Attributes+import Graphics.Rendering.Diagrams.Colors+import Graphics.Rendering.Diagrams.Layouts+import Graphics.Rendering.Diagrams.Engine++{- $intro++"Graphics.Rendering.Diagrams" is an embedded domain-specific language+(EDSL) for creating simple diagrams.  It is compositional; starting+with some basic shapes, you can build up complex diagrams by combining+simpler diagrams in various ways.++A few fundamental concepts to keep in mind:++  * When constructing diagrams, there is no concept of an absolute+    coordinate system; everything is relative.  You cannot say \"this+    diagram should go at (2,1)\"; you can only say \"this diagram should+    go to the right of this other one\", or \"this diagram should go two+    units to the right and one unit above where it would otherwise+    be\".++  * Every diagram has an associated rectangular bounding box, which+    determines its positioning and alignment relative to other+    diagrams.  Usually this makes no difference but there are times+    when it's nice to be aware of it. For example, translating a+    diagram works by moving the diagram relative to its bounding box;+    positioning the bounding box where it would have gone means the+    diagram itself ends up elsewhere.  Also, some shapes have+    non-obvious bounding boxes; for example, regular polygons have a+    bounding box that fits their circumcircle.++  * The positive y-axis points downwards.++For some simple examples, see+<http://byorgey.wordpress.com/2008/04/30/new-haskell-diagrams-library/>.++Enjoy!  Please send comments, suggestions, bug reports, or patches to+byorgey at gmail dot com.++-}++-- | The nil diagram, which takes up no space and produces no output.+nil :: Diagram+nil = Empty++-- | Create a 'Diagram' out of any instance of 'ShapeClass'.+shape :: (ShapeClass s) => s -> Diagram+shape = Prim . Shape++-- | @hspace w@ is a 'Diagram' which produces no output but takes up+--   @w@ amount of space horizontally.  Useful for manually creating+--   horizontal separation between two diagrams.  A negative value+--   of @w@ can also be used to move two diagrams closer to one+--   another. @hspace w@ is equivalent to @empty w 0@.+hspace :: Double -> Diagram+hspace w = empty w 0++-- | @vspace h@ is a 'Diagram' which produces no output but takes up+--   @h@ amount of space vertically.  Useful for manually creating+--   vertical separation between two diagrams.  A negative value of+--   @h@ can also be used to move two diagrams closer to one+--   another. @vspace h@ is equivalent to @empty 0 h@.+vspace :: Double -> Diagram+vspace h = empty 0 h++-- | @empty w h@ is an empty diagram which produces no output, but+--   takes up an amount of space equal to a @w@ by @h@ rectangle.+empty :: Double -> Double -> Diagram+empty w h = Sized (w, h) Empty++-- $transf+-- Various ways to modify and transform 'Diagram's.++-- | XXX comment me+view :: Point -> Point -> Diagram -> Diagram+view (x1,y1) (x2,y2) d = Sized (x2-x1, y2-y1) . translate ((x1-x2)/2) ((y1-y2)/2) $ d++-- $attr+-- Attributes which affect the way in which a 'Diagram' is rendered.+-- For a large list of predefined 'Color' values, see+-- "Graphics.Rendering.Diagrams.Colors".++-- | Render a diagram to a file in PNG format.+renderToPng :: String     -- ^ The name of the file to create.+            -> Int        -- ^ The desired width of the image, in pixels.+            -> Int        -- ^ The desired height of the image.+            -> Diagram    -- ^ The diagram to render.+            -> IO ()+renderToPng name w h dia = writePng name w h $+                             compose (fromIntegral w) (fromIntegral h) dia
+ Graphics/Rendering/Diagrams/Attributes.hs view
@@ -0,0 +1,193 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Rendering.Diagrams.Attributes+-- Copyright   :  (c) Brent Yorgey 2008+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  byorgey@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Attributes which can be added as annotations to a 'Diagram',+-- implemented via instances of 'AttrClass'.+--+-----------------------------------------------------------------------------+module Graphics.Rendering.Diagrams.Attributes+  ( fillColor, fc+  , fillTransparency, ft+  , lineColor, lc+  , lineWidth, lw++  , stretch, scale, scaleX, scaleY+  , translate, translateX, translateY+  , rotate, rotateR++  ) where++import Graphics.Rendering.Diagrams.Types++import qualified Graphics.Rendering.Cairo as C+++-- Fill color ----------------------++-- | Specify the default fill color for a 'Diagram'.+newtype Fill = Fill Color  deriving (Eq, Show, Read)+instance AttrClass Fill where+  renderAttr (Fill f) = return (setEnvFillColor f)++-- | Draw a diagram using the given fill color.  Note that the new+--   color only applies to parts of the diagram which are not+--   otherwise colored; subdiagrams which already have an explicit+--   fill color will not be affected.  The default fill color is+--   completely transparent.+fillColor :: Color -> Diagram -> Diagram+fillColor = Ann . Attr . Fill++-- | 'fc' is provided as a convenient short synonym for 'fillColor'.+fc :: Color -> Diagram -> Diagram+fc = fillColor++++-- Stroke color ----------------------++-- | Specify the default stroke color for a 'Diagram'.+newtype Stroke = Stroke Color  deriving (Eq, Show, Read)+instance AttrClass Stroke where+  renderAttr (Stroke sc) = return (setEnvStrokeColor sc)++-- | Draw a diagram using the given color for lines.   Note that the new+--   color only applies to parts of the diagram which are not+--   otherwise colored; subdiagrams which already have an explicit+--   line color will not be affected.  The default line color is black.+lineColor :: Color -> Diagram -> Diagram+lineColor = Ann . Attr . Stroke++-- | 'lc' is provided as a convenient short synonym for 'lineColor'.+lc :: Color -> Diagram -> Diagram+lc = lineColor+++-- Stroke width ------------------------------++-- | The stroke width to be used in drawing lines or shape outlines.+--   Note that the stroke width is measured in /device coordinates/,+--   so a stroke width of a certain size will look the same under any+--   uniform scaling.  Under non-uniform (i.e. different in the x and+--   y axes) scaling, however, strokes may look distorted.+newtype StrokeWidth = StrokeWidth Double  deriving (Eq, Show, Read)+instance AttrClass StrokeWidth where+  renderAttr (StrokeWidth w) = return (setEnvStrokeWidth w)++-- | Draw shape outlines and lines with the given width.  Note that+--   the line width is invariant under uniform scaling, although under+--   non-uniform scaling (scaling by different amounts in the x and y+--   axes) lines can become distorted.  The default line width is 1.+lineWidth :: Double -> Diagram -> Diagram+lineWidth = Ann . Attr . StrokeWidth++-- | 'lw' is provided as a convenient short synonym for 'lineWidth'.+lw :: Double -> Diagram -> Diagram+lw = lineWidth++++-- Transparency ------------------------------++newtype FillTransparency = FT Double  deriving (Eq, Show, Read)+instance AttrClass FillTransparency where+  renderAttr (FT t) = return setFillAlpha+    where setFillAlpha env = env { envFillColor = newFillColor env }+          newFillColor env   = RGBA r g b t+            where (RGBA r g b _)     = envFillColor env++-- XXX improve this -- currently, you have to put it AFTER the color!+-- | Set the transparency used for the fill color, from 0 (completely+--   transparent) to 255 (completely opaque).  Note that you can set+--   the alpha channel of the fill color using 'fillColor' combined+--   with 'rgba', but 'fillTransparency' allows you to set the alpha+--   channel independently of the color channels.  This means you can+--   use it together with the colors defined in+--   "Graphics.Rendering.Diagrams.Colors".+fillTransparency :: Int -> Diagram -> Diagram+fillTransparency = Ann . Attr . FT . (/255) . fromIntegral++-- | 'ft' is provided as a convenient short synonym for 'fillTransparency'.+ft = fillTransparency++-- XXX put a line transparency attribute here++-- Rotate ----------------------------++-- | Rotate a diagram clockwise through a certain number of radians.+newtype Rotate = Rotate Double  deriving (Eq, Show, Read)+instance AttrClass Rotate where+  renderAttr (Rotate d) = c $ C.rotate d >> return id++-- | @rotateR r@ rotates a diagram clockwise by @r@ radians.+rotateR :: Double -> Diagram -> Diagram+rotateR r = Ann (Attr (Rotate r))++-- | @rotate f@ rotates a diagram clockwise by fraction @f@ of a+--   complete revolution.  @rotate f@ is equivalent to @rotateR+--   (2*pi*f)@.+rotate :: Double -> Diagram -> Diagram+rotate f = rotateR (2*pi*f)+++-- Translate ---------------------------++-- | Translate a diagram by the given offset.+newtype Translate = Translate Point  deriving (Eq, Show, Read)+instance AttrClass Translate where+  renderAttr (Translate (x,y)) = c $ C.translate x y >> return id++-- | Translate a diagram by the given relative offsets in the x and y+--   directions.  Note that the positive x-axis is to the right, while+--   the positive y-axis points downwards.+translate :: Double -> Double -> Diagram -> Diagram+translate 0  0  = id+translate dx dy = Ann (Attr (Translate (dx,dy)))++-- | Translate a diagram along the x-axis only.  @translateX x@ is+--   equivalent to @translate x 0@.+translateX :: Double -> Diagram -> Diagram+translateX dx = translate dx 0++-- | Translate a diagram along the y-axis only.  @translateY y@ is+--   equivalent to @translate 0 y@.+translateY :: Double -> Diagram -> Diagram+translateY dy = translate 0 dy++++-- Scale --------------------------------++-- | Scale a diagram by the given scaling factors in the x and y axes,+--   respectively.+newtype Scale = Scale Point  deriving (Eq, Show, Read)+instance AttrClass Scale where+  attrSize (Scale k) s = k .* s+  renderAttr (Scale (x,y)) = c $ C.scale x y >> return id++-- | Stretch a diagram by a separate scaling factor for each axis.+--   @stretch w h@ scales by a factor of @w@ in the x direction and+--   a factor of @h@ in the y direction.+stretch :: Double -> Double -> Diagram -> Diagram+stretch sx sy = Ann (Attr (Scale (sx,sy)))++-- | Scale by the same scaling factor in both dimensions, so the diagram+--   retains its aspect ratio.+scale :: Double -> Diagram -> Diagram+scale 1 = id+scale s = stretch s s++-- | Scale a diagram along the x-axis only.  @scaleX s@ is equivalent+--   to @stretch s 1@.+scaleX :: Double -> Diagram -> Diagram+scaleX sx = stretch sx 1++-- | Scale a diagram along the y-axis only.  @scaleY s@ is equivalent+--   to @stretch 1 s@.+scaleY :: Double -> Diagram -> Diagram+scaleY sy = stretch 1 sy
+ Graphics/Rendering/Diagrams/Colors.hs view
@@ -0,0 +1,1338 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Rendering.Diagrams.Colors+-- Copyright   :  (c) Brent Yorgey 2008+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  byorgey@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Convenient pre-defined colors for "Graphics.Rendering.Diagrams", an+-- embedded domain-specific language (EDSL) for creating simple+-- diagrams.  Color names and definitions pulled from X11\'s list of+-- colors.+--+-----------------------------------------------------------------------------+module Graphics.Rendering.Diagrams.Colors where++import Graphics.Rendering.Diagrams.Types++rgb' :: Int -> Int -> Int -> Color+rgb' r g b = rgb (fromIntegral r / 255)+                 (fromIntegral g / 255)+                 (fromIntegral b / 255)++snow                 :: Color+snow                 =  rgb' 255 250 250+ghostWhite           :: Color+ghostWhite           =  rgb' 248 248 255+whiteSmoke           :: Color+whiteSmoke           =  rgb' 245 245 245+gainsboro            :: Color+gainsboro            =  rgb' 220 220 220+floralWhite          :: Color+floralWhite          =  rgb' 255 250 240+oldLace              :: Color+oldLace              =  rgb' 253 245 230+linen                :: Color+linen                =  rgb' 250 240 230+antiqueWhite         :: Color+antiqueWhite         =  rgb' 250 235 215+papayaWhip           :: Color+papayaWhip           =  rgb' 255 239 213+blanchedAlmond       :: Color+blanchedAlmond       =  rgb' 255 235 205+bisque               :: Color+bisque               =  rgb' 255 228 196+peachPuff            :: Color+peachPuff            =  rgb' 255 218 185+navajoWhite          :: Color+navajoWhite          =  rgb' 255 222 173+moccasin             :: Color+moccasin             =  rgb' 255 228 181+cornsilk             :: Color+cornsilk             =  rgb' 255 248 220+ivory                :: Color+ivory                =  rgb' 255 255 240+lemonChiffon         :: Color+lemonChiffon         =  rgb' 255 250 205+seashell             :: Color+seashell             =  rgb' 255 245 238+honeydew             :: Color+honeydew             =  rgb' 240 255 240+mintCream            :: Color+mintCream            =  rgb' 245 255 250+azure                :: Color+azure                =  rgb' 240 255 255+aliceBlue            :: Color+aliceBlue            =  rgb' 240 248 255+lavender             :: Color+lavender             =  rgb' 230 230 250+lavenderBlush        :: Color+lavenderBlush        =  rgb' 255 240 245+mistyRose            :: Color+mistyRose            =  rgb' 255 228 225+white                :: Color+white                =  rgb' 255 255 255+black                :: Color+black                =  rgb'   0   0   0+darkSlateGray        :: Color+darkSlateGray        =  rgb'  47  79  79+darkSlateGrey        :: Color+darkSlateGrey        =  rgb'  47  79  79+dimGray              :: Color+dimGray              =  rgb' 105 105 105+dimGrey              :: Color+dimGrey              =  rgb' 105 105 105+slateGray            :: Color+slateGray            =  rgb' 112 128 144+slateGrey            :: Color+slateGrey            =  rgb' 112 128 144+lightSlateGray       :: Color+lightSlateGray       =  rgb' 119 136 153+lightSlateGrey       :: Color+lightSlateGrey       =  rgb' 119 136 153+gray                 :: Color+gray                 =  rgb' 190 190 190+grey                 :: Color+grey                 =  rgb' 190 190 190+lightGrey            :: Color+lightGrey            =  rgb' 211 211 211+lightGray            :: Color+lightGray            =  rgb' 211 211 211+midnightBlue         :: Color+midnightBlue         =  rgb'  25  25 112+navy                 :: Color+navy                 =  rgb'   0   0 128+navyBlue             :: Color+navyBlue             =  rgb'   0   0 128+cornflowerBlue       :: Color+cornflowerBlue       =  rgb' 100 149 237+darkSlateBlue        :: Color+darkSlateBlue        =  rgb'  72  61 139+slateBlue            :: Color+slateBlue            =  rgb' 106  90 205+mediumSlateBlue      :: Color+mediumSlateBlue      =  rgb' 123 104 238+lightSlateBlue       :: Color+lightSlateBlue       =  rgb' 132 112 255+mediumBlue           :: Color+mediumBlue           =  rgb'   0   0 205+royalBlue            :: Color+royalBlue            =  rgb'  65 105 225+blue                 :: Color+blue                 =  rgb'   0   0 255+dodgerBlue           :: Color+dodgerBlue           =  rgb'  30 144 255+deepSkyBlue          :: Color+deepSkyBlue          =  rgb'   0 191 255+skyBlue              :: Color+skyBlue              =  rgb' 135 206 235+lightSkyBlue         :: Color+lightSkyBlue         =  rgb' 135 206 250+steelBlue            :: Color+steelBlue            =  rgb'  70 130 180+lightSteelBlue       :: Color+lightSteelBlue       =  rgb' 176 196 222+lightBlue            :: Color+lightBlue            =  rgb' 173 216 230+powderBlue           :: Color+powderBlue           =  rgb' 176 224 230+paleTurquoise        :: Color+paleTurquoise        =  rgb' 175 238 238+darkTurquoise        :: Color+darkTurquoise        =  rgb'   0 206 209+mediumTurquoise      :: Color+mediumTurquoise      =  rgb'  72 209 204+turquoise            :: Color+turquoise            =  rgb'  64 224 208+cyan                 :: Color+cyan                 =  rgb'   0 255 255+lightCyan            :: Color+lightCyan            =  rgb' 224 255 255+cadetBlue            :: Color+cadetBlue            =  rgb'  95 158 160+mediumAquamarine     :: Color+mediumAquamarine     =  rgb' 102 205 170+aquamarine           :: Color+aquamarine           =  rgb' 127 255 212+darkGreen            :: Color+darkGreen            =  rgb'   0 100   0+darkOliveGreen       :: Color+darkOliveGreen       =  rgb'  85 107  47+darkSeaGreen         :: Color+darkSeaGreen         =  rgb' 143 188 143+seaGreen             :: Color+seaGreen             =  rgb'  46 139  87+mediumSeaGreen       :: Color+mediumSeaGreen       =  rgb'  60 179 113+lightSeaGreen        :: Color+lightSeaGreen        =  rgb'  32 178 170+paleGreen            :: Color+paleGreen            =  rgb' 152 251 152+springGreen          :: Color+springGreen          =  rgb'   0 255 127+lawnGreen            :: Color+lawnGreen            =  rgb' 124 252   0+green                :: Color+green                =  rgb'   0 255   0+chartreuse           :: Color+chartreuse           =  rgb' 127 255   0+mediumSpringGreen    :: Color+mediumSpringGreen    =  rgb'   0 250 154+greenYellow          :: Color+greenYellow          =  rgb' 173 255  47+limeGreen            :: Color+limeGreen            =  rgb'  50 205  50+yellowGreen          :: Color+yellowGreen          =  rgb' 154 205  50+forestGreen          :: Color+forestGreen          =  rgb'  34 139  34+oliveDrab            :: Color+oliveDrab            =  rgb' 107 142  35+darkKhaki            :: Color+darkKhaki            =  rgb' 189 183 107+khaki                :: Color+khaki                =  rgb' 240 230 140+paleGoldenrod        :: Color+paleGoldenrod        =  rgb' 238 232 170+lightGoldenrodYellow :: Color+lightGoldenrodYellow =  rgb' 250 250 210+lightYellow          :: Color+lightYellow          =  rgb' 255 255 224+yellow               :: Color+yellow               =  rgb' 255 255   0+gold                 :: Color+gold                 =  rgb' 255 215   0+lightGoldenrod       :: Color+lightGoldenrod       =  rgb' 238 221 130+goldenrod            :: Color+goldenrod            =  rgb' 218 165  32+darkGoldenrod        :: Color+darkGoldenrod        =  rgb' 184 134  11+rosyBrown            :: Color+rosyBrown            =  rgb' 188 143 143+indianRed            :: Color+indianRed            =  rgb' 205  92  92+saddleBrown          :: Color+saddleBrown          =  rgb' 139  69  19+sienna               :: Color+sienna               =  rgb' 160  82  45+peru                 :: Color+peru                 =  rgb' 205 133  63+burlywood            :: Color+burlywood            =  rgb' 222 184 135+beige                :: Color+beige                =  rgb' 245 245 220+wheat                :: Color+wheat                =  rgb' 245 222 179+sandyBrown           :: Color+sandyBrown           =  rgb' 244 164  96+tan                  :: Color+tan                  =  rgb' 210 180 140+chocolate            :: Color+chocolate            =  rgb' 210 105  30+firebrick            :: Color+firebrick            =  rgb' 178  34  34+brown                :: Color+brown                =  rgb' 165  42  42+darkSalmon           :: Color+darkSalmon           =  rgb' 233 150 122+salmon               :: Color+salmon               =  rgb' 250 128 114+lightSalmon          :: Color+lightSalmon          =  rgb' 255 160 122+orange               :: Color+orange               =  rgb' 255 165   0+darkOrange           :: Color+darkOrange           =  rgb' 255 140   0+coral                :: Color+coral                =  rgb' 255 127  80+lightCoral           :: Color+lightCoral           =  rgb' 240 128 128+tomato               :: Color+tomato               =  rgb' 255  99  71+orangeRed            :: Color+orangeRed            =  rgb' 255  69   0+red                  :: Color+red                  =  rgb' 255   0   0+hotPink              :: Color+hotPink              =  rgb' 255 105 180+deepPink             :: Color+deepPink             =  rgb' 255  20 147+pink                 :: Color+pink                 =  rgb' 255 192 203+lightPink            :: Color+lightPink            =  rgb' 255 182 193+paleVioletRed        :: Color+paleVioletRed        =  rgb' 219 112 147+maroon               :: Color+maroon               =  rgb' 176  48  96+mediumVioletRed      :: Color+mediumVioletRed      =  rgb' 199  21 133+violetRed            :: Color+violetRed            =  rgb' 208  32 144+magenta              :: Color+magenta              =  rgb' 255   0 255+violet               :: Color+violet               =  rgb' 238 130 238+plum                 :: Color+plum                 =  rgb' 221 160 221+orchid               :: Color+orchid               =  rgb' 218 112 214+mediumOrchid         :: Color+mediumOrchid         =  rgb' 186  85 211+darkOrchid           :: Color+darkOrchid           =  rgb' 153  50 204+darkViolet           :: Color+darkViolet           =  rgb' 148   0 211+blueViolet           :: Color+blueViolet           =  rgb' 138  43 226+purple               :: Color+purple               =  rgb' 160  32 240+mediumPurple         :: Color+mediumPurple         =  rgb' 147 112 219+thistle              :: Color+thistle              =  rgb' 216 191 216+snow1                :: Color+snow1                =  rgb' 255 250 250+snow2                :: Color+snow2                =  rgb' 238 233 233+snow3                :: Color+snow3                =  rgb' 205 201 201+snow4                :: Color+snow4                =  rgb' 139 137 137+seashell1            :: Color+seashell1            =  rgb' 255 245 238+seashell2            :: Color+seashell2            =  rgb' 238 229 222+seashell3            :: Color+seashell3            =  rgb' 205 197 191+seashell4            :: Color+seashell4            =  rgb' 139 134 130+antiqueWhite1        :: Color+antiqueWhite1        =  rgb' 255 239 219+antiqueWhite2        :: Color+antiqueWhite2        =  rgb' 238 223 204+antiqueWhite3        :: Color+antiqueWhite3        =  rgb' 205 192 176+antiqueWhite4        :: Color+antiqueWhite4        =  rgb' 139 131 120+bisque1              :: Color+bisque1              =  rgb' 255 228 196+bisque2              :: Color+bisque2              =  rgb' 238 213 183+bisque3              :: Color+bisque3              =  rgb' 205 183 158+bisque4              :: Color+bisque4              =  rgb' 139 125 107+peachPuff1           :: Color+peachPuff1           =  rgb' 255 218 185+peachPuff2           :: Color+peachPuff2           =  rgb' 238 203 173+peachPuff3           :: Color+peachPuff3           =  rgb' 205 175 149+peachPuff4           :: Color+peachPuff4           =  rgb' 139 119 101+navajoWhite1         :: Color+navajoWhite1         =  rgb' 255 222 173+navajoWhite2         :: Color+navajoWhite2         =  rgb' 238 207 161+navajoWhite3         :: Color+navajoWhite3         =  rgb' 205 179 139+navajoWhite4         :: Color+navajoWhite4         =  rgb' 139 121  94+lemonChiffon1        :: Color+lemonChiffon1        =  rgb' 255 250 205+lemonChiffon2        :: Color+lemonChiffon2        =  rgb' 238 233 191+lemonChiffon3        :: Color+lemonChiffon3        =  rgb' 205 201 165+lemonChiffon4        :: Color+lemonChiffon4        =  rgb' 139 137 112+cornsilk1            :: Color+cornsilk1            =  rgb' 255 248 220+cornsilk2            :: Color+cornsilk2            =  rgb' 238 232 205+cornsilk3            :: Color+cornsilk3            =  rgb' 205 200 177+cornsilk4            :: Color+cornsilk4            =  rgb' 139 136 120+ivory1               :: Color+ivory1               =  rgb' 255 255 240+ivory2               :: Color+ivory2               =  rgb' 238 238 224+ivory3               :: Color+ivory3               =  rgb' 205 205 193+ivory4               :: Color+ivory4               =  rgb' 139 139 131+honeydew1            :: Color+honeydew1            =  rgb' 240 255 240+honeydew2            :: Color+honeydew2            =  rgb' 224 238 224+honeydew3            :: Color+honeydew3            =  rgb' 193 205 193+honeydew4            :: Color+honeydew4            =  rgb' 131 139 131+lavenderBlush1       :: Color+lavenderBlush1       =  rgb' 255 240 245+lavenderBlush2       :: Color+lavenderBlush2       =  rgb' 238 224 229+lavenderBlush3       :: Color+lavenderBlush3       =  rgb' 205 193 197+lavenderBlush4       :: Color+lavenderBlush4       =  rgb' 139 131 134+mistyRose1           :: Color+mistyRose1           =  rgb' 255 228 225+mistyRose2           :: Color+mistyRose2           =  rgb' 238 213 210+mistyRose3           :: Color+mistyRose3           =  rgb' 205 183 181+mistyRose4           :: Color+mistyRose4           =  rgb' 139 125 123+azure1               :: Color+azure1               =  rgb' 240 255 255+azure2               :: Color+azure2               =  rgb' 224 238 238+azure3               :: Color+azure3               =  rgb' 193 205 205+azure4               :: Color+azure4               =  rgb' 131 139 139+slateBlue1           :: Color+slateBlue1           =  rgb' 131 111 255+slateBlue2           :: Color+slateBlue2           =  rgb' 122 103 238+slateBlue3           :: Color+slateBlue3           =  rgb' 105  89 205+slateBlue4           :: Color+slateBlue4           =  rgb'  71  60 139+royalBlue1           :: Color+royalBlue1           =  rgb'  72 118 255+royalBlue2           :: Color+royalBlue2           =  rgb'  67 110 238+royalBlue3           :: Color+royalBlue3           =  rgb'  58  95 205+royalBlue4           :: Color+royalBlue4           =  rgb'  39  64 139+blue1                :: Color+blue1                =  rgb'   0   0 255+blue2                :: Color+blue2                =  rgb'   0   0 238+blue3                :: Color+blue3                =  rgb'   0   0 205+blue4                :: Color+blue4                =  rgb'   0   0 139+dodgerBlue1          :: Color+dodgerBlue1          =  rgb'  30 144 255+dodgerBlue2          :: Color+dodgerBlue2          =  rgb'  28 134 238+dodgerBlue3          :: Color+dodgerBlue3          =  rgb'  24 116 205+dodgerBlue4          :: Color+dodgerBlue4          =  rgb'  16  78 139+steelBlue1           :: Color+steelBlue1           =  rgb'  99 184 255+steelBlue2           :: Color+steelBlue2           =  rgb'  92 172 238+steelBlue3           :: Color+steelBlue3           =  rgb'  79 148 205+steelBlue4           :: Color+steelBlue4           =  rgb'  54 100 139+deepSkyBlue1         :: Color+deepSkyBlue1         =  rgb'   0 191 255+deepSkyBlue2         :: Color+deepSkyBlue2         =  rgb'   0 178 238+deepSkyBlue3         :: Color+deepSkyBlue3         =  rgb'   0 154 205+deepSkyBlue4         :: Color+deepSkyBlue4         =  rgb'   0 104 139+skyBlue1             :: Color+skyBlue1             =  rgb' 135 206 255+skyBlue2             :: Color+skyBlue2             =  rgb' 126 192 238+skyBlue3             :: Color+skyBlue3             =  rgb' 108 166 205+skyBlue4             :: Color+skyBlue4             =  rgb'  74 112 139+lightSkyBlue1        :: Color+lightSkyBlue1        =  rgb' 176 226 255+lightSkyBlue2        :: Color+lightSkyBlue2        =  rgb' 164 211 238+lightSkyBlue3        :: Color+lightSkyBlue3        =  rgb' 141 182 205+lightSkyBlue4        :: Color+lightSkyBlue4        =  rgb'  96 123 139+slateGray1           :: Color+slateGray1           =  rgb' 198 226 255+slateGray2           :: Color+slateGray2           =  rgb' 185 211 238+slateGray3           :: Color+slateGray3           =  rgb' 159 182 205+slateGray4           :: Color+slateGray4           =  rgb' 108 123 139+lightSteelBlue1      :: Color+lightSteelBlue1      =  rgb' 202 225 255+lightSteelBlue2      :: Color+lightSteelBlue2      =  rgb' 188 210 238+lightSteelBlue3      :: Color+lightSteelBlue3      =  rgb' 162 181 205+lightSteelBlue4      :: Color+lightSteelBlue4      =  rgb' 110 123 139+lightBlue1           :: Color+lightBlue1           =  rgb' 191 239 255+lightBlue2           :: Color+lightBlue2           =  rgb' 178 223 238+lightBlue3           :: Color+lightBlue3           =  rgb' 154 192 205+lightBlue4           :: Color+lightBlue4           =  rgb' 104 131 139+lightCyan1           :: Color+lightCyan1           =  rgb' 224 255 255+lightCyan2           :: Color+lightCyan2           =  rgb' 209 238 238+lightCyan3           :: Color+lightCyan3           =  rgb' 180 205 205+lightCyan4           :: Color+lightCyan4           =  rgb' 122 139 139+paleTurquoise1       :: Color+paleTurquoise1       =  rgb' 187 255 255+paleTurquoise2       :: Color+paleTurquoise2       =  rgb' 174 238 238+paleTurquoise3       :: Color+paleTurquoise3       =  rgb' 150 205 205+paleTurquoise4       :: Color+paleTurquoise4       =  rgb' 102 139 139+cadetBlue1           :: Color+cadetBlue1           =  rgb' 152 245 255+cadetBlue2           :: Color+cadetBlue2           =  rgb' 142 229 238+cadetBlue3           :: Color+cadetBlue3           =  rgb' 122 197 205+cadetBlue4           :: Color+cadetBlue4           =  rgb'  83 134 139+turquoise1           :: Color+turquoise1           =  rgb'   0 245 255+turquoise2           :: Color+turquoise2           =  rgb'   0 229 238+turquoise3           :: Color+turquoise3           =  rgb'   0 197 205+turquoise4           :: Color+turquoise4           =  rgb'   0 134 139+cyan1                :: Color+cyan1                =  rgb'   0 255 255+cyan2                :: Color+cyan2                =  rgb'   0 238 238+cyan3                :: Color+cyan3                =  rgb'   0 205 205+cyan4                :: Color+cyan4                =  rgb'   0 139 139+darkSlateGray1       :: Color+darkSlateGray1       =  rgb' 151 255 255+darkSlateGray2       :: Color+darkSlateGray2       =  rgb' 141 238 238+darkSlateGray3       :: Color+darkSlateGray3       =  rgb' 121 205 205+darkSlateGray4       :: Color+darkSlateGray4       =  rgb'  82 139 139+aquamarine1          :: Color+aquamarine1          =  rgb' 127 255 212+aquamarine2          :: Color+aquamarine2          =  rgb' 118 238 198+aquamarine3          :: Color+aquamarine3          =  rgb' 102 205 170+aquamarine4          :: Color+aquamarine4          =  rgb'  69 139 116+darkSeaGreen1        :: Color+darkSeaGreen1        =  rgb' 193 255 193+darkSeaGreen2        :: Color+darkSeaGreen2        =  rgb' 180 238 180+darkSeaGreen3        :: Color+darkSeaGreen3        =  rgb' 155 205 155+darkSeaGreen4        :: Color+darkSeaGreen4        =  rgb' 105 139 105+seaGreen1            :: Color+seaGreen1            =  rgb'  84 255 159+seaGreen2            :: Color+seaGreen2            =  rgb'  78 238 148+seaGreen3            :: Color+seaGreen3            =  rgb'  67 205 128+seaGreen4            :: Color+seaGreen4            =  rgb'  46 139  87+paleGreen1           :: Color+paleGreen1           =  rgb' 154 255 154+paleGreen2           :: Color+paleGreen2           =  rgb' 144 238 144+paleGreen3           :: Color+paleGreen3           =  rgb' 124 205 124+paleGreen4           :: Color+paleGreen4           =  rgb'  84 139  84+springGreen1         :: Color+springGreen1         =  rgb'   0 255 127+springGreen2         :: Color+springGreen2         =  rgb'   0 238 118+springGreen3         :: Color+springGreen3         =  rgb'   0 205 102+springGreen4         :: Color+springGreen4         =  rgb'   0 139  69+green1               :: Color+green1               =  rgb'   0 255   0+green2               :: Color+green2               =  rgb'   0 238   0+green3               :: Color+green3               =  rgb'   0 205   0+green4               :: Color+green4               =  rgb'   0 139   0+chartreuse1          :: Color+chartreuse1          =  rgb' 127 255   0+chartreuse2          :: Color+chartreuse2          =  rgb' 118 238   0+chartreuse3          :: Color+chartreuse3          =  rgb' 102 205   0+chartreuse4          :: Color+chartreuse4          =  rgb'  69 139   0+oliveDrab1           :: Color+oliveDrab1           =  rgb' 192 255  62+oliveDrab2           :: Color+oliveDrab2           =  rgb' 179 238  58+oliveDrab3           :: Color+oliveDrab3           =  rgb' 154 205  50+oliveDrab4           :: Color+oliveDrab4           =  rgb' 105 139  34+darkOliveGreen1      :: Color+darkOliveGreen1      =  rgb' 202 255 112+darkOliveGreen2      :: Color+darkOliveGreen2      =  rgb' 188 238 104+darkOliveGreen3      :: Color+darkOliveGreen3      =  rgb' 162 205  90+darkOliveGreen4      :: Color+darkOliveGreen4      =  rgb' 110 139  61+khaki1               :: Color+khaki1               =  rgb' 255 246 143+khaki2               :: Color+khaki2               =  rgb' 238 230 133+khaki3               :: Color+khaki3               =  rgb' 205 198 115+khaki4               :: Color+khaki4               =  rgb' 139 134  78+lightGoldenrod1      :: Color+lightGoldenrod1      =  rgb' 255 236 139+lightGoldenrod2      :: Color+lightGoldenrod2      =  rgb' 238 220 130+lightGoldenrod3      :: Color+lightGoldenrod3      =  rgb' 205 190 112+lightGoldenrod4      :: Color+lightGoldenrod4      =  rgb' 139 129  76+lightYellow1         :: Color+lightYellow1         =  rgb' 255 255 224+lightYellow2         :: Color+lightYellow2         =  rgb' 238 238 209+lightYellow3         :: Color+lightYellow3         =  rgb' 205 205 180+lightYellow4         :: Color+lightYellow4         =  rgb' 139 139 122+yellow1              :: Color+yellow1              =  rgb' 255 255   0+yellow2              :: Color+yellow2              =  rgb' 238 238   0+yellow3              :: Color+yellow3              =  rgb' 205 205   0+yellow4              :: Color+yellow4              =  rgb' 139 139   0+gold1                :: Color+gold1                =  rgb' 255 215   0+gold2                :: Color+gold2                =  rgb' 238 201   0+gold3                :: Color+gold3                =  rgb' 205 173   0+gold4                :: Color+gold4                =  rgb' 139 117   0+goldenrod1           :: Color+goldenrod1           =  rgb' 255 193  37+goldenrod2           :: Color+goldenrod2           =  rgb' 238 180  34+goldenrod3           :: Color+goldenrod3           =  rgb' 205 155  29+goldenrod4           :: Color+goldenrod4           =  rgb' 139 105  20+darkGoldenrod1       :: Color+darkGoldenrod1       =  rgb' 255 185  15+darkGoldenrod2       :: Color+darkGoldenrod2       =  rgb' 238 173  14+darkGoldenrod3       :: Color+darkGoldenrod3       =  rgb' 205 149  12+darkGoldenrod4       :: Color+darkGoldenrod4       =  rgb' 139 101   8+rosyBrown1           :: Color+rosyBrown1           =  rgb' 255 193 193+rosyBrown2           :: Color+rosyBrown2           =  rgb' 238 180 180+rosyBrown3           :: Color+rosyBrown3           =  rgb' 205 155 155+rosyBrown4           :: Color+rosyBrown4           =  rgb' 139 105 105+indianRed1           :: Color+indianRed1           =  rgb' 255 106 106+indianRed2           :: Color+indianRed2           =  rgb' 238  99  99+indianRed3           :: Color+indianRed3           =  rgb' 205  85  85+indianRed4           :: Color+indianRed4           =  rgb' 139  58  58+sienna1              :: Color+sienna1              =  rgb' 255 130  71+sienna2              :: Color+sienna2              =  rgb' 238 121  66+sienna3              :: Color+sienna3              =  rgb' 205 104  57+sienna4              :: Color+sienna4              =  rgb' 139  71  38+burlywood1           :: Color+burlywood1           =  rgb' 255 211 155+burlywood2           :: Color+burlywood2           =  rgb' 238 197 145+burlywood3           :: Color+burlywood3           =  rgb' 205 170 125+burlywood4           :: Color+burlywood4           =  rgb' 139 115  85+wheat1               :: Color+wheat1               =  rgb' 255 231 186+wheat2               :: Color+wheat2               =  rgb' 238 216 174+wheat3               :: Color+wheat3               =  rgb' 205 186 150+wheat4               :: Color+wheat4               =  rgb' 139 126 102+tan1                 :: Color+tan1                 =  rgb' 255 165  79+tan2                 :: Color+tan2                 =  rgb' 238 154  73+tan3                 :: Color+tan3                 =  rgb' 205 133  63+tan4                 :: Color+tan4                 =  rgb' 139  90  43+chocolate1           :: Color+chocolate1           =  rgb' 255 127  36+chocolate2           :: Color+chocolate2           =  rgb' 238 118  33+chocolate3           :: Color+chocolate3           =  rgb' 205 102  29+chocolate4           :: Color+chocolate4           =  rgb' 139  69  19+firebrick1           :: Color+firebrick1           =  rgb' 255  48  48+firebrick2           :: Color+firebrick2           =  rgb' 238  44  44+firebrick3           :: Color+firebrick3           =  rgb' 205  38  38+firebrick4           :: Color+firebrick4           =  rgb' 139  26  26+brown1               :: Color+brown1               =  rgb' 255  64  64+brown2               :: Color+brown2               =  rgb' 238  59  59+brown3               :: Color+brown3               =  rgb' 205  51  51+brown4               :: Color+brown4               =  rgb' 139  35  35+salmon1              :: Color+salmon1              =  rgb' 255 140 105+salmon2              :: Color+salmon2              =  rgb' 238 130  98+salmon3              :: Color+salmon3              =  rgb' 205 112  84+salmon4              :: Color+salmon4              =  rgb' 139  76  57+lightSalmon1         :: Color+lightSalmon1         =  rgb' 255 160 122+lightSalmon2         :: Color+lightSalmon2         =  rgb' 238 149 114+lightSalmon3         :: Color+lightSalmon3         =  rgb' 205 129  98+lightSalmon4         :: Color+lightSalmon4         =  rgb' 139  87  66+orange1              :: Color+orange1              =  rgb' 255 165   0+orange2              :: Color+orange2              =  rgb' 238 154   0+orange3              :: Color+orange3              =  rgb' 205 133   0+orange4              :: Color+orange4              =  rgb' 139  90   0+darkOrange1          :: Color+darkOrange1          =  rgb' 255 127   0+darkOrange2          :: Color+darkOrange2          =  rgb' 238 118   0+darkOrange3          :: Color+darkOrange3          =  rgb' 205 102   0+darkOrange4          :: Color+darkOrange4          =  rgb' 139  69   0+coral1               :: Color+coral1               =  rgb' 255 114  86+coral2               :: Color+coral2               =  rgb' 238 106  80+coral3               :: Color+coral3               =  rgb' 205  91  69+coral4               :: Color+coral4               =  rgb' 139  62  47+tomato1              :: Color+tomato1              =  rgb' 255  99  71+tomato2              :: Color+tomato2              =  rgb' 238  92  66+tomato3              :: Color+tomato3              =  rgb' 205  79  57+tomato4              :: Color+tomato4              =  rgb' 139  54  38+orangeRed1           :: Color+orangeRed1           =  rgb' 255  69   0+orangeRed2           :: Color+orangeRed2           =  rgb' 238  64   0+orangeRed3           :: Color+orangeRed3           =  rgb' 205  55   0+orangeRed4           :: Color+orangeRed4           =  rgb' 139  37   0+red1                 :: Color+red1                 =  rgb' 255   0   0+red2                 :: Color+red2                 =  rgb' 238   0   0+red3                 :: Color+red3                 =  rgb' 205   0   0+red4                 :: Color+red4                 =  rgb' 139   0   0+deepPink1            :: Color+deepPink1            =  rgb' 255  20 147+deepPink2            :: Color+deepPink2            =  rgb' 238  18 137+deepPink3            :: Color+deepPink3            =  rgb' 205  16 118+deepPink4            :: Color+deepPink4            =  rgb' 139  10  80+hotPink1             :: Color+hotPink1             =  rgb' 255 110 180+hotPink2             :: Color+hotPink2             =  rgb' 238 106 167+hotPink3             :: Color+hotPink3             =  rgb' 205  96 144+hotPink4             :: Color+hotPink4             =  rgb' 139  58  98+pink1                :: Color+pink1                =  rgb' 255 181 197+pink2                :: Color+pink2                =  rgb' 238 169 184+pink3                :: Color+pink3                =  rgb' 205 145 158+pink4                :: Color+pink4                =  rgb' 139  99 108+lightPink1           :: Color+lightPink1           =  rgb' 255 174 185+lightPink2           :: Color+lightPink2           =  rgb' 238 162 173+lightPink3           :: Color+lightPink3           =  rgb' 205 140 149+lightPink4           :: Color+lightPink4           =  rgb' 139  95 101+paleVioletRed1       :: Color+paleVioletRed1       =  rgb' 255 130 171+paleVioletRed2       :: Color+paleVioletRed2       =  rgb' 238 121 159+paleVioletRed3       :: Color+paleVioletRed3       =  rgb' 205 104 137+paleVioletRed4       :: Color+paleVioletRed4       =  rgb' 139  71  93+maroon1              :: Color+maroon1              =  rgb' 255  52 179+maroon2              :: Color+maroon2              =  rgb' 238  48 167+maroon3              :: Color+maroon3              =  rgb' 205  41 144+maroon4              :: Color+maroon4              =  rgb' 139  28  98+violetRed1           :: Color+violetRed1           =  rgb' 255  62 150+violetRed2           :: Color+violetRed2           =  rgb' 238  58 140+violetRed3           :: Color+violetRed3           =  rgb' 205  50 120+violetRed4           :: Color+violetRed4           =  rgb' 139  34  82+magenta1             :: Color+magenta1             =  rgb' 255   0 255+magenta2             :: Color+magenta2             =  rgb' 238   0 238+magenta3             :: Color+magenta3             =  rgb' 205   0 205+magenta4             :: Color+magenta4             =  rgb' 139   0 139+orchid1              :: Color+orchid1              =  rgb' 255 131 250+orchid2              :: Color+orchid2              =  rgb' 238 122 233+orchid3              :: Color+orchid3              =  rgb' 205 105 201+orchid4              :: Color+orchid4              =  rgb' 139  71 137+plum1                :: Color+plum1                =  rgb' 255 187 255+plum2                :: Color+plum2                =  rgb' 238 174 238+plum3                :: Color+plum3                =  rgb' 205 150 205+plum4                :: Color+plum4                =  rgb' 139 102 139+mediumOrchid1        :: Color+mediumOrchid1        =  rgb' 224 102 255+mediumOrchid2        :: Color+mediumOrchid2        =  rgb' 209  95 238+mediumOrchid3        :: Color+mediumOrchid3        =  rgb' 180  82 205+mediumOrchid4        :: Color+mediumOrchid4        =  rgb' 122  55 139+darkOrchid1          :: Color+darkOrchid1          =  rgb' 191  62 255+darkOrchid2          :: Color+darkOrchid2          =  rgb' 178  58 238+darkOrchid3          :: Color+darkOrchid3          =  rgb' 154  50 205+darkOrchid4          :: Color+darkOrchid4          =  rgb' 104  34 139+purple1              :: Color+purple1              =  rgb' 155  48 255+purple2              :: Color+purple2              =  rgb' 145  44 238+purple3              :: Color+purple3              =  rgb' 125  38 205+purple4              :: Color+purple4              =  rgb'  85  26 139+mediumPurple1        :: Color+mediumPurple1        =  rgb' 171 130 255+mediumPurple2        :: Color+mediumPurple2        =  rgb' 159 121 238+mediumPurple3        :: Color+mediumPurple3        =  rgb' 137 104 205+mediumPurple4        :: Color+mediumPurple4        =  rgb'  93  71 139+thistle1             :: Color+thistle1             =  rgb' 255 225 255+thistle2             :: Color+thistle2             =  rgb' 238 210 238+thistle3             :: Color+thistle3             =  rgb' 205 181 205+thistle4             :: Color+thistle4             =  rgb' 139 123 139+gray0                :: Color+gray0                =  rgb'   0   0   0+grey0                :: Color+grey0                =  rgb'   0   0   0+gray1                :: Color+gray1                =  rgb'   3   3   3+grey1                :: Color+grey1                =  rgb'   3   3   3+gray2                :: Color+gray2                =  rgb'   5   5   5+grey2                :: Color+grey2                =  rgb'   5   5   5+gray3                :: Color+gray3                =  rgb'   8   8   8+grey3                :: Color+grey3                =  rgb'   8   8   8+gray4                :: Color+gray4                =  rgb'  10  10  10+grey4                :: Color+grey4                =  rgb'  10  10  10+gray5                :: Color+gray5                =  rgb'  13  13  13+grey5                :: Color+grey5                =  rgb'  13  13  13+gray6                :: Color+gray6                =  rgb'  15  15  15+grey6                :: Color+grey6                =  rgb'  15  15  15+gray7                :: Color+gray7                =  rgb'  18  18  18+grey7                :: Color+grey7                =  rgb'  18  18  18+gray8                :: Color+gray8                =  rgb'  20  20  20+grey8                :: Color+grey8                =  rgb'  20  20  20+gray9                :: Color+gray9                =  rgb'  23  23  23+grey9                :: Color+grey9                =  rgb'  23  23  23+gray10               :: Color+gray10               =  rgb'  26  26  26+grey10               :: Color+grey10               =  rgb'  26  26  26+gray11               :: Color+gray11               =  rgb'  28  28  28+grey11               :: Color+grey11               =  rgb'  28  28  28+gray12               :: Color+gray12               =  rgb'  31  31  31+grey12               :: Color+grey12               =  rgb'  31  31  31+gray13               :: Color+gray13               =  rgb'  33  33  33+grey13               :: Color+grey13               =  rgb'  33  33  33+gray14               :: Color+gray14               =  rgb'  36  36  36+grey14               :: Color+grey14               =  rgb'  36  36  36+gray15               :: Color+gray15               =  rgb'  38  38  38+grey15               :: Color+grey15               =  rgb'  38  38  38+gray16               :: Color+gray16               =  rgb'  41  41  41+grey16               :: Color+grey16               =  rgb'  41  41  41+gray17               :: Color+gray17               =  rgb'  43  43  43+grey17               :: Color+grey17               =  rgb'  43  43  43+gray18               :: Color+gray18               =  rgb'  46  46  46+grey18               :: Color+grey18               =  rgb'  46  46  46+gray19               :: Color+gray19               =  rgb'  48  48  48+grey19               :: Color+grey19               =  rgb'  48  48  48+gray20               :: Color+gray20               =  rgb'  51  51  51+grey20               :: Color+grey20               =  rgb'  51  51  51+gray21               :: Color+gray21               =  rgb'  54  54  54+grey21               :: Color+grey21               =  rgb'  54  54  54+gray22               :: Color+gray22               =  rgb'  56  56  56+grey22               :: Color+grey22               =  rgb'  56  56  56+gray23               :: Color+gray23               =  rgb'  59  59  59+grey23               :: Color+grey23               =  rgb'  59  59  59+gray24               :: Color+gray24               =  rgb'  61  61  61+grey24               :: Color+grey24               =  rgb'  61  61  61+gray25               :: Color+gray25               =  rgb'  64  64  64+grey25               :: Color+grey25               =  rgb'  64  64  64+gray26               :: Color+gray26               =  rgb'  66  66  66+grey26               :: Color+grey26               =  rgb'  66  66  66+gray27               :: Color+gray27               =  rgb'  69  69  69+grey27               :: Color+grey27               =  rgb'  69  69  69+gray28               :: Color+gray28               =  rgb'  71  71  71+grey28               :: Color+grey28               =  rgb'  71  71  71+gray29               :: Color+gray29               =  rgb'  74  74  74+grey29               :: Color+grey29               =  rgb'  74  74  74+gray30               :: Color+gray30               =  rgb'  77  77  77+grey30               :: Color+grey30               =  rgb'  77  77  77+gray31               :: Color+gray31               =  rgb'  79  79  79+grey31               :: Color+grey31               =  rgb'  79  79  79+gray32               :: Color+gray32               =  rgb'  82  82  82+grey32               :: Color+grey32               =  rgb'  82  82  82+gray33               :: Color+gray33               =  rgb'  84  84  84+grey33               :: Color+grey33               =  rgb'  84  84  84+gray34               :: Color+gray34               =  rgb'  87  87  87+grey34               :: Color+grey34               =  rgb'  87  87  87+gray35               :: Color+gray35               =  rgb'  89  89  89+grey35               :: Color+grey35               =  rgb'  89  89  89+gray36               :: Color+gray36               =  rgb'  92  92  92+grey36               :: Color+grey36               =  rgb'  92  92  92+gray37               :: Color+gray37               =  rgb'  94  94  94+grey37               :: Color+grey37               =  rgb'  94  94  94+gray38               :: Color+gray38               =  rgb'  97  97  97+grey38               :: Color+grey38               =  rgb'  97  97  97+gray39               :: Color+gray39               =  rgb'  99  99  99+grey39               :: Color+grey39               =  rgb'  99  99  99+gray40               :: Color+gray40               =  rgb' 102 102 102+grey40               :: Color+grey40               =  rgb' 102 102 102+gray41               :: Color+gray41               =  rgb' 105 105 105+grey41               :: Color+grey41               =  rgb' 105 105 105+gray42               :: Color+gray42               =  rgb' 107 107 107+grey42               :: Color+grey42               =  rgb' 107 107 107+gray43               :: Color+gray43               =  rgb' 110 110 110+grey43               :: Color+grey43               =  rgb' 110 110 110+gray44               :: Color+gray44               =  rgb' 112 112 112+grey44               :: Color+grey44               =  rgb' 112 112 112+gray45               :: Color+gray45               =  rgb' 115 115 115+grey45               :: Color+grey45               =  rgb' 115 115 115+gray46               :: Color+gray46               =  rgb' 117 117 117+grey46               :: Color+grey46               =  rgb' 117 117 117+gray47               :: Color+gray47               =  rgb' 120 120 120+grey47               :: Color+grey47               =  rgb' 120 120 120+gray48               :: Color+gray48               =  rgb' 122 122 122+grey48               :: Color+grey48               =  rgb' 122 122 122+gray49               :: Color+gray49               =  rgb' 125 125 125+grey49               :: Color+grey49               =  rgb' 125 125 125+gray50               :: Color+gray50               =  rgb' 127 127 127+grey50               :: Color+grey50               =  rgb' 127 127 127+gray51               :: Color+gray51               =  rgb' 130 130 130+grey51               :: Color+grey51               =  rgb' 130 130 130+gray52               :: Color+gray52               =  rgb' 133 133 133+grey52               :: Color+grey52               =  rgb' 133 133 133+gray53               :: Color+gray53               =  rgb' 135 135 135+grey53               :: Color+grey53               =  rgb' 135 135 135+gray54               :: Color+gray54               =  rgb' 138 138 138+grey54               :: Color+grey54               =  rgb' 138 138 138+gray55               :: Color+gray55               =  rgb' 140 140 140+grey55               :: Color+grey55               =  rgb' 140 140 140+gray56               :: Color+gray56               =  rgb' 143 143 143+grey56               :: Color+grey56               =  rgb' 143 143 143+gray57               :: Color+gray57               =  rgb' 145 145 145+grey57               :: Color+grey57               =  rgb' 145 145 145+gray58               :: Color+gray58               =  rgb' 148 148 148+grey58               :: Color+grey58               =  rgb' 148 148 148+gray59               :: Color+gray59               =  rgb' 150 150 150+grey59               :: Color+grey59               =  rgb' 150 150 150+gray60               :: Color+gray60               =  rgb' 153 153 153+grey60               :: Color+grey60               =  rgb' 153 153 153+gray61               :: Color+gray61               =  rgb' 156 156 156+grey61               :: Color+grey61               =  rgb' 156 156 156+gray62               :: Color+gray62               =  rgb' 158 158 158+grey62               :: Color+grey62               =  rgb' 158 158 158+gray63               :: Color+gray63               =  rgb' 161 161 161+grey63               :: Color+grey63               =  rgb' 161 161 161+gray64               :: Color+gray64               =  rgb' 163 163 163+grey64               :: Color+grey64               =  rgb' 163 163 163+gray65               :: Color+gray65               =  rgb' 166 166 166+grey65               :: Color+grey65               =  rgb' 166 166 166+gray66               :: Color+gray66               =  rgb' 168 168 168+grey66               :: Color+grey66               =  rgb' 168 168 168+gray67               :: Color+gray67               =  rgb' 171 171 171+grey67               :: Color+grey67               =  rgb' 171 171 171+gray68               :: Color+gray68               =  rgb' 173 173 173+grey68               :: Color+grey68               =  rgb' 173 173 173+gray69               :: Color+gray69               =  rgb' 176 176 176+grey69               :: Color+grey69               =  rgb' 176 176 176+gray70               :: Color+gray70               =  rgb' 179 179 179+grey70               :: Color+grey70               =  rgb' 179 179 179+gray71               :: Color+gray71               =  rgb' 181 181 181+grey71               :: Color+grey71               =  rgb' 181 181 181+gray72               :: Color+gray72               =  rgb' 184 184 184+grey72               :: Color+grey72               =  rgb' 184 184 184+gray73               :: Color+gray73               =  rgb' 186 186 186+grey73               :: Color+grey73               =  rgb' 186 186 186+gray74               :: Color+gray74               =  rgb' 189 189 189+grey74               :: Color+grey74               =  rgb' 189 189 189+gray75               :: Color+gray75               =  rgb' 191 191 191+grey75               :: Color+grey75               =  rgb' 191 191 191+gray76               :: Color+gray76               =  rgb' 194 194 194+grey76               :: Color+grey76               =  rgb' 194 194 194+gray77               :: Color+gray77               =  rgb' 196 196 196+grey77               :: Color+grey77               =  rgb' 196 196 196+gray78               :: Color+gray78               =  rgb' 199 199 199+grey78               :: Color+grey78               =  rgb' 199 199 199+gray79               :: Color+gray79               =  rgb' 201 201 201+grey79               :: Color+grey79               =  rgb' 201 201 201+gray80               :: Color+gray80               =  rgb' 204 204 204+grey80               :: Color+grey80               =  rgb' 204 204 204+gray81               :: Color+gray81               =  rgb' 207 207 207+grey81               :: Color+grey81               =  rgb' 207 207 207+gray82               :: Color+gray82               =  rgb' 209 209 209+grey82               :: Color+grey82               =  rgb' 209 209 209+gray83               :: Color+gray83               =  rgb' 212 212 212+grey83               :: Color+grey83               =  rgb' 212 212 212+gray84               :: Color+gray84               =  rgb' 214 214 214+grey84               :: Color+grey84               =  rgb' 214 214 214+gray85               :: Color+gray85               =  rgb' 217 217 217+grey85               :: Color+grey85               =  rgb' 217 217 217+gray86               :: Color+gray86               =  rgb' 219 219 219+grey86               :: Color+grey86               =  rgb' 219 219 219+gray87               :: Color+gray87               =  rgb' 222 222 222+grey87               :: Color+grey87               =  rgb' 222 222 222+gray88               :: Color+gray88               =  rgb' 224 224 224+grey88               :: Color+grey88               =  rgb' 224 224 224+gray89               :: Color+gray89               =  rgb' 227 227 227+grey89               :: Color+grey89               =  rgb' 227 227 227+gray90               :: Color+gray90               =  rgb' 229 229 229+grey90               :: Color+grey90               =  rgb' 229 229 229+gray91               :: Color+gray91               =  rgb' 232 232 232+grey91               :: Color+grey91               =  rgb' 232 232 232+gray92               :: Color+gray92               =  rgb' 235 235 235+grey92               :: Color+grey92               =  rgb' 235 235 235+gray93               :: Color+gray93               =  rgb' 237 237 237+grey93               :: Color+grey93               =  rgb' 237 237 237+gray94               :: Color+gray94               =  rgb' 240 240 240+grey94               :: Color+grey94               =  rgb' 240 240 240+gray95               :: Color+gray95               =  rgb' 242 242 242+grey95               :: Color+grey95               =  rgb' 242 242 242+gray96               :: Color+gray96               =  rgb' 245 245 245+grey96               :: Color+grey96               =  rgb' 245 245 245+gray97               :: Color+gray97               =  rgb' 247 247 247+grey97               :: Color+grey97               =  rgb' 247 247 247+gray98               :: Color+gray98               =  rgb' 250 250 250+grey98               :: Color+grey98               =  rgb' 250 250 250+gray99               :: Color+gray99               =  rgb' 252 252 252+grey99               :: Color+grey99               =  rgb' 252 252 252+gray100              :: Color+gray100              =  rgb' 255 255 255+grey100              :: Color+grey100              =  rgb' 255 255 255+darkGrey             :: Color+darkGrey             =  rgb' 169 169 169+darkGray             :: Color+darkGray             =  rgb' 169 169 169+darkBlue             :: Color+darkBlue             =  rgb'   0   0 139+darkCyan             :: Color+darkCyan             =  rgb'   0 139 139+darkMagenta          :: Color+darkMagenta          =  rgb' 139   0 139+darkRed              :: Color+darkRed              =  rgb' 139   0   0+lightGreen           :: Color+lightGreen           =  rgb' 144 238 144
+ Graphics/Rendering/Diagrams/Engine.hs view
@@ -0,0 +1,131 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Rendering.Diagrams.Engine+-- Copyright   :  (c) Brent Yorgey 2008+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  byorgey@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- The core rendering engine for "Graphics.Rendering.Diagrams", an+-- embedded domain-specific language (EDSL) for creating simple+-- diagrams.+--+-----------------------------------------------------------------------------++module Graphics.Rendering.Diagrams.Engine+  (+    -- * Preprocessing+    -- $preproc++    sizeAndPos++    -- * Rendering+    -- $render++    -- ** User interface++  , compose+  , writePng++    -- ** Internals++  , atomic+  , render++  ) where++import Graphics.Rendering.Diagrams.Types+import Graphics.Rendering.Diagrams.Attributes+import Graphics.Rendering.Diagrams.Layouts++import qualified Graphics.Rendering.Cairo as C+import Control.Arrow ((***))+import Control.Monad.Reader+import Data.List (foldl1')++-- $preproc+-- These functions take a user-generated 'Diagram' object and+-- preprocess it in preparation for final rendering.  The+-- preprocessing includes calculating diagram sizes and positioning+-- diagrams by the addition of appropriate translate annotations.++-- | Given a 'Diagram', compute its total size, and produce a new+--   version of the 'Diagram' with all sub-'Diagram's positioned+--   properly.+sizeAndPos :: Diagram -> (Point,Diagram)++-- the empty diagram takes up no space.+sizeAndPos Empty = ((0,0), Empty)++sizeAndPos d@(Prim (Shape s)) = (shapeSize s, d)++-- ignore the size calculated by the recursive call, and use the given+-- size instead.+sizeAndPos (Sized s d) = (s, snd $ sizeAndPos d)++-- attributes may affect the size of a diagram.+sizeAndPos (Ann a@(Attr attr) d) = (attrSize attr s, (Ann a d'))+  where (s, d') = sizeAndPos d++sizeAndPos (Compound (Layout l ds)) = (s, Union ds')+  where (s, ds') = layoutSizeAndPos l (fmap sizeAndPos ds)++-- $render+-- The rendering code takes a 'Diagram' and turns it into+-- actual graphics output, using the Cairo library to perform the low-level+-- drawing operations.++-- | Given a target width and height and a user-constructed 'Diagram',+--   render it using the Cairo rendering library.  Note that 'compose'+--   takes care of all the rendering details, including preprocessing+--   of the 'Diagram', and scaling/translating the final output so+--   that it fits within the given width and height.+--+--   The background of the output diagram will be opaque white.+--+--   In order to produce a physical output, the output of 'compose'+--   must be given as input to an output adapter such as 'writePng'.+compose :: Double      -- ^ output width+        -> Double      -- ^ output height+        -> Diagram     -- ^ 'Diagram' to render+        -> C.Render ()+compose w h d = do++  -- Preprocess the diagram, and use the global bounding box size to+  -- scale and translate the output so that it fits within the target+  -- output width and height.+  let ((x,y), d') = sizeAndPos d+      s           = min (w/x) (w/y)+  C.scale s s+  C.translate (x/2) (y/2)++  -- Set the output background to opaque white.+  C.save+  C.setSourceRGBA 1 1 1 1+  C.paint+  C.restore++  -- render the final diagram.+  flip runDiaRenderM defaultDiaRenderEnv . render $ d'++-- | Given a rendered diagram, output it to a .png file with the given+--   width and height.+writePng :: String -> Int -> Int -> C.Render () -> IO ()+writePng fileName w h render =+  C.withImageSurface C.FormatARGB32 w h $ \surface -> do+    C.renderWith surface render+    C.surfaceWriteToPNG surface fileName++-- | Perform a rendering operation atomically, by saving the state and+--   restoring it afterwards.+atomic :: DiaRenderM () -> DiaRenderM ()+atomic render = (c C.save) >> render >> (c C.restore)++-- | Render a diagram.+render :: Diagram -> DiaRenderM ()+render Empty = return ()+render (Prim (Shape s)) = renderShape s+render (Ann (Attr a) d) = atomic $ renderAttr a >>= flip local (render d)+render (Union ds) = mapM_ render ds+render (Sized _ d) = render d
+ Graphics/Rendering/Diagrams/Layouts.hs view
@@ -0,0 +1,296 @@+{-# LANGUAGE MultiParamTypeClasses #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Rendering.Diagrams.Types+-- Copyright   :  (c) Brent Yorgey 2008+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  byorgey@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Layout definitions for "Graphics.Rendering.Diagrams", an embedded+-- domain-specific language (EDSL) for creating simple diagrams.+--+-----------------------------------------------------------------------------++module Graphics.Rendering.Diagrams.Layouts+  ( -- * Union++    (##)+  , union, unionA++    -- * Lists++  , (<>), (//)+  , hcat, vcat+  , hcatA, vcatA+  , hsep, vsep+  , hsepA, vsepA+  , hdistrib, vdistrib+  , hdistribA, vdistribA++  , VAlignment+  , top, vcenter, bottom+  , HAlignment+  , left, hcenter, right++  ) where++import Graphics.Rendering.Diagrams.Types+import Graphics.Rendering.Diagrams.Attributes+import Control.Arrow ((***), first, (>>>))++-- Union -----------------------------------------------++-- | The union layout, which lays out diagrams superimposed on one+--   another.  The diagrams can be aligned both vertically and+--   horizontally.  A union layout with centered alignment in both+--   axes is simply the identity layout which does no repositioning of+--   subdiagrams.+data UnionLayout = UnionL HAlignment VAlignment+instance LayoutClass UnionLayout [] where+  layoutSizeAndPos _ [] = ((0,0), [])+  layoutSizeAndPos (UnionL halign valign) pds = ((w,h), positionedDs)+    where (sizes, diagrams) = unzip pds+          (xs, ys)          = unzip sizes+          (w,h)             = (maximum xs, maximum ys)+          xs'               = align halign w xs+          ys'               = align valign h ys+          positionedDs      = zipWith3 translate xs' ys' diagrams++-- | Create a 'Diagram' as a union of subdiagrams which will not be+--   repositioned.  If the subdiagrams overlap, they will appear with+--   the first 'Diagram' on the bottom, and the last on top.+union :: [Diagram] -> Diagram+union = unionA hcenter vcenter++-- | Superimpose one diagram atop another.  @d1 ## d2@ results in a+--   diagram in which @d2@ is on top of @d1@ (i.e., @d1@ is drawn+--   first, then @d2@).+(##) :: Diagram -> Diagram -> Diagram+d1 ## d2 = union [d1, d2]++-- | Create a 'Diagram' as a union of subdiagrams superimposed on one+--   another, aligned vertically and/or horizontally.+unionA :: HAlignment -> VAlignment -> [Diagram] -> Diagram+unionA ha va = Compound . Layout (UnionL ha va)++-- Lists -----------------------------------------------++-- | The possible ways to arrange a list of diagrams.+data ListType = H    -- ^ in a horizontal row, left to right+              | V    -- ^ in a vertical column, top to bottom+  deriving (Eq, Show, Read)++-- | A list of 'Diagram's can be aligned in one of several ways.+data Alignment = TopLeft      -- ^ Align along top/left edges, i.e. in+                              --   the negative direction+               | Center       -- ^ Align centers+               | BottomRight  -- ^ Align bottom/right edges, i.e. in+                              --   the positive direction+  deriving (Eq, Show, Read)++-- | Vertical alignment.+type VAlignment = Alignment++-- | Horizontal alignment.+type HAlignment = Alignment++top, vcenter, bottom :: VAlignment+left, hcenter, right :: HAlignment+top = TopLeft+bottom = BottomRight+left = TopLeft+right = BottomRight+vcenter = Center+hcenter = Center++-- | Compute new coordinates for the centers of the subdiagrams of a+--   list, based on the alignment.+align :: Alignment -> Double -> [Double] -> [Double]+align TopLeft     h hs = map ((/2) . (subtract h)) hs+align Center      h hs = repeat 0+align BottomRight h hs = map negate (align TopLeft h hs)++-- | A list of 'Diagram's can be distributed in one of several ways.+data Distribution = Sep Double  -- ^ Put a constant separation between+                                --   each pair of diagrams+                  | Distrib Alignment Double+                                -- ^ @Distrib align sep@ represents+                                --   evenly spaced diagrams,+                                --   distributed with the @align@ of a+                                --   diagram placed every @sep@ units.+                                --   For example, @Distrib TopLeft 50@+                                --   means that the top/left of a+                                --   diagram will occur every 50+                                --   units.+  deriving (Eq, Show, Read)++-- | A horizontal or vertical list of diagrams, with configurable+--   alignment and distribution.+data List = List ListType Alignment Distribution+instance LayoutClass List [] where+  layoutSizeAndPos _ [] = ((0,0), [])+  layoutSizeAndPos (List typ algn dist) dss =++        -- unzip sizes and diagrams, flipping sizes for a vertical layout+    let (sizes, diagrams) = first (map (mswap typ)) $ unzip dss++        -- calculate the total size, given the method of distribution+        size  = listSize  dist sizes++        -- calculate new positions for the subdiagrams, flipping+        --   positions back for a vertical layout+        pos   = map (mswap typ) $ listPosns algn dist size sizes++        -- apply appropriate translates, and flip the final size for a+        --   vertical layout+    in  (mswap typ size, zipWith (uncurry translate) pos diagrams)++-- | Conditionally swap points, so vertical lists can be laid out+--   using the same code as horizontal lists, with appropriate swaps+--   before and after layout processing.+mswap :: ListType -> Point -> Point+mswap H (x,y) = (x,y)+mswap V (x,y) = (y,x)++-- | Given a method of distribution and the sizes of the subdiagrams+--   for a horizontal list, compute the total size of the entire list+listSize :: Distribution -> [Point] -> Point+listSize (Sep sep) ss = (x,y)+  where (xs,ys) = unzip ss+        x = sum xs + (sep * fromIntegral (length ss - 1))+        y = maximum ys+listSize (Distrib _ sep) ss = (x,y)+  where x = sep * fromIntegral (length ss)+        y = maximum (map snd ss)++-- | Calculate the final positions for the centers of the subdiagrams+--   of a horizontal list, based on the alignment and distribution.+listPosns :: Alignment      -- ^ vertical alignment of list elements+          -> Distribution   -- ^ horizontal distribution+          -> Point          -- ^ pre-calculated total size of the list+          -> [Point]        -- ^ sizes of individual elements+          -> [Point]        -- ^ new coordinates for the center of+                            --   each list element+listPosns a (Sep sep) (w,h) sizes = zip xs ys+  where (ws,hs)    = unzip sizes+        offsets    = scanl (+) 0 ws+        offsWSeps  = zipWith (+) offsets (zipWith (*) [0..] (repeat sep))+        centers    = zipWith (+) (init offsWSeps) (map (/2) ws)+        xs         = map (subtract (w/2)) centers+        ys         = align a h hs++listPosns a (Distrib da sep) (w,h) sizes = zip xs ys+  where (ws,hs)    = unzip sizes+        offsets    = zipWith (*) [0..] (repeat sep)+        centers    = zipWith (+) offsets (map (centerOffs da) ws)+        centerOffs TopLeft width = width/2+        centerOffs Center  _     = sep/2+        centerOffs BottomRight width = sep - width/2+        xs         = map (subtract (w/2)) centers+        ys         = align a h hs++-- | Lay out a list of 'Diagram's horizontally from left to right,+--   aligned along their top edges.+hcat :: [Diagram] -> Diagram+hcat = hsep 0++-- | @d1 <> d2@ is a 'Diagram' with @d1@ to the left of @d2@, aligned+--   along their top edges.+(<>) :: Diagram -> Diagram -> Diagram+d1 <> d2 = hcat [d1, d2]++-- | Lay out a list of 'Diagram's horizontally from left to right,+--   with the given vertical alignment ('top', 'vcenter', or 'bottom').+hcatA :: VAlignment -> [Diagram] -> Diagram+hcatA = hsepA 0++-- | Lay out a list of 'Diagram's horizontally, aligned along their+--   top edges, with a given amount of separation in between each pair.+hsep :: Double        -- ^ amount of separation between each pair of diagrams+     -> [Diagram] -> Diagram+hsep sep = hsepA sep top++-- | Lay out a list of 'Diagram's horizontally, with the given+--   amount of separation in between each pair, using the given+--   vertical alignment ('top', 'center', or 'bottom').+hsepA :: Double       -- ^ amount of separation between each pair of diagrams+      -> VAlignment   -- ^ alignment to use ('top', 'vcenter', or 'bottom')+      -> [Diagram] -> Diagram+hsepA = sepA H++-- | Distribute a list of 'Diagram's horizontally according to a+--   regular spacing, aligned along their top edges.+hdistrib :: Double      -- ^ How far from one diagram to the next?+         -> HAlignment  -- ^ Distribute according to which parts of+                        --   the diagrams ('left', 'hcenter', 'right')?+         -> [Diagram] -> Diagram+hdistrib sep alignD = hdistribA sep alignD top++-- | Distribute a list of 'Diagram's horizontally according to a+--   regular spacing, with the given alignment.+hdistribA :: Double     -- ^ How far from one diagram to the next?+          -> HAlignment -- ^ Distribute according to which parts of+                        --   the diagrams ('left', 'hcenter', 'right')?+          -> VAlignment -- ^ alignment to use ('top', 'vcenter', 'bottom')+          -> [Diagram] -> Diagram+hdistribA = distribA H++-- | Lay out a list of 'Diagram's vertically from top to bottom,+--   aligned along their left edges.+vcat :: [Diagram] -> Diagram+vcat = vsep 0++-- | @d1 <> d2@ is a 'Diagram' with @d1@ above @d2@, aligned+--   along their left edges.+(//) :: Diagram -> Diagram -> Diagram+d1 // d2 = vcat [d1, d2]++-- | Lay out a list of 'Diagram's vertically from top to bottom,+--   with the given horizontal alignment ('left', 'hcenter', or 'right').+vcatA :: HAlignment -> [Diagram] -> Diagram+vcatA = vsepA 0++-- | Lay out a list of 'Diagram's vertically, aligned along their+--   left edges, with a given amount of separation in between each pair.+vsep :: Double       -- ^ amount of separation between each pair of diagrams+     -> [Diagram] -> Diagram+vsep sep = vsepA sep left++-- | Lay out a list of 'Diagram's vertically, with the given+--   amount of separation in between each pair, using the given+--   horizontal alignment ('left', 'hcenter', or 'right').++vsepA :: Double       -- ^ amount of separation between each pair of diagrams+      -> HAlignment   -- ^ alignment to use ('left', 'hcenter', or 'right')+      -> [Diagram] -> Diagram+vsepA = sepA V++-- | Distribute a list of 'Diagram's vertically according to a regular+--   spacing, aligned along their left edges.+vdistrib :: Double     -- ^ How far from one diagram to the next?+         -> VAlignment -- ^ Distribute according to which parts of+                       --   the diagrams ('top', 'vcenter', 'bottom')?+         -> [Diagram] -> Diagram+vdistrib sep alignD = vdistribA sep alignD left++-- | Distribute a list of 'Diagram's vertically according to a+--   regular spacing, with the given alignment.+vdistribA :: Double     -- ^ How far from one diagram to the next?+          -> VAlignment -- ^ Distribute according to which parts of+                        --   the diagrams ('top', 'vcenter', 'bottom')?+          -> HAlignment -- ^ alignment to use ('left', 'hcenter', 'right')+          -> [Diagram] -> Diagram+vdistribA = distribA V++-- | The mother-combinator for all the @sep@ functions, used+--   internally.+sepA :: ListType -> Double -> Alignment -> [Diagram] -> Diagram+sepA lt sep align = Compound . Layout (List lt align (Sep sep))++-- | The mother-combinator for all the @distrib@ functions, used+--   internally.+distribA :: ListType -> Double -> Alignment -> Alignment -> [Diagram] -> Diagram+distribA lt sep alignD align =+  Compound . Layout (List lt align (Distrib alignD sep))
+ Graphics/Rendering/Diagrams/Shapes.hs view
@@ -0,0 +1,92 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Rendering.Diagrams.Shapes+-- Copyright   :  (c) Brent Yorgey 2008+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  byorgey@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Primitive shapes out of which 'Diagram's can be built, implemented+-- via instances of 'ShapeClass'.+--+-----------------------------------------------------------------------------+module Graphics.Rendering.Diagrams.Shapes+  ( circle+  , poly+  , rect++  , draw+  ) where++import Graphics.Rendering.Diagrams.Types+import Graphics.Rendering.Diagrams.Attributes (scale)++import qualified Graphics.Rendering.Cairo as C+import Control.Arrow ((&&&), (***))+import Control.Monad.Reader++-- | Draw the shape defined by the current cairo path, using the+--   current fill color, stroke color, and stroke width settings.+draw :: DiaRenderM ()+draw = do c $ C.save+          (RGBA r g b a) <- asks envFillColor+          c $ C.setSourceRGBA r g b a+          c $ C.fillPreserve++          (RGBA r g b a) <- asks envStrokeColor+          c $ C.setSourceRGBA r g b a+          sw <- asks envStrokeWidth+          c $ fmap dist (C.deviceToUserDistance sw 0) >>= C.setLineWidth+          c $ C.stroke+          c $ C.restore+  where dist = sqrt . uncurry (+) . ((^2) *** (^2))++-- | A unit circle centered at the origin.+data Circle = Circle  deriving (Eq, Show, Read)+instance ShapeClass Circle where+  shapeSize _   = (2,2)+  renderShape _ = do+    c $ C.arc 0 0 1 0 (2*pi)+    draw++-- | @circle r@ is a circle with radius @r@.+circle :: Double -> Diagram+circle r = scale r $ Prim (Shape Circle)++++-- | @RPoly n@ is a regular n-gon centered at the origin, with a+--   vertex at (1,0).+data RPoly = RPoly Int  deriving (Eq, Show, Read)+instance ShapeClass RPoly where+  shapeSize _ = (2,2)+  renderShape (RPoly n) = do+      c $ C.moveTo 1 0+      c $ mapM_ (uncurry C.lineTo . (cos &&& sin)) $+        tail [0,2*pi/nd .. (nd-1)*2*pi/nd]+      c $ C.closePath+      draw+    where nd = fromIntegral n++-- | @poly n r@ is a regular n-gon, with a circumcircle of radius @r@.+--   One vertex is oriented along the positive x-axis.  Note that the+--   bounding box is the square circumscribed around the circumcircle.+poly :: Int -> Double -> Diagram+poly n r = scale r $ Prim (Shape (RPoly n))++++-- | @Rect w@ is a 2w (width) by 2 (height) rectangle, centered at the+--   origin.+data Rect = Rect Double  deriving (Eq, Show, Read)+instance ShapeClass Rect where+  shapeSize (Rect w) = (2*w,2)+  renderShape (Rect w) = do+    c $ C.rectangle (-w) (-1) (2*w) 2+    draw++-- | @rect w h@ is a rectangle of width @w@ and height @h@.+rect :: Double -> Double -> Diagram+rect w h = scale (h/2) $ Prim (Shape (Rect (w/h)))+
+ Graphics/Rendering/Diagrams/Types.hs view
@@ -0,0 +1,199 @@+{-# LANGUAGE ExistentialQuantification, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Rendering.Diagrams.Types+-- Copyright   :  (c) Brent Yorgey 2008+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  byorgey@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Type definitions and convenience functions for+-- "Graphics.Rendering.Diagrams", an embedded domain-specific language+-- (EDSL) for creating simple diagrams.+--+-----------------------------------------------------------------------------++module Graphics.Rendering.Diagrams.Types+  (++  -- * Primitive types++    Diagram(..)++  , Color(..), rgb, rgba+  , Point+  , (.+), (.*)++  -- * Shapes, attributes, and layouts++  , ShapeClass(..), Shape(..)+  , AttrClass(..), Attr(..)+  , LayoutClass(..), Layout(..)++  -- * Rendering++  , DiaRenderEnv(..)+  , defaultDiaRenderEnv+  , setEnvFillColor, setEnvStrokeColor, setEnvStrokeWidth+  , DiaRenderM(..)+  , runDiaRenderM+  , c++  ) where++import Graphics.Rendering.Cairo+import Control.Monad.Reader++-- | 'Diagram' is the core data type which describes a diagram.+--   'Diagram's may be constructed, transformed, combined, and+--   ultimately rendered as an image.+data Diagram = Empty                -- ^ The empty diagram+             | Prim Shape           -- ^ A primitive shape+             | Ann Attr Diagram     -- ^ An annotated diagram+             | Compound Layout      -- ^ A compound diagram+             | Union [Diagram]      -- ^ A fully processed compound+                                    --   diagram, ready for rendering+             | Sized Point Diagram+               -- ^ An explicitly sized diagram whose bounding box+               --   takes up a particular amount of space.++-- | An existential wrapper type for layouts.  A layout consists of a+--   (possibly parameterized) layout type, along with a container of+--   'Diagram's.+data Layout = forall l f. (LayoutClass l f) => Layout l (f Diagram)++-- | All layouts must be instances of 'LayoutClass', along with an+--   appropriate container type which must be an instance of Functor.+class (Functor f) => LayoutClass l f where+  -- | Given a layout and a container of @(size, diagram)@ pairs (which+  --   have already had all subdiagrams appropriately positioned),+  --   compute the overall bounding box size for this layout, as well+  --   as a list of positioned subdiagrams.+  layoutSizeAndPos :: l -> f (Point,Diagram) -> (Point, [Diagram])++-- | The 'Color' type represents colors in red-green-blue-alpha+--   format, with each channel in the range 0-1.  For a large list of+--   predefined colors, see "Graphics.Rendering.Diagrams.Colors".+data Color = RGBA Double Double Double Double+  deriving (Eq, Show, Read)++-- | Construct an opaque (alpha = 1) color from RGB values specified+--   as Doubles in the range 0-1.+rgb :: Double    -- ^ red channel+    -> Double    -- ^ green channel+    -> Double    -- ^ blue channel+    -> Color+rgb r g b = rgba r g b 1++-- | Construct a color from RGBA values, specified as Doubles in the+--   range 0-1.+rgba :: Double    -- ^ red channel+     -> Double    -- ^ green channel+     -> Double    -- ^ blue channel+     -> Double    -- ^ alpha (transparency) channel+     -> Color+rgba = RGBA++-- | Basic 2D points/vectors.+type Point = (Double,Double)++-- | Elementwise addition and multiplication for 'Point's.+(.+), (.*) :: Point -> Point -> Point+(x1,y1) .+ (x2,y2) = (x1 + x2, y1 + y2)+(x1,y1) .* (x2,y2) = (x1 * x2, y1 * y2)++-- | Existential wrapper type for attributes.+data Attr = forall a. AttrClass a => Attr a++-- | Attributes which can be applied as annotations to a 'Diagram',+--   and change the way the 'Diagram' is interpreted or rendered.+--   Every attribute must be an instance of 'AttrClass'.+class AttrClass a where++  -- | Given an attribute and the size of the diagram to which it is+  --   an annotation, return a new size for the diagram.  The default+  --   implementation is to simply return the size unchanged.+  attrSize :: a -> Point -> Point+  attrSize _ p = p++  -- | In order to implement this attribute, 'renderAttr' may perform+  --    an action in the DiaRenderM monad, and return a function which+  --    produces a local modification to the render environment. The+  --    change produced by this function will only remain in effect+  --    for any sub-diagrams, and the environment will return to its+  --    former state afterwards.+  renderAttr :: a -> DiaRenderM (DiaRenderEnv -> DiaRenderEnv)++-- | Existential wrapper type for shapes.+data Shape = forall s. ShapeClass s => Shape s++-- | The primitive shapes which can be used to build up a diagram.+--   Every primitive shape must be an instance of 'ShapeClass'.+--+--   Given a shape @s@, if @shapeSize s@ evaluates to @(w,h)@, then+--   the drawing rendered by @renderShape s@ should fit within a @w@+--   by @h@ rectangle centered at the origin.+--+--   You can create your own shape primitives by creating a new data+--   type and making it an instance of 'ShapeClass'.  If you do so,+--   you must be sure that your 'ShapeClass' instance satisfies the+--   law described above, on which the rendering engine relies in+--   order to compute the proper positions for objects in a diagram.+--   Otherwise, instances of your object in a diagram may extend+--   outside the boundaries of the rendered image, or inadvertently+--   overlap or be overlapped by other diagram elements.  Of course,+--   you are free to ignore this \"law\" as well; it will cause+--   unexpected output at worst, and at best you may find some clever+--   way to bend the system to your will. =)+--+class ShapeClass s where++  -- | Calculate the size (the dimensions of a bounding box centered+  --   at the origin) of a shape.+  shapeSize   :: s -> Point++  -- | Calculate a cairo Render action to render a shape.+  renderShape :: s -> DiaRenderM ()++-- | An environment containing additional parameters to be made+--   available while rendering, which for one reason or another are+--   not or cannot be provided by the cairo 'Render' monad itself.+--   For example, cairo only tracks one current color, so we must+--   track a fill color and stroke color separately.+data DiaRenderEnv = DREnv { envFillColor   :: Color+                          , envStrokeColor :: Color+                          , envStrokeWidth :: Double+                          }+  deriving (Show)++setEnvFillColor :: Color -> DiaRenderEnv -> DiaRenderEnv+setEnvFillColor c d = d { envFillColor = c }++setEnvStrokeColor :: Color -> DiaRenderEnv -> DiaRenderEnv+setEnvStrokeColor c d = d { envStrokeColor = c }++setEnvStrokeWidth :: Double -> DiaRenderEnv -> DiaRenderEnv+setEnvStrokeWidth c d = d { envStrokeWidth = c }++-- | The default rendering environment: transparent fill with 1-pixel+--   black strokes.+defaultDiaRenderEnv :: DiaRenderEnv+defaultDiaRenderEnv = DREnv { envFillColor   = RGBA 1 1 1 0+                            , envStrokeColor = RGBA 0 0 0 1+                            , envStrokeWidth = 1+                            }++-- | The custom rendering monad: ReaderT 'DiaRenderEnv' on top of+--   cairo's Render monad.+newtype DiaRenderM a = DRM (ReaderT DiaRenderEnv Render a)+  deriving (Functor, Monad, MonadReader DiaRenderEnv)++-- | Run a 'DiaRenderM' action, given an initial rendering+--   environment, to produce a cairo @Render@ action.+runDiaRenderM :: DiaRenderM a -> DiaRenderEnv -> Render a+runDiaRenderM (DRM m) e = runReaderT m e++-- | Lift a cairo @Render@ action into a 'DiaRenderM' action.+c :: Render a -> DiaRenderM a+c = DRM . lift
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) Brent Yorgey 2008++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of other contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ README view
@@ -0,0 +1,49 @@++Graphics.Rendering.Diagrams provides an embedded domain-specific+language (EDSL) for creating simple diagrams in a compositional style.++------------------------------------------------------------------------++Building:++Get the dependencies++    The diagrams library uses Haskell bindings to the Cairo vector+    graphics library.  In order to build the diagrams library, you+    will first need the following:++    * The Cairo library itself.  This is probably available through+      your system's package manager and may even already be installed.+      On Ubuntu, for example, it is available from the 'libcairo'+      package.++    * The Haskell cairo bindings, which are packaged as part of+      gtk2hs.  Unfortunately, for various technical reasons, gtk2hs is+      not cabalized and cannot be downloaded and installed from+      Hackage.  To get gtk2hs you will need to go to the gtk2hs+      website (http://www.haskell.org/gtk2hs/) and follow the+      instructions to download and build it.+++Build with Cabal:++    runhaskell Setup.lhs configure --prefix=$HOME --user+    runhaskell Setup.lhs build+    runhaskell Setup.lhs install++    (Optionally, you can omit the --prefix and --user arguments to the+    configure step, and run the install step with 'sudo' in order to+    install the library systemwide.)+++Building Haddock documentation (recommended):++    runhaskell Setup.lhs haddock++    Once the documentation has been built, you can access it by +    pointing your browser to dist/doc/html/index.html.+++For some examples of use, see ++http://byorgey.wordpress.com/2008/04/30/new-haskell-diagrams-library/
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ diagrams.cabal view
@@ -0,0 +1,22 @@+Name:                diagrams+Version:             0.1+Stability:           experimental+Description:         An embedded domain-specific language (EDSL) for +                     creating simple diagrams, built on top of the Cairo+                     rendering engine.  +Synopsis:            An EDSL for creating simple diagrams+License:             BSD3+License-file:        LICENSE+Extra-source-files:  README+Author:              Brent Yorgey+Maintainer:          byorgey@gmail.com+Category:            Graphics+Build-Depends:       base,mtl,cairo+Build-type:          Simple+Exposed-Modules:     Graphics.Rendering.Diagrams,+                     Graphics.Rendering.Diagrams.Types,+                     Graphics.Rendering.Diagrams.Shapes,+                     Graphics.Rendering.Diagrams.Attributes,+                     Graphics.Rendering.Diagrams.Layouts,+                     Graphics.Rendering.Diagrams.Colors,+                     Graphics.Rendering.Diagrams.Engine