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 +182/−0
- Graphics/Rendering/Diagrams/Attributes.hs +193/−0
- Graphics/Rendering/Diagrams/Colors.hs +1338/−0
- Graphics/Rendering/Diagrams/Engine.hs +131/−0
- Graphics/Rendering/Diagrams/Layouts.hs +296/−0
- Graphics/Rendering/Diagrams/Shapes.hs +92/−0
- Graphics/Rendering/Diagrams/Types.hs +199/−0
- LICENSE +27/−0
- README +49/−0
- Setup.lhs +3/−0
- diagrams.cabal +22/−0
+ 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