packages feed

diagrams-cairo 0.5.0.2 → 0.6

raw patch · 13 files changed

+637/−301 lines, 13 filesdep +colourdep +timedep −gtkdep ~basedep ~cairodep ~cmdargsPVP ok

version bump matches the API change (PVP)

Dependencies added: colour, time

Dependencies removed: gtk

Dependency ranges changed: base, cairo, cmdargs, diagrams-core, diagrams-lib, directory, filepath, old-time, process, split, unix

API changes (from Hackage documentation)

- Diagrams.Backend.Cairo: GTK :: dw -> Bool -> OutputType
- Diagrams.Backend.Cairo: gtkBypass :: OutputType -> Bool
- Diagrams.Backend.Cairo: gtkWindow :: OutputType -> dw
- Diagrams.Backend.Cairo.Gtk: defaultRender :: Monoid' m => DrawingArea -> QDiagram Cairo R2 m -> IO ()
- Diagrams.Backend.Cairo.Gtk: renderToGtk :: (DrawableClass dc, Monoid' m) => dc -> QDiagram Cairo R2 m -> IO ()
- Diagrams.Backend.Cairo.Gtk: toGtkCoords :: Monoid' m => QDiagram Cairo R2 m -> QDiagram Cairo R2 m
- Diagrams.Backend.Cairo.Internal: GTK :: dw -> Bool -> OutputType
- Diagrams.Backend.Cairo.Internal: gtkBypass :: OutputType -> Bool
- Diagrams.Backend.Cairo.Internal: gtkWindow :: OutputType -> dw
- Diagrams.Backend.Cairo.Text: textLineBounded, textVisualBounded :: StyleParam -> String -> Diagram Cairo R2
- Diagrams.Backend.Cairo.Text: type StyleParam = forall a. HasStyle a => a -> a
+ Diagrams.Backend.Cairo: RenderOnly :: OutputType
+ Diagrams.Backend.Cairo.Internal: RenderOnly :: OutputType
+ Diagrams.Backend.Cairo.List: renderToList :: (Ord a, Floating a) => Int -> Int -> Diagram Cairo R2 -> IO [[AlphaColour a]]
+ Diagrams.Backend.Cairo.Ptr: renderForeignPtr :: Int -> Int -> Diagram Cairo R2 -> IO (ForeignPtr Word8)
+ Diagrams.Backend.Cairo.Ptr: renderPtr :: Int -> Int -> Diagram Cairo R2 -> IO (Ptr Word8)
+ Diagrams.Backend.Cairo.Text: textLineBounded :: Style R2 -> String -> Diagram Cairo R2
+ Diagrams.Backend.Cairo.Text: textVisualBounded :: Style R2 -> String -> Diagram Cairo R2
- Diagrams.Backend.Cairo.Text: cairoWithStyle :: Render a -> StyleParam -> Render a
+ Diagrams.Backend.Cairo.Text: cairoWithStyle :: Render a -> Style R2 -> Render a
- Diagrams.Backend.Cairo.Text: getExtents :: StyleParam -> String -> Render (FontExtents, TextExtents)
+ Diagrams.Backend.Cairo.Text: getExtents :: Style R2 -> String -> Render (FontExtents, TextExtents)
- Diagrams.Backend.Cairo.Text: getFontExtents :: StyleParam -> Render FontExtents
+ Diagrams.Backend.Cairo.Text: getFontExtents :: Style R2 -> Render FontExtents
- Diagrams.Backend.Cairo.Text: getTextExtents :: StyleParam -> String -> Render TextExtents
+ Diagrams.Backend.Cairo.Text: getTextExtents :: Style R2 -> String -> Render TextExtents
- Diagrams.Backend.Cairo.Text: kerningCorrection :: StyleParam -> Char -> Char -> Double
+ Diagrams.Backend.Cairo.Text: kerningCorrection :: Style R2 -> Char -> Char -> Double
- Diagrams.Backend.Cairo.Text: kerningCorrectionIO :: StyleParam -> Char -> Char -> IO Double
+ Diagrams.Backend.Cairo.Text: kerningCorrectionIO :: Style R2 -> Char -> Char -> IO Double
- Diagrams.Backend.Cairo.Text: textLineBoundedIO :: StyleParam -> String -> IO (Diagram Cairo R2)
+ Diagrams.Backend.Cairo.Text: textLineBoundedIO :: Style R2 -> String -> IO (Diagram Cairo R2)
- Diagrams.Backend.Cairo.Text: textVisualBoundedIO :: StyleParam -> String -> IO (Diagram Cairo R2)
+ Diagrams.Backend.Cairo.Text: textVisualBoundedIO :: Style R2 -> String -> IO (Diagram Cairo R2)

Files

− CHANGES
@@ -1,84 +0,0 @@-0.5.0.2 : 13 May 2012--  * Allow building under mtl 2.1.*--0.5.0.1 : 9 March 2012--  * Remove statement in package description that a development version-    of gtk2hs must be used with GHC 7.4; this is no longer true as of-    the 0.12.3 release of gtk2hs.--0.5: 9 March 2012--  * New features--    - New Diagrams.Backend.Cairo.Text module by Michael Sloan, with-      functions for creating appropriately sized text objects by-      querying cairo for the size, and related supporting functions.--    - Basic support for animation, by generating frames sampled at-      regular intervals.--    - Proper vertical alignment of default text based on font-      parameters (Michael Sloan).--    - Requesting just a width or height now causes the other to be-      computed appropriately.--  * API changes--    - Move "Diagrams.Backend.Cairo" to-      "Diagrams.Backend.Cairo.Internal" and export everything.-      "Diagrams.Backend.Cairo" now just re-exports selected functions-      from Internal.  This allows anyone who wants access to the-      helper/utility functions to import Internal.--  * Dependency/version changes--    - relax cmdargs upper bound-    - GHC 7.4.1 compatibility: update base, filepath, old-time upper bounds--  * Bug fixes--    - #54: Generate warning for missing image files (Ian Ross).--0.4: 22 October 2011--  * New features:-    + Support for drawing directly to Gtk widgets-    + Support for path fill rule attribute--  * New/improved examples--  * Improved documentation--  * Bug fixes:-    + Warning for unsupported image types (#41)--0.3: 18 June 2011--  * Some new/improved examples--  * New features:-    + simple text support-    + simple support for external PNG images--0.2: 3 June 2011--  * add Typeable and other instances for Cairo type--  * generalize Result type to (IO (), Render ()), so programs that-    don't want to generate a file but just want a Render operation-    (e.g. to use to paint a gtk window) can use the second component.--  * add support for opacity attribute and path clipping--0.1.2: 18 May 2011-  * link to new website--0.1.1: 18 May 2011-  * fix tic-tac-toe example--0.1: 17 May 2011-  * initial preview release-
+ CHANGES.markdown view
@@ -0,0 +1,148 @@+0.6: 11 December 2012+---------------------++* **New features**++    - New `--list` option for `multiMain` to list all available diagrams++    - Major documentation improvements++    - New modules:++        + `Diagrams.Backend.Cairo.Ptr`, for rendering directly to buffers+          in memory++        + `Diagrams.Backend.Cairo.List`, for rendering to a list of lists+          of pixels.++* **API changes**++    - Removal of `StyleParam` from `Diagrams.Backend.Cairo.Text`, change+      functions in that module to accept `Style R2`.  Usage can be fixed+      by applying these style functions to `mempty`.++    - GTK rendering has been split out into a new package, diagrams-gtk.++	+ The `Diagrams.Backend.Cairo.Gtk` module is now+	  `Diagrams.Backend.Gtk` in the `diagrams-gtk` package.++	+ The `CairoOptions` record has a new boolean `cairoBypassAdjust`+	  option; when set, the backend should bypass calling `adjustDia2D`.++	+ The GTK output type is gone.++	+ There is a new `RenderOnly` output type, for when you don't+	  care about the `IO` action but only want the cairo `Render` action.++* **Dependency/version changes**++    - Upper bounds relaxed to allow+      `base`-4.6, `unix`-2.6, `cmdargs`-0.10, `split`-0.2.*, `mtl`-2.1++    - Add a dependency on `time`, and conditional compilation to use+      either ClockTime or UTCTime depending on the version of the+      `directory` package++    - Add dependency on `colour`++    - Lower bound on `cairo` raised to 0.12.4+    +* **Bug fixes**++    - Fixed looped compile mode, which was repeatedly trying to compile+      when the code contained errors, instead of trying once and then+      waiting for a change.++    - Fix a bug where default attributes were not being set when using+      the "bypass" mode used by the gtk backend. ([\#16](https://github.com/diagrams/diagrams-cairo/pull/16))++0.5.0.2 : 13 May 2012+---------------------++* Allow building under `mtl` 2.1.*++0.5.0.1 : 9 March 2012+----------------------++* Remove statement in package description that a development version+    of `gtk2hs` must be used with GHC 7.4; this is no longer true as of+    the 0.12.3 release of `gtk2hs`.++0.5: 9 March 2012+-----------------++* **New features**+    - New `Diagrams.Backend.Cairo.Text` module by Michael Sloan, with+      functions for creating appropriately sized text objects by+      querying cairo for the size, and related supporting functions.+    - Basic support for animation with `animMain` function, by+      generating frames sampled at regular intervals.+    - Proper vertical alignment of default text based on font+      parameters (Michael Sloan).+    - Requesting just a width or height now causes the other to be+      computed appropriately.++* **API changes**+    - Move `Diagrams.Backend.Cairo` to+      `Diagrams.Backend.Cairo.Internal` and export everything.+      `Diagrams.Backend.Cairo` now just re-exports selected functions+      from `Internal`.  This allows anyone who wants access to the+      helper/utility functions to import `Internal`.++* **Dependency/version changes**+    - relax `cmdargs` upper bound+    - GHC 7.4.1 compatibility: update `base`, `filepath`, and+      `old-time` upper bounds++* **Bug fixes**+    - [\#54](http://code.google.com/p/diagrams/issues/detail?id=54): Generate warning for missing image files (Ian Ross).++0.4: 22 October 2011+--------------------++* New features:+    + Support for drawing directly to Gtk widgets+    + Support for path fill rule attribute++* New/improved examples++* Improved documentation++* Bug fixes:+    + Warning for unsupported image types (#41)++0.3: 18 June 2011+-----------------++* Some new/improved examples++* New features:+    + simple text support+    + simple support for external PNG images++0.2: 3 June 2011+----------------++* add `Typeable` and other instances for `Cairo` type++* generalize `Result` type to `(IO (), Render ())`, so programs that+    don't want to generate a file but just want a `Render` operation+    (*e.g.* to use to paint a gtk window) can use the second component.++* add support for opacity attribute and path clipping++0.1.2: 18 May 2011+------------------++* link to new website++0.1.1: 18 May 2011+------------------++* fix tic-tac-toe example++0.1: 17 May 2011+----------------++* initial preview release+
LICENSE view
@@ -1,6 +1,7 @@ Copyright 2011-2012 diagrams-cairo team:    Sam Griffin <sam.griffin@gmail.com>+  Niklas Haas <nand@lavabit.com>   John Lato <jwlato@gmail.com>   Ian Ross <ian@skybluetrades.net>   Michael Sloan <mgsloan@gmail.com>
− README
@@ -1,9 +0,0 @@-A rendering backend for diagrams, a Haskell embedded domain-specific-language for compositional, declarative drawing.  See--  http://projects.haskell.org/diagrams/--for more information about the project, including installation-instructions, tutorials, a user manual, a gallery of example images,-and links to the mailing list, IRC channel, developer wiki and bug-tracker.
+ README.markdown view
@@ -0,0 +1,71 @@+[![Build Status](https://secure.travis-ci.org/diagrams/diagrams-cairo.png)](http://travis-ci.org/diagrams/diagrams-cairo)++_diagrams-cairo_ is a rendering backend for [diagrams], a powerful,+flexible, declarative domain-specific language for creating vector graphics,+using the [Haskell programming language][haskell].++[diagrams]: http://projects.haskell.org/diagrams/+[haskell]: http://www.haskell.org/haskellwiki/Haskell++_diagrams-cairo_ is implemented using the [cairo] rendering engine and+is a fully-featured, officially supported backend for diagrams.++[cairo]: http://www.cairographics.org/++# Installation++```+cabal update && cabal install gtk2hs-buildtools diagrams-cairo+```++# Basic usage++A simple example that uses _diagrams-cairo_ to draw a blue circle:++```haskell+import Diagrams.Prelude+import Diagrams.Backend.Cairo.CmdLine++d = circle 1 # fc blue++main = defaultMain (pad 1.1 d)+```++Save this to file named `Circle.hs` and compile it:++```+ghc --make Circle.hs+```++This will generate an executable which, when run, outputs a blue+circle to some file. Run the executable with the `--help` option to+find out more about how to call it.++```+$ ./Circle --help+Command-line diagram generation.++Circle [OPTIONS]++Common flags:+  -w --width=INT    Desired width of the output image+  -h --height=INT   Desired height of the output image+  -o --output=FILE  Output file+  -? --help         Display help message+  -V --version      Print version information+```++The output type will be automatically determined from the file+extension.  Currently PNG, PDF, PS, and SVG are supported.++```+$ ./Circle -o circle.png -w 400+```++The command above generates a PNG file with a width of 400px.++# Advanced usage++Instead of just creating a standalone executable, the cairo backend+can also be called from within a larger program.  For more+information, see the Diagram.Backend.Cairo module.
diagrams-cairo.cabal view
@@ -1,50 +1,68 @@ Name:                diagrams-cairo-Version:             0.5.0.2+Version:             0.6 Synopsis:            Cairo backend for diagrams drawing EDSL Description:         A full-featured backend for rendering                      diagrams using the cairo rendering engine.-                     To get started, see "Diagrams.Backend.Cairo.CmdLine".+                     .+                     * "Diagrams.Backend.Cairo.CmdLine" - if you're+                       just getting started with diagrams, begin here.+                     .+                     * "Diagrams.Backend.Cairo" - look at this next.+                       The general API for the cairo backend.+                     .+                     * "Diagrams.Backend.Cairo.Internal" - the+                       implementation guts of the cairo backend.+                       Users should normally not need to import this+                       module.+                     .+                     * "Diagrams.Backend.Cairo.Text" - cairo-specific+                       text support, including automatic bounding+                       boxes.+                     .+                     * "Diagrams.Backend.Cairo.List" - render diagrams+                       to two-dimensional lists of colors (/i.e./+                       pixels).+                     .+                     * "Diagrams.Backend.Cairo.Ptr" - render diagrams+                       to buffers in memory. Homepage:            http://projects.haskell.org/diagrams License:             BSD3 License-file:        LICENSE Author:              Brent Yorgey Maintainer:          diagrams-discuss@googlegroups.com+Bug-reports:         http://github.com/diagrams/diagrams-cairo/issues Category:            Graphics Build-type:          Simple-Cabal-version:       >=1.6-Extra-source-files:  CHANGES, README-Tested-with:         GHC == 6.12.3, GHC == 7.0.4, GHC == 7.2.1, GHC == 7.4.1+Cabal-version:       >=1.10+Extra-source-files:  CHANGES.markdown, README.markdown+Tested-with:         GHC == 7.2.1, GHC == 7.4.2, GHC == 7.6.1 Source-repository head-  type:     darcs-  location: http://patch-tag.com/r/byorgey/diagrams-cairo+  type:     git+  location: http://github.com/diagrams/diagrams-cairo.git  Library   Exposed-modules:     Diagrams.Backend.Cairo                        Diagrams.Backend.Cairo.CmdLine-                       Diagrams.Backend.Cairo.Gtk                        Diagrams.Backend.Cairo.Internal+                       Diagrams.Backend.Cairo.List+                       Diagrams.Backend.Cairo.Ptr                        Diagrams.Backend.Cairo.Text   Hs-source-dirs:      src-  Build-depends:       base >= 4.2 && < 4.6,+  Build-depends:       base >= 4.2 && < 4.7,                        mtl >= 2.0 && < 2.2,-                       process >= 1.0 && < 1.2,-                       directory >= 1.0 && < 1.2,-                       filepath >= 1.1 && < 1.4,-                       old-time >= 1.0 && < 1.2,-                       diagrams-core >= 0.5 && < 0.6,-                       diagrams-lib >= 0.5 && < 0.6,-                       cairo >= 0.10.1 && < 0.13,-                       cmdargs >= 0.6 && < 0.10,-                       gtk >= 0.12.0  && < 0.13.0,-                       split >= 0.1.2 && < 0.2+                       process,+                       directory,+                       filepath,+                       old-time,+                       time,+                       diagrams-core >= 0.6 && < 0.7,+                       diagrams-lib >= 0.6 && < 0.7,+                       cairo >= 0.12.4 && < 0.13,+                       cmdargs >= 0.6 && < 0.11,+                       colour,+                       split >= 0.1.2 && < 0.3+  default-language:    Haskell2010+   if !os(windows)     cpp-options: -DCMDLINELOOP-    Build-depends:     unix >= 2.4 && < 2.6--  if impl(ghc >= 7.2.1 && < 7.4)-    Build-depends:     cairo >= 0.12.1,-                       gtk   >= 0.12.1--  if impl(ghc >= 7.4.1)-    Build-depends:     cairo >= 0.12.3,-                       gtk   >= 0.12.3+    Build-depends:     unix >= 2.4 && < 2.7
src/Diagrams/Backend/Cairo.hs view
@@ -10,6 +10,46 @@ -- A full-featured rendering backend for diagrams using the -- cairo rendering engine. --+-- To invoke the cairo backend, use methods from the+-- 'Diagrams.Core.Types.Backend' instance for @Cairo@.  In particular,+-- 'Diagrams.Core.Types.renderDia' has the generic type+--+-- > renderDia :: b -> Options b v -> QDiagram b v m -> Result b v+--+-- (omitting a few type class constraints).  @b@ represents the+-- backend type, @v@ the vector space, and @m@ the type of monoidal+-- query annotations on the diagram.  'Options' and 'Result' are+-- associated data and type families, respectively, which yield the+-- type of option records and rendering results specific to any+-- particular backend.  For @b ~ Cairo@ and @v ~ R2@, we have+--+-- > data family Options Cairo R2 = CairoOptions+-- >          { cairoFileName     :: String     -- ^ The name of the file you want generated+-- >          , cairoSizeSpec     :: SizeSpec2D -- ^ The requested size of the output+-- >          , cairoOutputType   :: OutputType -- ^ the output format and associated options+-- >          , cairoBypassAdjust :: Bool       -- ^ Should the 'adjustDia' step be bypassed during rendering?+-- >          }+--+-- @+-- data family Render Cairo R2 = C ('RenderM' ())+-- @+--+-- @+-- type family Result Cairo R2 = (IO (), 'Graphics.Rendering.Cairo.Render' ())+-- @+--+-- So the type of 'renderDia' resolves to+--+-- @+-- renderDia :: Cairo -> Options Cairo R2 -> QDiagram Cairo R2 m -> (IO (), 'Graphics.Rendering.Cairo.Render' ())+-- @+--+-- which you could call like @renderDia Cairo (CairoOptions "foo.png"+-- (Width 250) PNG) myDiagram@.  This would return a pair; the first+-- element is an @IO ()@ action which will write out @foo.png@ to+-- disk, and the second is a cairo rendering action which can be used,+-- for example, to directly draw to a Gtk window.+-- ----------------------------------------------------------------------------- module Diagrams.Backend.Cairo @@ -55,6 +95,8 @@ -- -- > renderDia Cairo (CairoOptions "foo.png" (Width 250) PNG) myDiagram ----- /Important note/: a bug in GHC 7.0.x prevents re-exporting this--- data family.  To bring CairoOptions into scope when using GHC 7.0.x--- you must import "Diagrams.Backend.Cairo.Internal".+-- /Important note/: a bug in GHC 7.0.x and 7.4.1 prevents+-- re-exporting this data family.  (Strangely, this bug seems to be+-- present in 7.0 and 7.4 but not 7.2.) To bring CairoOptions into+-- scope when using GHC 7.0.x or 7.4 you must import+-- "Diagrams.Backend.Cairo.Internal".
src/Diagrams/Backend/Cairo/CmdLine.hs view
@@ -9,6 +9,26 @@ -- Convenient creation of command-line-driven executables for -- rendering diagrams using the cairo backend. --+-- * 'defaultMain' creates an executable which can render a single+--   diagram at various options.+--+-- * 'multiMain' is like 'defaultMain' but allows for a list of+--   diagrams from which the user can choose one to render.+--+-- * 'animMain' is like 'defaultMain' but for animations instead of+--   diagrams.+--+-- If you want to generate diagrams programmatically---/i.e./ if you+-- want to do anything more complex than what the below functions+-- provide---you have several options.+--+-- * A simple but somewhat inflexible approach is to wrap up+--   'defaultMain' (or 'multiMain', or 'animMain') in a call to+--   'System.Environment.withArgs'.+--+-- * A more flexible approach is to directly call 'renderDia'; see+--   "Diagrams.Backend.Cairo" for more information.+-- -----------------------------------------------------------------------------  module Diagrams.Backend.Cairo.CmdLine@@ -19,6 +39,7 @@        , Cairo        ) where +import Data.List (intercalate) import Diagrams.Prelude hiding (width, height, interval) import Diagrams.Backend.Cairo @@ -33,7 +54,7 @@ import Prelude hiding      (catch)  import Data.Maybe          (fromMaybe)-import Control.Monad       (when, forM_)+import Control.Monad       (when, forM_, mplus) import Data.List.Split  import Text.Printf@@ -45,18 +66,29 @@ import System.IO           (openFile, hClose, IOMode(..),                             hSetBuffering, BufferMode(..), stdout) import System.Exit         (ExitCode(..))-import System.Time         (ClockTime, getClockTime) import Control.Concurrent  (threadDelay) import Control.Exception   (catch, SomeException(..), bracket)  #ifdef CMDLINELOOP import System.Posix.Process (executeFile)+#if MIN_VERSION_directory(1,2,0)+import Data.Time.Clock (UTCTime,getCurrentTime)+type ModuleTime = UTCTime+getModuleTime :: IO  ModuleTime+getModuleTime = getCurrentTime+#else+import System.Time         (ClockTime, getClockTime)+type ModuleTime = ClockTime+getModuleTime :: IO  ModuleTime+getModuleTime = getClockTime #endif+#endif  data DiagramOpts = DiagramOpts                    { width     :: Maybe Int                    , height    :: Maybe Int                    , output    :: FilePath+                   , list      :: Bool                    , selection :: Maybe String                    , fpu       :: Double #ifdef CMDLINELOOP@@ -85,6 +117,9 @@               &= help "Name of the diagram to render"               &= (if sel then typ "NAME" else ignore) +  , list = def+         &= (if sel then help "List all available diagrams" else ignore)+   , fpu = 30           &= typ "FLOAT"           &= help "Frames per unit time (for animations)"@@ -104,20 +139,52 @@ -- | This is the simplest way to render diagrams, and is intended to --   be used like so: ----- > ... definitions ...+-- > ... other definitions ...+-- > myDiagram = ... -- > -- > main = defaultMain myDiagram -----   Compiling this file will result in an executable which takes---   various command-line options for setting the size, output file,---   and so on, and renders @myDiagram@ with the specified options.+--   Compiling a source file like the above example will result in an+--   executable which takes command-line options for setting the size,+--   output file, and so on, and renders @myDiagram@ with the+--   specified options. -- --   On Unix systems, the generated executable also supports a --   rudimentary \"looped\" mode, which watches the source file for --   changes and recompiles itself on the fly. -- --   Pass @--help@ to the generated executable to see all available---   options.+--   options.  Currently it looks something like+--+-- @+-- Command-line diagram generation.+--+-- Foo [OPTIONS]+--+-- Common flags:+--   -w --width=INT         Desired width of the output image+--   -h --height=INT        Desired height of the output image+--   -o --output=FILE       Output file+--   -f --fpu=FLOAT         Frames per unit time (for animations)+--   -l --loop              Run in a self-recompiling loop+--   -s --src=FILE          Source file to watch+--   -i --interval=SECONDS  When running in a loop, check for changes every n+--                          seconds.+--   -? --help              Display help message+--   -V --version           Print version information+-- @+--+--   For example, a couple common scenarios include+--+-- @+-- $ ghc --make MyDiagram+--+--   # output image.png with a width of 400px (and auto-determined height)+-- $ ./MyDiagram -o image.png -w 400+--+--   # output 200x200 dia.pdf, then watch for changes every 10 seconds+-- $ ./MyDiagram -o dia.pdf -h 200 -w 200 -l -i 10+-- @  defaultMain :: Diagram Cairo R2 -> IO () defaultMain d = do@@ -140,49 +207,74 @@                  "pdf" -> PDF                  "svg" -> SVG                  _     -> PDF-               sizeSpec = case (width opts, height opts) of-                            (Nothing, Nothing) -> Absolute-                            (Just w, Nothing)  -> Width (fromIntegral w)-                            (Nothing, Just h)  -> Height (fromIntegral h)-                            (Just w, Just h)   -> Dims (fromIntegral w)-                                                       (fromIntegral h)-           fst $ renderDia Cairo (CairoOptions-                                    (output opts)-                                    sizeSpec-                                    outTy-                                 )-                           d+           fst $ renderDia+                   Cairo+                   ( CairoOptions+                     (output opts)+                     (mkSizeSpec+                       (fromIntegral <$> width opts)+                       (fromIntegral <$> height opts)+                     )+                     outTy+                     False+                   )+                   d        | otherwise -> putStrLn $ "Unknown file type: " ++ last ps  -- | @multiMain@ is like 'defaultMain', except instead of a single --   diagram it takes a list of diagrams paired with names as input.---   The generated executable then takes an argument specifying the---   name of the diagram that should be rendered.  This is a---   convenient way to create an executable that can render many---   different diagrams without modifying the source code in between---   each one.+--   The generated executable then takes a @--selection@ option+--   specifying the name of the diagram that should be rendered.  The+--   list of available diagrams may also be printed by passing the+--   option @--list@.+--+--   Example usage:+--+-- @+-- $ ghc --make MultiTest+-- [1 of 1] Compiling Main             ( MultiTest.hs, MultiTest.o )+-- Linking MultiTest ...+-- $ ./MultiTest --list+-- Available diagrams:+--   foo bar+-- $ ./MultiTest --selection bar -o Bar.png -w 200+-- @+ multiMain :: [(String, Diagram Cairo R2)] -> IO () multiMain ds = do   prog <- getProgName   opts <- cmdArgs (diagramOpts prog True)-  case selection opts of-    Nothing  -> putStrLn "No diagram selected."-    Just sel -> case lookup sel ds of-      Nothing -> putStrLn $ "Unknown diagram: " ++ sel-      Just d  -> chooseRender opts d+  if list opts+    then showDiaList (map fst ds)+    else+      case selection opts of+        Nothing  -> putStrLn "No diagram selected." >> showDiaList (map fst ds)+        Just sel -> case lookup sel ds of+          Nothing -> putStrLn $ "Unknown diagram: " ++ sel+          Just d  -> chooseRender opts d --- | @animMain@ takes an animation and produces a command-line program---   which will crudely \"render\" the animation by rendering one image---   for each frame, named by extending the given output file name by---   consecutive integers.  For example if the given output file name---   is @foo\/blah.png@, the frames will be saved in @foo\/blah001.png@,---   @foo\/blah002.png@, and so on (the number of padding digits used---   depends on the total number of frames).  It is up to the user to---   take these images and stitch them together into an actual---   animation format (using, /e.g./ @ffmpeg@).+-- | Display the list of diagrams available for rendering.+showDiaList :: [String] -> IO ()+showDiaList ds = do+  putStrLn "Available diagrams:"+  putStrLn $ "  " ++ intercalate " " ds++-- | @animMain@ is like 'defaultMain', but renders an animation+-- instead of a diagram.  It takes as input an animation and produces+-- a command-line program which will crudely \"render\" the animation+-- by rendering one image for each frame, named by extending the given+-- output file name by consecutive integers.  For example if the given+-- output file name is @foo\/blah.png@, the frames will be saved in+-- @foo\/blah001.png@, @foo\/blah002.png@, and so on (the number of+-- padding digits used depends on the total number of frames).  It is+-- up to the user to take these images and stitch them together into+-- an actual animation format (using, /e.g./ @ffmpeg@). -- --   Of course, this is a rather crude method of rendering animations; --   more sophisticated methods will likely be added in the future.+--+-- The @--fpu@ option can be used to control how many frames will be+-- output for each second (unit time) of animation. animMain :: Animation Cairo R2 -> IO () animMain anim = do   prog <- getProgName@@ -202,7 +294,7 @@         (base, ext) = splitExtension (output opts)  #ifdef CMDLINELOOP-waitForChange :: Maybe ClockTime -> DiagramOpts -> String -> [String] -> IO ()+waitForChange :: Maybe ModuleTime -> DiagramOpts -> String -> [String] -> IO () waitForChange lastAttempt opts prog args = do     hSetBuffering stdout NoBuffering     go lastAttempt@@ -212,7 +304,7 @@           (newBin, newAttempt) <- recompile lastAtt prog (src opts)           if newBin             then executeFile prog False args Nothing-            else go $ getFirst (First newAttempt <> First lastAtt)+            else go $ newAttempt `mplus` lastAtt  -- | @recompile t prog@ attempts to recompile @prog@, assuming the --   last attempt was made at time @t@.  If @t@ is @Nothing@ assume@@ -222,7 +314,7 @@ --   of this attempt.  Otherwise (if nothing has changed since the --   last attempt), return @Nothing@.  Also return a Bool saying --   whether a successful recompilation happened.-recompile :: Maybe ClockTime -> String -> Maybe String -> IO (Bool, Maybe ClockTime)+recompile :: Maybe ModuleTime -> String -> Maybe String -> IO (Bool, Maybe ModuleTime) recompile lastAttempt prog mSrc = do   let errFile = prog ++ ".errors"       srcFile = fromMaybe (prog ++ ".hs") mSrc@@ -239,7 +331,7 @@         then putStrLn "" >> putStrLn (replicate 75 '-') >> readFile errFile >>= putStr         else putStrLn "done." -      curTime <- getClockTime+      curTime <- getModuleTime       return (status == ExitSuccess, Just curTime)      else return (False, Nothing)
− src/Diagrams/Backend/Cairo/Gtk.hs
@@ -1,70 +0,0 @@-{-# LANGUAGE CPP #-}--------------------------------------------------------------------------------- |--- Module      :  Diagrams.Backend.Cairo.Gtk--- Copyright   :  (c) 2011 Diagrams-cairo team (see LICENSE)--- License     :  BSD-style (see LICENSE)--- Maintainer  :  diagrams-discuss@googlegroups.com------ Convenient interface to rendering diagrams directly--- on Gtk widgets using the Cairo backend.-----------------------------------------------------------------------------------module Diagrams.Backend.Cairo.Gtk-       ( defaultRender-       , toGtkCoords-       , renderToGtk-       ) where--import Diagrams.Prelude hiding (width, height)-import Diagrams.Backend.Cairo---- Below hack is needed because GHC 7.0.x has a bug regarding export--- of data family constructors; see comments in Diagrams.Backend.Cairo-#if __GLASGOW_HASKELL__ < 702 || __GLASGOW_HASKELL__ >= 704-import Diagrams.Backend.Cairo.Internal-#endif--import Graphics.UI.Gtk---- | Convert a Diagram to the backend coordinates.------ Provided to Query the diagram with coordinates from a mouse click--- event.------ > widget `on` buttonPressEvent $ tryEvent $ do--- >   click <- eventClick--- >   (x,y) <- eventCoordinates--- >   let result = runQuery (query $ toGtkCoords myDiagram) (P (x,y))--- >   do_something_with result------ `toGtkCoords` does no rescaling of the diagram, however it is centered in--- the window.-toGtkCoords :: Monoid' m => QDiagram Cairo R2 m -> QDiagram Cairo R2 m-toGtkCoords d = snd $-  adjustDia Cairo-            (CairoOptions "" Absolute (GTK (undefined :: DrawWindow) False))-            d---- | Render a diagram to a DrawingArea, rescaling to fit the full area.-defaultRender :: Monoid' m => DrawingArea -> QDiagram Cairo R2 m -> IO ()-defaultRender da d = do-  (w,h) <- widgetGetSize da-  dw <- widgetGetDrawWindow da-  fst $ renderDia Cairo (CairoOptions "" (Dims (fromIntegral w) (fromIntegral h))-                                         (GTK dw False)-                        )-        d---- | Render a diagram to a DrawableClass.  No rescaling or transformations--- will be performed.------ Typically the diagram will already have been transformed by `toGtkCoords`.-renderToGtk ::-  (DrawableClass dc, Monoid' m)-  => dc                     -- ^ widget to render onto-  -> QDiagram Cairo R2 m  -- ^ Diagram-  -> IO ()-renderToGtk dc d =-  fst $ renderDia Cairo (CairoOptions "" Absolute (GTK dc True)) d
src/Diagrams/Backend/Cairo/Internal.hs view
@@ -15,22 +15,31 @@ -- License     :  BSD-style (see LICENSE) -- Maintainer  :  diagrams-discuss@googlegroups.com ----- Implementation of the diagrams Cairo backend.  This module exports the--- internal helper functions, for usage elsewhere.+-- This module contains the internal implementation guts of the+-- diagrams cairo backend.  If you want to see how the cairo backend+-- works under the hood, you are in the right place (try clicking on+-- the \"Source\" links).  (Guts under the hood, what an awful mixed+-- metaphor.)  If you know what you are doing and really want access+-- to the internals of the implementation, you are also in the right+-- place.  Otherwise, you should have no need of this module; import+-- "Diagrams.Backend.Cairo.CmdLine" or "Diagrams.Backend.Cairo"+-- instead. --+-- The one exception is that this module may have to be imported+-- sometimes to work around an apparent bug in certain versions of+-- GHC, which results in a \"not in scope\" error for 'CairoOptions'.+-- ----------------------------------------------------------------------------- module Diagrams.Backend.Cairo.Internal where -import Graphics.Rendering.Diagrams.Transform+import Diagrams.Core.Transform  import Diagrams.Prelude import Diagrams.TwoD.Path (Clip(..), getFillRule) import Diagrams.TwoD.Text import Diagrams.TwoD.Image-import Diagrams.TwoD.Adjust (adjustDia2D, adjustSize)--import Graphics.UI.Gtk (DrawableClass)-import qualified Graphics.UI.Gtk.Cairo as CG+import Diagrams.TwoD.Adjust (adjustDia2D, setDefault2DAttributes)+import Diagrams.TwoD.Size (requiredScaleT)  import qualified Graphics.Rendering.Cairo as C import qualified Graphics.Rendering.Cairo.Matrix as CM@@ -46,31 +55,35 @@ import Data.Typeable  -- | This data declaration is simply used as a token to distinguish---   this rendering engine.+--   the cairo backend: (1) when calling functions where the type+--   inference engine would otherwise have know way to know which+--   backend you wanted to use, and (2) as an argument to the+--   'Backend' and 'Renderable' type classes. data Cairo = Cairo   deriving (Eq,Ord,Read,Show,Typeable)  -- | Output types supported by cairo, including four different file---   types (PNG, PS, PDF, SVG) as well as Gtk windows.+--   types (PNG, PS, PDF, SVG).  If you want to output directly to GTK+--   windows, see the diagrams-gtk package. data OutputType =-    -- | Output directly to a Gtk window.  See "Diagrams.Backends.Cairo.Gtk".-    forall dw. (DrawableClass dw) =>-    GTK { gtkWindow :: dw-          -- ^ The window on which to draw.--        , gtkBypass :: Bool-          -- ^ Should the 'adjustDia' step be bypassed during rendering?-        }--  | PNG      -- ^ Portable Network Graphics output.+    PNG      -- ^ Portable Network Graphics output.   | PS       -- ^ PostScript output   | PDF      -- ^ Portable Document Format output.   | SVG      -- ^ Scalable Vector Graphics output.+  | RenderOnly  -- ^ Don't output any file; the returned @IO ()@+                -- action will do nothing, but the @Render ()@ action+                -- can be used (e.g. to draw to a Gtk window)  instance Monoid (Render Cairo R2) where   mempty  = C $ return ()   (C rd1) `mappend` (C rd2) = C (rd1 >> rd2) +-- | The custom monad in which intermediate drawing options take+--   place; 'Graphics.Rendering.Cairo.Render' is cairo's own rendering+--   monad.  At one point @RenderM@ really did use @StateT@, but then+--   the state got taken out... but the @StateT@ remains, now with a+--   zen-like state of type unit, \"just in case\".  Think of it as a+--   good luck charm. type RenderM a = StateT () C.Render a  -- no state for now  -- simple, stupid implementations of save and restore for now, since@@ -79,9 +92,11 @@ -- implementation using an "undoable state" monad which lets you save -- (push state onto a stack) and restore (pop from the stack). +-- | Push the current context onto a stack. save :: RenderM () save = lift C.save +-- | Restore the context from a stack. restore :: RenderM () restore = lift C.restore @@ -92,6 +107,7 @@           { cairoFileName   :: String     -- ^ The name of the file you want generated           , cairoSizeSpec   :: SizeSpec2D -- ^ The requested size of the output           , cairoOutputType :: OutputType -- ^ the output format and associated options+          , cairoBypassAdjust  :: Bool    -- ^ Should the 'adjustDia' step be bypassed during rendering?           }    withStyle _ s t (C r) = C $ do@@ -104,7 +120,7 @@       C.stroke     restore -  doRender _ (CairoOptions file size out) (C r) = (renderIO, r')+  doRender _ (CairoOptions file size out _) (C r) = (renderIO, r')     where r' = evalStateT r ()           renderIO = do             let surfaceF s = C.renderWith s r'@@ -120,7 +136,6 @@                           Absolute   -> (100,100)              case out of-              GTK win _ -> CG.renderWithDrawable win r'               PNG ->                 C.withImageSurface C.FormatARGB32 (round w) (round h) $ \surface -> do                   surfaceF surface@@ -128,19 +143,20 @@               PS  -> C.withPSSurface  file w h surfaceF               PDF -> C.withPDFSurface file w h surfaceF               SVG -> C.withSVGSurface file w h surfaceF+              RenderOnly -> return () -  adjustDia c opts d = if bypass (cairoOutputType opts)-                         then (opts,d)+  adjustDia c opts d = if cairoBypassAdjust opts+                         then (opts, d # setDefault2DAttributes)                          else adjustDia2D cairoSizeSpec                                           setCairoSizeSpec                                           c opts (d # reflectY)     where setCairoSizeSpec sz o = o { cairoSizeSpec = sz }-          bypass  (GTK _ x) = x-          bypass  _         = False  renderC :: (Renderable a Cairo, V a ~ R2) => a -> RenderM () renderC a = case (render Cairo a) of C r -> r +-- | Handle \"miscellaneous\" style attributes (clip, font stuff, fill+--   color and fill rule). cairoMiscStyle :: Style v -> RenderM () cairoMiscStyle s =   sequence_@@ -172,6 +188,7 @@ fromFontWeight FontWeightNormal = C.FontWeightNormal fromFontWeight FontWeightBold   = C.FontWeightBold +-- | Handle style attributes having to do with stroke. cairoStrokeStyle :: Style v -> C.Render () cairoStrokeStyle s =   sequence_@@ -200,6 +217,8 @@                       Just d  -> a * d  +-- | Multiply the current transformation matrix by the given 2D+--   transformation. cairoTransf :: T2 -> C.Render () cairoTransf t = C.transform m   where m = CM.Matrix a1 a2 b1 b2 c1 c2@@ -260,7 +279,7 @@           Right pngSurf -> do             w <- C.imageSurfaceGetWidth pngSurf             h <- C.imageSurfaceGetHeight pngSurf-            cairoTransf $ adjustSize sz (fromIntegral w, fromIntegral h)+            cairoTransf $ requiredScaleT sz (fromIntegral w, fromIntegral h)             C.setSourceSurface pngSurf (-fromIntegral w / 2)                                        (-fromIntegral h / 2)           Left _ ->
+ src/Diagrams/Backend/Cairo/List.hs view
@@ -0,0 +1,48 @@++-----------------------------------------------------------------------------+-- |+-- Module      :  Diagrams.Backend.Cairo.List+-- Copyright   :  (c) 2012 Diagrams-cairo team (see LICENSE)+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  diagrams-discuss@googlegroups.com+--+-- Render a diagram directly to a list of lists of Colour values+-- (/i.e./ pixels).+--+-----------------------------------------------------------------------------++module Diagrams.Backend.Cairo.List where++import Control.Applicative ((<$>))+import Control.Exception (bracket)++import Data.Colour+import Data.Colour.SRGB (sRGB)+import Data.Word (Word8)++import Diagrams.Prelude (Diagram, R2)+import Diagrams.Backend.Cairo (Cairo)+import Diagrams.Backend.Cairo.Ptr (renderPtr)++import Foreign.Marshal.Alloc (free)+import Foreign.Marshal.Array (peekArray)++-- | Render to a regular list of Colour values.++renderToList :: (Ord a, Floating a) =>+                  Int -> Int -> Diagram Cairo R2 -> IO [[AlphaColour a]]+renderToList w h d =+  f 0 <$> bracket (renderPtr w h d) free (peekArray $ w*h*4)+ where+  f :: (Ord a, Floating a) => Int -> [Word8] -> [[AlphaColour a]]+  f _ [] = []+  f n xs | n >= w = [] : f 0 xs+  f n (g:b:r:a:xs) =+    let l n = fromIntegral n / fromIntegral a+        c   = sRGB (l r) (l g) (l b) `withOpacity` (fromIntegral a / 255)++    in case f (n+1) xs of+      []    -> [[c]]+      cs:ys -> (c:cs) : ys++  f _ _ = error "renderToList: Internal format error"
+ src/Diagrams/Backend/Cairo/Ptr.hs view
@@ -0,0 +1,55 @@++-----------------------------------------------------------------------------+-- |+-- Module      :  Diagrams.Backend.Cairo.Ptr+-- Copyright   :  (c) 2012 Diagrams-cairo team (see LICENSE)+-- License     :  BSD-style (see LICENSE)+-- Maintainer  :  diagrams-discuss@googlegroups.com+--+-- Render diagrams to buffers in memory.+--+-----------------------------------------------------------------------------++module Diagrams.Backend.Cairo.Ptr where++import Data.Word (Word8)++import Diagrams.Prelude (Diagram, R2, SizeSpec2D (..), renderDia)+import Diagrams.Backend.Cairo+import Diagrams.Backend.Cairo.Internal++import Foreign.ForeignPtr.Safe (ForeignPtr, newForeignPtr)+import Foreign.Marshal.Alloc   (finalizerFree)+import Foreign.Marshal.Array   (mallocArray, pokeArray)+import Foreign.Ptr             (Ptr, castPtr)++import Graphics.Rendering.Cairo ( Format (..)+                                , formatStrideForWidth+                                , renderWith+                                , withImageSurfaceForData+                                )++-- | Render a diagram to a new buffer in memory, with the format ARGB32.++renderPtr :: Int -> Int -> Diagram Cairo R2 -> IO (Ptr Word8)+renderPtr w h d = do+  let stride = formatStrideForWidth FormatARGB32 w+      size   = stride * h+      opt    = CairoOptions+        { cairoSizeSpec     = Dims (fromIntegral w) (fromIntegral h)+        , cairoOutputType   = RenderOnly+        , cairoBypassAdjust = False+        , cairoFileName     = ""+        }+      (_, r) = renderDia Cairo opt d++  b <- mallocArray size+  pokeArray b (replicate size 0)+  withImageSurfaceForData b FormatARGB32 w h stride (`renderWith` r)++  return (castPtr b)++-- | Like 'renderPtr' but automatically garbage collected by Haskell.++renderForeignPtr :: Int -> Int -> Diagram Cairo R2 -> IO (ForeignPtr Word8)+renderForeignPtr w h d = renderPtr w h d >>= newForeignPtr finalizerFree
src/Diagrams/Backend/Cairo/Text.hs view
@@ -6,34 +6,30 @@ -- License     :  BSD-style (see LICENSE) -- Maintainer  :  diagrams-discuss@googlegroups.com ----- This module provides convenience functions for querying information from--- Cairo.  In particular, this provides utilities for information about fonts,--- and creating text primitives with bounds based on the font being used.+-- This module provides convenience functions for querying information+-- from cairo.  In particular, this provides utilities for information+-- about fonts, and creating text primitives with bounds based on the+-- font being used. To render text with automatically determined+-- envelopes, use 'textLineBounded', 'textLineBoundedIO',+-- 'textVisualBounded', or 'textVisualBoundedIO'. --+-- Many of these functions take a 'Style' 'R2' parameter, determining the+-- style to apply to the text before rendering / querying information about+-- the text.  These 'Style' 'R2' parameters can be created a variety of ways,+-- but the most direct will likely be by applying style-transforming functions+-- such as 'font', 'fontSize', 'fontSlant', and 'fontWeight' to 'mempty'.+-- This works because there are instances of 'HasStyle' and 'Monoid' for+-- @'Style' v@.+-- ----------------------------------------------------------------------------- module Diagrams.Backend.Cairo.Text   (-    -- * Cairo Utilities-    queryCairo, unsafeCairo-  , StyleParam, cairoWithStyle--    -- * Extents--    -- ** Data Structures--  , TextExtents(..), FontExtents(..)--    -- ** Queries--  , getTextExtents, getFontExtents, getExtents-  , kerningCorrectionIO-     -- * Primitives      -- | These create diagrams instantiated with extents-based envelopes-  , textLineBoundedIO, textVisualBoundedIO+    textLineBoundedIO, textVisualBoundedIO -    -- * Unsafe+    -- ** Unsafe      -- | These are convenient unsafe variants of the above operations     --   postfixed with \"IO\". They should be pretty well-behaved as the@@ -41,6 +37,20 @@     --   (which ought to stay the same during a given execution).    , kerningCorrection, textLineBounded, textVisualBounded++    -- * Extents++    -- ** Data Structures+  , TextExtents(..), FontExtents(..)++    -- ** Queries++  , getTextExtents, getFontExtents, getExtents+  , kerningCorrectionIO++    -- * Utilities+  , queryCairo, unsafeCairo+  , cairoWithStyle   ) where  import Diagrams.Backend.Cairo.Internal@@ -60,19 +70,14 @@ unsafeCairo :: C.Render a -> a unsafeCairo = unsafePerformIO . queryCairo --- | Existential type for mutations on objects that \"have style\". This is---   used as a parameter to @getTextExtents@ and @getFontExtents@ in order to---   set font-size and font-face.-type StyleParam = forall a. HasStyle a => a -> a- -- | Executes the given cairo action, with styling applied. --   This does not do all styling - just attributes that are processed by --   \"cairoMiscStyle\", which does clip, fill color, fill rule, and, --   importantly for this module, font face, style, and weight.-cairoWithStyle :: C.Render a -> StyleParam -> C.Render a+cairoWithStyle :: C.Render a -> Style R2 -> C.Render a cairoWithStyle f style = do   C.save-  evalStateT (cairoMiscStyle (style mempty)) ()+  evalStateT (cairoMiscStyle style) ()   result <- f   C.restore   return result@@ -86,7 +91,7 @@                     = TextExtents (r2 (xb,yb)) (r2 (w,h)) (r2 (xa,ya))  -- | Get the extents of a string of text, given a style to render it with.-getTextExtents :: StyleParam -> String -> C.Render TextExtents+getTextExtents :: Style R2 -> String -> C.Render TextExtents getTextExtents style txt   = cairoWithStyle (processTextExtents <$> C.textExtents txt) style @@ -101,14 +106,14 @@                     = FontExtents a d h (r2 (mx,my))  -- | Gets the intrinsic extents of a font.-getFontExtents :: StyleParam -> C.Render FontExtents+getFontExtents :: Style R2 -> C.Render FontExtents getFontExtents style   = cairoWithStyle (processFontExtents <$> C.fontExtents) style  -- | Gets both the "FontExtents" and "TextExtents" of the string with the a --   particular style applied.  This is more efficient than calling both --   @getFontExtents@ and @getTextExtents@.-getExtents :: StyleParam -> String -> C.Render (FontExtents, TextExtents)+getExtents :: Style R2 -> String -> C.Render (FontExtents, TextExtents) getExtents style str = cairoWithStyle (do     fe <- processFontExtents <$> C.fontExtents     te <- processTextExtents <$> C.textExtents str@@ -118,7 +123,7 @@ -- | Queries the amount of horizontal offset that needs to be applied in order to --   position the second character properly, in the event that it is @hcat@-ed --   @baselineText@.-kerningCorrectionIO :: StyleParam -> Char -> Char -> IO Double+kerningCorrectionIO :: Style R2 -> Char -> Char -> IO Double kerningCorrectionIO style a b = do   let ax t = fst . unr2 . advance <$> queryCairo (getTextExtents style t)   l  <- ax [a, b]@@ -129,25 +134,25 @@ -- | Creates text diagrams with their envelopes set such that using --   @vcat . map (textLineBounded style)@ stacks them in the way that --   the font designer intended.-textLineBoundedIO :: StyleParam -> String -> IO (Diagram Cairo R2)+textLineBoundedIO :: Style R2 -> String -> IO (Diagram Cairo R2) textLineBoundedIO style str = do   (fe, te) <- queryCairo $ getExtents style str   let box = fromCorners (p2 (0,      negate $ descent fe))                         (p2 (fst . unr2 $ advance te, ascent fe))-  return . setEnvelope (getEnvelope box) $ style (baselineText str)+  return . setEnvelope (getEnvelope box) . applyStyle style $ baselineText str  -- | Creates a text diagram with its envelope set to enclose the glyphs of the text, --   including leading (though not trailing) whitespace.-textVisualBoundedIO :: StyleParam -> String -> IO (Diagram Cairo R2)+textVisualBoundedIO :: Style R2 -> String -> IO (Diagram Cairo R2) textVisualBoundedIO style str = do   te <- queryCairo $ getTextExtents style str   let box = fromCorners (origin .+^ bearing te)-                        (origin .+^ bearing te ^+^ (textSize te))-  return . setEnvelope (getEnvelope box) $ style (baselineText str)+                        ((origin .+^ bearing te) .+^ textSize te)+  return . setEnvelope (getEnvelope box) . applyStyle style $ baselineText str -kerningCorrection :: StyleParam -> Char -> Char -> Double+kerningCorrection :: Style R2 -> Char -> Char -> Double kerningCorrection style a = unsafePerformIO . kerningCorrectionIO style a -textLineBounded, textVisualBounded :: StyleParam -> String -> Diagram Cairo R2-textLineBounded style   = unsafePerformIO . textLineBoundedIO   style+textLineBounded, textVisualBounded :: Style R2 -> String -> Diagram Cairo R2+textLineBounded   style = unsafePerformIO . textLineBoundedIO   style textVisualBounded style = unsafePerformIO . textVisualBoundedIO style