    {-# LINE 2 "./Graphics/UI/Gtk/Cairo.chs" #-}
    -- -*-haskell-*-
    -- GIMP Toolkit (GTK) Cairo GDK integration
    --
    -- Author : Duncan Coutts
    --
    -- Created: 17 August 2005
    --
    -- Copyright (C) 2005 Duncan Coutts
    --
    -- This library is free software; you can redistribute it and/or
    -- modify it under the terms of the GNU Lesser General Public
    -- License as published by the Free Software Foundation; either
    -- version 2.1 of the License, or (at your option) any later version.
    --
    -- This library is distributed in the hope that it will be useful,
    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    -- Lesser General Public License for more details.
    --
    -- #hide

    -- |
    -- Maintainer : gtk2hs-users@lists.sourceforge.net
    -- Stability : provisional
    -- Portability : portable (depends on GHC)
    --
    --
    -- Gtk specific functions to for rendering with Cairo.
    --
    -- Cairo is a graphics library that supports vector graphics and image
    -- compositing that can be used with Gdk.
    -- The Cairo API is an addition to Gdk\/Gtk (rather than a replacement).
    -- Cairo rendering can be performed on any 'Graphics.UI.Gtk.Gdk.Drawable'
    -- by calling 'renderWithDrawable'. The functions in this module provide
    -- ways of drawing Gtk specific elements, such as 'Pixbuf's or text
    -- laid out with Pango.
    --
    -- All functions in this module are only available in Gtk 2.8 or higher.
    --
    module Graphics.UI.Gtk.Cairo (

      -- * Global Cairo settings.
      cairoFontMapGetDefault,
      cairoFontMapSetResolution,
      cairoFontMapGetResolution,
      cairoCreateContext,
      cairoContextSetResolution,
      cairoContextGetResolution,
      cairoContextSetFontOptions,
      cairoContextGetFontOptions,
      -- * Functions for the 'Render' monad.

      getClipRectangle,
      renderWithDrawWindow,

      region,
      setSourceColor,
      setSourcePixbuf,
      rectangle,
      updateContext,
      createLayout,
      updateLayout,
      showGlyphString,
      showLayoutLine,
      showLayout,
      glyphStringPath,
      layoutLinePath,
      layoutPath

      ) where

    import Control.Exception (bracket)

    import System.Glib.FFI
    import Graphics.UI.Gtk.Types
    {-# LINE 79 "./Graphics/UI/Gtk/Cairo.chs" #-}

    import Graphics.Rendering.Pango.Cairo
    {-# LINE 83 "./Graphics/UI/Gtk/Cairo.chs" #-}

    import Graphics.Rendering.Cairo.Types as Cairo

    import qualified Graphics.Rendering.Cairo.Internal as Cairo.Internal
    import Graphics.Rendering.Cairo.Internal (Render(Render))
    import Control.Monad.Reader
    import Graphics.UI.Gtk.General.Structs (Rectangle(..))

    import Control.Monad (unless, liftM)

    {-# LINE 98 "./Graphics/UI/Gtk/Cairo.chs" #-}

    --------------------
    -- Methods
    {-# LINE 121 "./Graphics/UI/Gtk/Cairo.chs" #-}
    -- | Creates a Cairo context for drawing to a 'DrawWindow'.
    renderWithDrawWindow :: DrawWindowClass drawWindow =>
        drawWindow -- ^ @drawWindow@ - a 'DrawWindow'
     -> Render a -- ^ A newly created Cairo context.
     -> IO a
    renderWithDrawWindow :: forall drawWindow a.
    DrawWindowClass drawWindow =>
    drawWindow -> Render a -> IO a
    renderWithDrawWindow drawWindow
    drawWindow Render a
    m =
      IO Cairo -> (Cairo -> IO ()) -> (Cairo -> IO a) -> IO a
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    bracket ((Ptr Cairo -> Cairo) -> IO (Ptr Cairo) -> IO Cairo
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM Ptr Cairo -> Cairo
    Cairo.Cairo (IO (Ptr Cairo) -> IO Cairo) -> IO (Ptr Cairo) -> IO Cairo
    forall a b. (a -> b) -> a -> b
    $ (\(DrawWindow ForeignPtr DrawWindow
    arg1) -> ForeignPtr DrawWindow
    -> (Ptr DrawWindow -> IO (Ptr Cairo)) -> IO (Ptr Cairo)
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr DrawWindow
    arg1 ((Ptr DrawWindow -> IO (Ptr Cairo)) -> IO (Ptr Cairo))
    -> (Ptr DrawWindow -> IO (Ptr Cairo)) -> IO (Ptr Cairo)
    forall a b. (a -> b) -> a -> b
    $ \Ptr DrawWindow
    argPtr1 ->Ptr DrawWindow -> IO (Ptr Cairo)
    gdk_cairo_create Ptr DrawWindow
    argPtr1) (drawWindow -> DrawWindow
    forall o. DrawWindowClass o => o -> DrawWindow
    toDrawWindow drawWindow
    drawWindow))
              (\Cairo
    context -> do status <- Cairo -> IO Status
    Cairo.Internal.status Cairo
    context
                              Cairo.Internal.destroy context
                              unless (status == Cairo.StatusSuccess) $
                                fail =<< Cairo.Internal.statusToString status)
              (\Cairo
    context -> ReaderT Cairo IO a -> Cairo -> IO a
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT (Render a -> ReaderT Cairo IO a
    forall m. Render m -> ReaderT Cairo IO m
    Cairo.Internal.runRender Render a
    m) Cairo
    context)

    -- | Compute a bounding box in user coordinates covering the area inside
    -- the current clip. It rounds the bounding box to integer coordinates.
    -- Returns 'Nothing' indicating if a clip area doesn't exist.
    getClipRectangle :: Render (Maybe Rectangle)
    getClipRectangle :: Render (Maybe Rectangle)
    getClipRectangle = ReaderT Cairo IO (Maybe Rectangle) -> Render (Maybe Rectangle)
    forall m. ReaderT Cairo IO m -> Render m
    Render (ReaderT Cairo IO (Maybe Rectangle) -> Render (Maybe Rectangle))
    -> ReaderT Cairo IO (Maybe Rectangle) -> Render (Maybe Rectangle)
    forall a b. (a -> b) -> a -> b
    $ do
      cr <- ReaderT Cairo IO Cairo
    forall r (m :: * -> *). MonadReader r m => m r
    ask
      liftIO $ alloca $ \Ptr Rectangle
    rectPtr -> do
        ok <- (\(Cairo Ptr Cairo
    arg1) Ptr ()
    arg2 -> Ptr Cairo -> Ptr () -> IO CInt
    gdk_cairo_get_clip_rectangle Ptr Cairo
    arg1 Ptr ()
    arg2)
    {-# LINE 142 "./Graphics/UI/Gtk/Cairo.chs" #-}
          cr
          (Ptr Rectangle -> Ptr ()
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Rectangle
    rectPtr)
        if ok /= 0
          then fmap Just (peek rectPtr)
          else return Nothing

    -- | Sets the given pixbuf as the source pattern for the Cairo context. The
    -- pattern has an extend mode of 'ExtendNone' and is aligned so that the
    -- origin of pixbuf is @(x, y)@.
    --
    setSourcePixbuf ::
        Pixbuf
     -> Double -- ^ x
     -> Double -- ^ y
     -> Render ()
    setSourcePixbuf :: Pixbuf -> Double -> Double -> Render ()
    setSourcePixbuf Pixbuf
    pixbuf Double
    pixbufX Double
    pixbufY = ReaderT Cairo IO () -> Render ()
    forall m. ReaderT Cairo IO m -> Render m
    Render (ReaderT Cairo IO () -> Render ())
    -> ReaderT Cairo IO () -> Render ()
    forall a b. (a -> b) -> a -> b
    $ do
      cr <- ReaderT Cairo IO Cairo
    forall r (m :: * -> *). MonadReader r m => m r
    ask
      liftIO $ (\(Cairo Ptr Cairo
    arg1) (Pixbuf ForeignPtr Pixbuf
    arg2) CDouble
    arg3 CDouble
    arg4 -> ForeignPtr Pixbuf -> (Ptr Pixbuf -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Pixbuf
    arg2 ((Ptr Pixbuf -> IO ()) -> IO ()) -> (Ptr Pixbuf -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr Pixbuf
    argPtr2 ->Ptr Cairo -> Ptr Pixbuf -> CDouble -> CDouble -> IO ()
    gdk_cairo_set_source_pixbuf Ptr Cairo
    arg1 Ptr Pixbuf
    argPtr2 CDouble
    arg3 CDouble
    arg4)
    {-# LINE 161 "./Graphics/UI/Gtk/Cairo.chs" #-}
        cr
        pixbuf
        (realToFrac pixbufX)
        (realToFrac pixbufY)

    -- | Adds the given region to the current path of the 'Render' context.
    rectangle :: Rectangle -> Render ()
    rectangle :: Rectangle -> Render ()
    rectangle Rectangle
    rect = ReaderT Cairo IO () -> Render ()
    forall m. ReaderT Cairo IO m -> Render m
    Render (ReaderT Cairo IO () -> Render ())
    -> ReaderT Cairo IO () -> Render ()
    forall a b. (a -> b) -> a -> b
    $ do
      cr <- ReaderT Cairo IO Cairo
    forall r (m :: * -> *). MonadReader r m => m r
    ask
      liftIO $ with rect $ \ Ptr Rectangle
    rectPtr ->
        (\(Cairo Ptr Cairo
    arg1) Ptr ()
    arg2 -> Ptr Cairo -> Ptr () -> IO ()
    gdk_cairo_rectangle Ptr Cairo
    arg1 Ptr ()
    arg2)
    {-# LINE 172 "./Graphics/UI/Gtk/Cairo.chs" #-}
          cr
          (Ptr Rectangle -> Ptr ()
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Rectangle
    rectPtr)

    -- | Adds the given region to the current path of the 'Render' context.
    region :: Region -> Render ()
    region :: Region -> Render ()
    region Region
    region = ReaderT Cairo IO () -> Render ()
    forall m. ReaderT Cairo IO m -> Render m
    Render (ReaderT Cairo IO () -> Render ())
    -> ReaderT Cairo IO () -> Render ()
    forall a b. (a -> b) -> a -> b
    $ do
      cr <- ReaderT Cairo IO Cairo
    forall r (m :: * -> *). MonadReader r m => m r
    ask
      liftIO $ (\(Cairo Ptr Cairo
    arg1) (Region ForeignPtr Region
    arg2) -> ForeignPtr Region -> (Ptr Region -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Region
    arg2 ((Ptr Region -> IO ()) -> IO ()) -> (Ptr Region -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr Region
    argPtr2 ->Ptr Cairo -> Ptr Region -> IO ()
    gdk_cairo_region Ptr Cairo
    arg1 Ptr Region
    argPtr2)
    {-# LINE 180 "./Graphics/UI/Gtk/Cairo.chs" #-}
        cr
        region

    foreign import ccall unsafe "gdk_cairo_create"
      gdk_cairo_create :: ((Ptr DrawWindow) -> (IO (Ptr Cairo)))

    foreign import ccall unsafe "gdk_cairo_get_clip_rectangle"
      gdk_cairo_get_clip_rectangle :: ((Ptr Cairo) -> ((Ptr ()) -> (IO CInt)))

    foreign import ccall unsafe "gdk_cairo_set_source_pixbuf"
      gdk_cairo_set_source_pixbuf :: ((Ptr Cairo) -> ((Ptr Pixbuf) -> (CDouble -> (CDouble -> (IO ())))))

    foreign import ccall unsafe "gdk_cairo_rectangle"
      gdk_cairo_rectangle :: ((Ptr Cairo) -> ((Ptr ()) -> (IO ())))

    foreign import ccall unsafe "gdk_cairo_region"
      gdk_cairo_region :: ((Ptr Cairo) -> ((Ptr Region) -> (IO ())))