summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreyevanmalicesun <>2019-01-11 01:58:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2019-01-11 01:58:00 (GMT)
commitdd84e347b348dfeed7b317fd6853739c443c6d9a (patch)
tree8bc56744113f617623c1411d8613db1b85376e12
version 0.0.1HEAD0.0.1master
-rw-r--r--GI/Cairo/Render.hs2238
-rw-r--r--GI/Cairo/Render/Internal.hs70
-rw-r--r--GI/Cairo/Render/Internal/Drawing/Cairo.chs77
-rw-r--r--GI/Cairo/Render/Internal/Drawing/Paths.chs45
-rw-r--r--GI/Cairo/Render/Internal/Drawing/Patterns.chs43
-rw-r--r--GI/Cairo/Render/Internal/Drawing/Text.chs56
-rw-r--r--GI/Cairo/Render/Internal/Drawing/Transformations.chs36
-rw-r--r--GI/Cairo/Render/Internal/Fonts/FontOptions.chs42
-rw-r--r--GI/Cairo/Render/Internal/Region.chs57
-rw-r--r--GI/Cairo/Render/Internal/Surfaces/Image.chs44
-rw-r--r--GI/Cairo/Render/Internal/Surfaces/PDF.chs34
-rw-r--r--GI/Cairo/Render/Internal/Surfaces/PNG.chs36
-rw-r--r--GI/Cairo/Render/Internal/Surfaces/PS.chs34
-rw-r--r--GI/Cairo/Render/Internal/Surfaces/SVG.chs30
-rw-r--r--GI/Cairo/Render/Internal/Surfaces/Surface.chs38
-rw-r--r--GI/Cairo/Render/Internal/Utilities.chs46
-rw-r--r--GI/Cairo/Render/Matrix.chs140
-rw-r--r--GI/Cairo/Render/Types.chs454
-rw-r--r--LICENSE11
-rw-r--r--gi-cairo-render.cabal75
-rwxr-xr-xinclude/gi-cairo-render.h13
21 files changed, 3619 insertions, 0 deletions
diff --git a/GI/Cairo/Render.hs b/GI/Cairo/Render.hs
new file mode 100644
index 0000000..4f5b5fd
--- /dev/null
+++ b/GI/Cairo/Render.hs
@@ -0,0 +1,2238 @@
+{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses, FlexibleInstances, CPP #-}
+
+-- The following is all rather brittle: We need to pre-process this file with GHC
+-- in order to get the __GLASGOW_HASKELL__ macro (which we should replace with a
+-- version test of the array package). At the same time we need to version of
+-- Cairo and the macros for testing it. We sneakily get the version from the
+-- internal cairo-version.h file but we have to define the testing macros ourselves.
+#include<cairo-features.h>
+
+-- GTK-2.12 doesn't have cairo-version.h, but defines the appropriate VERSION
+-- variables in cairo-features.h instead. So only include this when necessary.
+#ifndef CAIRO_VERSION_MAJOR
+#include<cairo-version.h>
+#endif
+#define CAIRO_VERSION_ENCODE(major, minor, micro) ( \
+ ((major) * 10000) \
+ + ((minor) * 100) \
+ + ((micro) * 1))
+
+#define CAIRO_VERSION CAIRO_VERSION_ENCODE( \
+ CAIRO_VERSION_MAJOR, \
+ CAIRO_VERSION_MINOR, \
+ CAIRO_VERSION_MICRO)
+
+#define CAIRO_CHECK_VERSION(major,minor,micro) \
+ (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(major,minor,micro))
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render
+-- Copyright : (c) Paolo Martini 2005, (c) Abraham Egnor 2004, (c) Aetion Technologies LLC 2004
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- The Cairo 2D graphics library.
+--
+-- Cairo is a 2D graphics library with support for multiple output devices.
+-- Currently supported output targets include the X Window System, win32, and
+-- image buffers. Experimental backends include OpenGL (through glitz), Quartz,
+-- XCB, PostScript and PDF file output.
+--
+-- Cairo is designed to produce consistent output on all output media while
+-- taking advantage of display hardware acceleration when available (eg.
+-- through the X Render Extension).
+--
+-- The cairo API provides operations similar to the drawing operators of
+-- PostScript and PDF. Operations in cairo including stroking and filling cubic
+-- Bezier splines, transforming and compositing translucent images, and
+-- antialiased text rendering. All drawing operations can be transformed by any
+-- affine transformation (scale, rotation, shear, etc.)
+--
+-- Cairo is free software and is available to be redistributed and\/or modified
+-- under the terms of either the GNU Lesser General Public License (LGPL)
+-- version 2.1 or the Mozilla Public License (MPL) version 1.1.
+--
+-- For more information see <http://cairographics.org>
+--
+-- * Note the Haskell bindings do not support all the possible cairo backends
+-- because it would require bindings for the associated technology (eg X11,
+-- glitz, etc) however bindings to other backends may be implemented
+-- externally. For example, Gtk2Hs provides a binding to the backend for X11
+-- (and win32 on Windows).
+-----------------------------------------------------------------------------
+module GI.Cairo.Render (
+ -- * Drawing
+ renderWith
+ , save
+ , restore
+ , status
+ , withTargetSurface
+ , pushGroup
+ , pushGroupWithContent
+ , popGroupToSource
+ , setSourceRGB
+ , setSourceRGBA
+ , setSource
+ , setSourceSurface
+ , getSource
+ , setAntialias
+ , setDash
+ , setFillRule
+ , getFillRule
+ , setLineCap
+ , getLineCap
+ , setLineJoin
+ , getLineJoin
+ , setLineWidth
+ , getLineWidth
+ , setMiterLimit
+ , getMiterLimit
+ , setOperator
+ , getOperator
+ , setTolerance
+ , getTolerance
+ , clip
+ , clipPreserve
+ , clipExtents
+ , resetClip
+ , fill
+ , fillPreserve
+ , fillExtents
+ , inFill
+ , mask
+ , maskSurface
+ , paint
+ , paintWithAlpha
+ , stroke
+ , strokePreserve
+ , strokeExtents
+ , inStroke
+ , copyPage
+ , showPage
+
+ -- ** Paths
+ , getCurrentPoint
+ , newPath
+ , closePath
+ , arc
+ , arcNegative
+ , curveTo
+ , lineTo
+ , moveTo
+ , rectangle
+ , textPath
+ , relCurveTo
+ , relLineTo
+ , relMoveTo
+
+ -- ** Patterns
+ , withRGBPattern
+ , withRGBAPattern
+ , withPatternForSurface
+ , withGroupPattern
+ , withLinearPattern
+ , withRadialPattern
+ , patternAddColorStopRGB
+ , patternAddColorStopRGBA
+ , patternSetMatrix
+ , patternGetMatrix
+ , patternSetExtend
+ , patternGetExtend
+ , patternSetFilter
+ , patternGetFilter
+
+ -- ** Transformations
+ , translate
+ , scale
+ , rotate
+ , transform
+ , setMatrix
+ , getMatrix
+ , identityMatrix
+ , userToDevice
+ , userToDeviceDistance
+ , deviceToUser
+ , deviceToUserDistance
+
+ -- ** Text
+ , selectFontFace
+ , setFontSize
+ , setFontMatrix
+ , getFontMatrix
+ , setFontOptions
+ , showText
+ , fontExtents
+ , textExtents
+
+ -- * Fonts
+
+ -- ** Font options
+ , fontOptionsCreate
+ , fontOptionsCopy
+ , fontOptionsMerge
+ , fontOptionsHash
+ , fontOptionsEqual
+ , fontOptionsSetAntialias
+ , fontOptionsGetAntialias
+ , fontOptionsSetSubpixelOrder
+ , fontOptionsGetSubpixelOrder
+ , fontOptionsSetHintStyle
+ , fontOptionsGetHintStyle
+ , fontOptionsSetHintMetrics
+ , fontOptionsGetHintMetrics
+
+ -- * Surfaces
+
+ , withSimilarSurface
+ , createSimilarSurface
+ , renderWithSimilarSurface
+ , surfaceGetFontOptions
+ , surfaceFinish
+ , surfaceFlush
+ , surfaceMarkDirty
+ , surfaceMarkDirtyRectangle
+ , surfaceSetDeviceOffset
+
+ -- ** Image surfaces
+ , withImageSurface
+ , withImageSurfaceForData
+#if CAIRO_CHECK_VERSION(1,6,0)
+ , formatStrideForWidth
+#endif
+ , createImageSurfaceForData
+ , createImageSurface
+ , imageSurfaceGetWidth
+ , imageSurfaceGetHeight
+#if CAIRO_CHECK_VERSION(1,2,0)
+ , imageSurfaceGetFormat
+ , imageSurfaceGetStride
+#if __GLASGOW_HASKELL__ >= 606
+ , imageSurfaceGetData
+#endif
+ , SurfaceData
+ , imageSurfaceGetPixels
+#endif
+
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+ -- ** PNG support
+ , withImageSurfaceFromPNG
+ , imageSurfaceCreateFromPNG
+ , surfaceWriteToPNG
+#endif
+
+#ifdef CAIRO_HAS_PDF_SURFACE
+ -- ** PDF surfaces
+ , withPDFSurface
+#if CAIRO_CHECK_VERSION(1,2,0)
+ , pdfSurfaceSetSize
+#endif
+#endif
+
+#ifdef CAIRO_HAS_PS_SURFACE
+ -- ** PS surfaces
+ , withPSSurface
+#if CAIRO_CHECK_VERSION(1,2,0)
+ , psSurfaceSetSize
+#endif
+#endif
+
+#ifdef CAIRO_HAS_SVG_SURFACE
+ -- ** SVG surfaces
+ , withSVGSurface
+#endif
+
+#if CAIRO_CHECK_VERSION(1,10,0)
+ -- * Regions
+ , regionCreate
+ , regionCreateRectangle
+ , regionCreateRectangles
+ , regionCopy
+ , regionGetExtents
+ , regionNumRectangles
+ , regionGetRectangle
+ , regionIsEmpty
+ , regionContainsPoint
+ , regionContainsRectangle
+ , regionEqual
+ , regionTranslate
+ , regionIntersect
+ , regionIntersectRectangle
+ , regionSubtract
+ , regionSubtractRectangle
+ , regionUnion
+ , regionUnionRectangle
+ , regionXor
+ , regionXorRectangle
+
+#endif
+
+ -- * Utilities
+
+ , liftIO
+ , version
+ , versionString
+ , CairoString
+
+ -- * Types
+
+ , Render
+ , Matrix
+ , Surface
+ , Pattern
+ , Status(..)
+ , Operator(..)
+ , Antialias(..)
+ , FillRule(..)
+ , LineCap(..)
+ , LineJoin(..)
+ , ScaledFont
+ , FontFace
+ , Glyph
+ , TextExtents(..)
+ , FontExtents(..)
+ , FontSlant(..)
+ , FontWeight(..)
+ , SubpixelOrder(..)
+ , HintStyle(..)
+ , HintMetrics(..)
+ , FontOptions
+ , Path
+#if CAIRO_CHECK_VERSION(1,10,0)
+ , RectangleInt(..)
+ , RegionOverlap(..)
+ , Region
+#endif
+ , Content(..)
+ , Format(..)
+ , Extend(..)
+ , Filter(..)
+
+ ) where
+
+import Data.GI.Base (wrapBoxed)
+import Control.Monad (unless, when)
+import Control.Monad.Reader (ReaderT(runReaderT), ask, MonadIO, liftIO)
+import Control.Exception (bracket)
+import Foreign.Ptr (Ptr, nullPtr, castPtr)
+import Foreign.Storable (Storable(..))
+import Foreign.ForeignPtr ( touchForeignPtr )
+#if __GLASGOW_HASKELL__ >= 606
+import qualified Data.ByteString as BS
+#endif
+import Data.Ix
+-- internal module of GHC
+import Data.Array.Base ( MArray, newArray, newArray_, unsafeRead, unsafeWrite,
+#if __GLASGOW_HASKELL__ < 605
+ HasBounds, bounds
+#else
+ getBounds
+#endif
+#if __GLASGOW_HASKELL__ >= 608
+ ,getNumElements
+#endif
+ )
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+import GI.Cairo.Render.Internal (imageSurfaceCreateFromPNG)
+#endif
+
+import GI.Cairo.Render.Types
+import GI.Cairo.Render.Internal.Utilities (CairoString(..))
+import qualified GI.Cairo.Render.Internal as Internal
+import GI.Cairo.Render.Internal (Render(..), bracketR)
+
+liftRender0 :: (Cairo -> IO a) -> Render a
+liftRender0 f = ask >>= \context -> liftIO (f context)
+liftRender1 :: (Cairo -> a -> IO b) -> a -> Render b
+liftRender1 f a = ask >>= \context -> liftIO (f context a)
+liftRender2 :: (Cairo -> a -> b -> IO c) -> a -> b -> Render c
+liftRender2 f a b = ask >>= \context -> liftIO (f context a b)
+liftRender3 :: (Cairo -> a -> b -> c -> IO d) -> a -> b -> c -> Render d
+liftRender3 f a b c = ask >>= \context -> liftIO (f context a b c)
+liftRender4 :: (Cairo -> a -> b -> c -> d -> IO e) -> a -> b -> c -> d -> Render e
+liftRender4 f a b c d = ask >>= \context -> liftIO (f context a b c d)
+liftRender5 :: (Cairo -> a -> b -> c -> d -> e -> IO f) -> a -> b -> c -> d -> e -> Render f
+liftRender5 f a b c d e = ask >>= \context -> liftIO (f context a b c d e)
+liftRender6 :: (Cairo -> a -> b -> c -> d -> e -> f -> IO g) -> a -> b -> c -> d -> e -> f -> Render g
+liftRender6 f a b c d e g = ask >>= \context -> liftIO (f context a b c d e g)
+
+-- | Creates a new Render context with all graphics state parameters set to
+-- default values and with the given surface as a target surface. The target
+-- surface should be constructed with a backend-specific function such as
+-- 'withImageSurface' (or any other with\<backend\>Surface variant).
+--
+renderWith :: (MonadIO m) =>
+ Surface -- ^ the target surface for the Render context
+ -> Render a
+ -> m a
+renderWith surface (Render m) = liftIO $
+ bracket (do context <- Internal.create surface
+ wrapBoxed Cairo context)
+ (\context -> do status <- Internal.status context
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status)
+ (\context -> runReaderT m context)
+
+-- | Makes a copy of the current state and saves it on an internal stack of
+-- saved states. When 'restore' is called, the saved state is restored.
+-- Multiple calls to 'save' and 'restore' can be nested; each call to 'restore'
+-- restores the state from the matching paired 'save'.
+--
+save :: Render ()
+save = liftRender0 Internal.save
+
+-- | Restores to the state saved by a preceding call to 'save' and removes that
+-- state from the stack of saved states.
+--
+restore :: Render ()
+restore = liftRender0 Internal.restore
+
+
+-- | Ask for the status of the current 'Render' monad.
+--
+status :: Render Status
+status = liftRender0 Internal.status
+
+-- | Gets the target surface for the Render context as passed to 'renderWith'.
+--
+withTargetSurface :: (Surface -> Render a) -> Render a
+withTargetSurface f = do
+ context <- ask
+ surface <- liftIO $ Internal.getTarget context
+ f surface
+
+-- | Like @pushGroupWithContent ContentColorAlpha@, but more convenient.
+pushGroup :: Render ()
+pushGroup = liftRender0 Internal.pushGroup
+
+-- | Temporarily redirects drawing to an intermediate surface known as a group.
+-- The redirection lasts until the group is completed by a call to
+-- 'withGroupPattern' or 'popGroupToSource'. These calls provide the result of
+-- any drawing to the group as a pattern (either as an explicit object, or set
+-- as the source pattern). This group functionality can be convenient for
+-- performing intermediate compositing. One common use of a group is to render
+-- objects as opaque within the group (so that they occlude each other), and
+-- then blend the result with translucence onto the destination.
+--
+-- Groups can be nested arbitrarily deeply by making balanced calls to
+-- 'pushGroupWithContent' and 'withGroupPattern'. As a side effect,
+-- 'pushGroupWithContent' calls 'save' and 'withGroupPattern' calls 'restore',
+-- so that any changes to the graphics state will not be visible outside the
+-- group.
+--
+-- As an example, here is how one might fill and stroke a path with
+-- translucence, but without any portion of the fill being visible under the
+-- stroke:
+--
+-- > pushGroup
+-- > setSource fillPattern
+-- > fillPreserve
+-- > setSource strokePattern
+-- > stroke
+-- > popGroupToSource
+-- > paintWithAlpha alpha
+pushGroupWithContent :: Content -> Render ()
+pushGroupWithContent = liftRender1 Internal.pushGroupWithContent
+
+-- | Like @withGroupPattern setSource@, but more convenient.
+popGroupToSource :: Render ()
+popGroupToSource = liftRender0 Internal.popGroupToSource
+
+-- | Sets the source pattern within the context to an opaque color. This opaque
+-- color will then be used for any subsequent drawing operation until a new source
+-- pattern is set.
+--
+-- The color components are floating point numbers in the range 0 to 1. If the
+-- values passed in are outside that range, they will be clamped.
+--
+setSourceRGB ::
+ Double -- ^ red component of colour
+ -> Double -- ^ green component of colour
+ -> Double -- ^ blue compoment of colour
+ -> Render ()
+setSourceRGB = liftRender3 Internal.setSourceRGB
+
+-- | Sets the source pattern within the context to a translucent color. This
+-- color will then be used for any subsequent drawing operation until a new
+-- source pattern is set.
+--
+-- The color and alpha components are floating point numbers in the range 0 to
+-- 1. If the values passed in are outside that range, they will be clamped.
+--
+setSourceRGBA ::
+ Double -- ^ red component of color
+ -> Double -- ^ green component of color
+ -> Double -- ^ blue component of color
+ -> Double -- ^ alpha component of color
+ -> Render ()
+setSourceRGBA = liftRender4 Internal.setSourceRGBA
+
+-- | Sets the source pattern within the context to source. This pattern will
+-- then be used for any subsequent drawing operation until a new source pattern
+-- is set.
+--
+-- Note: The pattern's transformation matrix will be locked to the user space
+-- in effect at the time of 'setSource'. This means that further
+-- modifications of the current transformation matrix will not affect the source
+-- pattern. See 'setMatrix'.
+--
+setSource ::
+ Pattern -- ^ a 'Pattern' to be used as the source for subsequent drawing
+ -- operations.
+ -> Render ()
+setSource = liftRender1 Internal.setSource
+
+-- | This is a convenience function for creating a pattern from surface and
+-- setting it as the source in the context with 'setSource'.
+--
+-- The x and y parameters give the user-space coordinate at which the surface
+-- origin should appear. (The surface origin is its upper-left corner before any
+-- transformation has been applied.) The x and y patterns are negated and then
+-- set as translation values in the pattern matrix.
+--
+-- Other than the initial translation pattern matrix, as described above, all
+-- other pattern attributes, (such as its extend mode), are set to the default
+-- values as in 'patternCreateForSurface'. The resulting pattern can be queried
+-- with 'getSource' so that these attributes can be modified if desired, (eg. to
+-- create a repeating pattern with 'patternSetExtent'.
+--
+setSourceSurface ::
+ Surface -- ^ a surface to be used to set the source pattern
+ -> Double -- ^ user-space X coordinate for surface origin
+ -> Double -- ^ user-space Y coordinate for surface origin
+ -> Render ()
+setSourceSurface = liftRender3 Internal.setSourceSurface
+
+-- | Gets the current source pattern.
+--
+getSource :: Render Pattern
+getSource = liftRender0 Internal.getSource
+
+-- | Set the antialiasing mode of the rasterizer used for drawing shapes. This
+-- value is a hint, and a particular backend may or may not support a particular
+-- value. At the current time, no backend supports 'AntialiasSubpixel' when
+-- drawing shapes.
+--
+-- Note that this option does not affect text rendering, instead see
+-- 'fontOptionsSetAntilias'.
+--
+setAntialias ::
+ Antialias -- ^ the new antialiasing mode
+ -> Render ()
+setAntialias = liftRender1 Internal.setAntialias
+
+-- | Gets the current shape antialiasing mode, as set by 'setAntialias'.
+--
+getAntialias :: Render Antialias
+getAntialias = liftRender0 Internal.getAntialias
+
+-- | Sets the dash pattern to be used by 'stroke'. A dash pattern is specified
+-- by dashes, a list of positive values. Each value provides the user-space
+-- length of altenate "on" and "off" portions of the stroke. The offset
+-- specifies an offset into the pattern at which the stroke begins.
+--
+-- If @dashes@ is @[]@ then dashing is disabled.
+
+-- If @dashes@ is @[a]@ a symmetric pattern is assumed with alternating on and
+-- off portions of the size specified by the single value in dashes.
+
+-- If any value in @dashes@ is negative, or if all values are 0, then context
+-- will be put into an error state with a status of 'StatusInvalidDash'.
+--
+setDash ::
+ [Double] -- ^ @dashes@ a list specifying alternate lengths of on and off
+ -- portions of the stroke
+ -> Double -- ^ an offset into the dash pattern at which the stroke should
+ -- start
+ -> Render ()
+setDash = liftRender2 Internal.setDash
+
+-- | Set the current fill rule within the cairo context. The fill rule is used
+-- to determine which regions are inside or outside a complex (potentially
+-- self-intersecting) path. The current fill rule affects both 'fill' and
+-- 'clip'. See 'FillRule' for details on the semantics of each available fill
+-- rule.
+--
+setFillRule ::
+ FillRule -- ^ a fill rule
+ -> Render ()
+setFillRule = liftRender1 Internal.setFillRule
+
+-- | Gets the current fill rule, as set by 'setFillrule'.
+--
+getFillRule :: Render FillRule
+getFillRule = liftRender0 Internal.getFillRule
+
+-- | Sets the current line cap style within the cairo context. See 'LineCap'
+-- for details about how the available line cap styles are drawn.
+--
+-- As with the other stroke parameters, the current line cap style is examined
+-- by 'stroke', 'strokeExtents', and 'strokeToPath', but does not have any
+-- effect during path construction.
+--
+setLineCap ::
+ LineCap -- ^ a line cap style
+ -> Render ()
+setLineCap = liftRender1 Internal.setLineCap
+
+-- | Gets the current line cap style, as set by 'setLineCap'.
+--
+getLineCap :: Render LineCap
+getLineCap = liftRender0 Internal.getLineCap
+
+-- | Sets the current line join style within the cairo context. See 'LineJoin'
+-- for details about how the available line join styles are drawn.
+--
+-- As with the other stroke parameters, the current line join style is examined
+-- by 'stroke', 'strokeExtents', and 'strokeToPath', but does not have any
+-- effect during path construction.
+--
+setLineJoin ::
+ LineJoin -- ^ a line joint style
+ -> Render ()
+setLineJoin = liftRender1 Internal.setLineJoin
+
+-- | Gets the current line join style, as set by 'setLineJoin'.
+--
+getLineJoin :: Render LineJoin
+getLineJoin = liftRender0 Internal.getLineJoin
+
+-- | Sets the current line width within the cairo context. The line width
+-- specifies the diameter of a pen that is circular in user-space.
+--
+-- As with the other stroke parameters, the current line cap style is examined
+-- by 'stroke', 'strokeExtents', and 'strokeToPath', but does not have any
+-- effect during path construction.
+--
+setLineWidth ::
+ Double -- ^ a line width
+ -> Render ()
+setLineWidth = liftRender1 Internal.setLineWidth
+
+-- | Gets the current line width, as set by 'setLineWidth'.
+--
+getLineWidth :: Render Double
+getLineWidth = liftRender0 Internal.getLineWidth
+
+-- |
+--
+setMiterLimit ::
+ Double -- ^ -
+ -> Render ()
+setMiterLimit = liftRender1 Internal.setMiterLimit
+
+-- | Gets the current miter limit, as set by 'setMiterLimit'.
+--
+getMiterLimit :: Render Double
+getMiterLimit = liftRender0 Internal.getMiterLimit
+
+-- | Sets the compositing operator to be used for all drawing operations.
+-- See 'Operator' for details on the semantics of each available compositing
+-- operator.
+--
+setOperator ::
+ Operator -- ^ a compositing operator
+ -> Render ()
+setOperator = liftRender1 Internal.setOperator
+
+-- | Gets the current compositing operator for a cairo context.
+--
+getOperator :: Render Operator
+getOperator = liftRender0 Internal.getOperator
+
+-- | Sets the tolerance used when converting paths into trapezoids. Curved
+-- segments of the path will be subdivided until the maximum deviation between
+-- the original path and the polygonal approximation is less than tolerance.
+-- The default value is 0.1. A larger value will give better performance,
+-- a smaller value, better appearance. (Reducing the value from the default
+-- value of 0.1 is unlikely to improve appearance significantly.)
+--
+setTolerance ::
+ Double -- ^ the tolerance, in device units (typically pixels)
+ -> Render ()
+setTolerance = liftRender1 Internal.setTolerance
+
+-- | Gets the current tolerance value, as set by 'setTolerance'.
+--
+getTolerance :: Render Double
+getTolerance = liftRender0 Internal.getTolerance
+
+-- | Establishes a new clip region by intersecting the current clip region with
+-- the current path as it would be filled by 'fill' and according to the current
+-- fill rule (see 'setFillRule').
+--
+-- After 'clip', the current path will be cleared from the cairo context.
+--
+-- The current clip region affects all drawing operations by effectively masking
+-- out any changes to the surface that are outside the current clip region.
+--
+-- Calling 'clip' can only make the clip region smaller, never larger. But the
+-- current clip is part of the graphics state, so a temporary restriction of the
+-- clip region can be achieved by calling 'clip' within a 'save'/'restore' pair.
+-- The only other means of increasing the size of the clip region is 'resetClip'.
+--
+clip :: Render ()
+clip = liftRender0 Internal.clip
+
+-- | Establishes a new clip region by intersecting the current clip region with
+-- the current path as it would be filled by 'fill' and according to the current
+-- fill rule (see 'setFillRule').
+--
+-- Unlike 'clip', cairoClipPreserve preserves the path within the cairo context.
+--
+-- The current clip region affects all drawing operations by effectively masking
+-- out any changes to the surface that are outside the current clip region.
+--
+-- Calling 'clip' can only make the clip region smaller, never larger. But the
+-- current clip is part of the graphics state, so a temporary restriction of the
+-- clip region can be achieved by calling 'clip' within a 'save'/'restore' pair.
+-- The only other means of increasing the size of the clip region is 'resetClip'.
+--
+clipPreserve :: Render ()
+clipPreserve = liftRender0 Internal.clipPreserve
+
+-- | Reset the current clip region to its original, unrestricted state. That is,
+-- set the clip region to an infinitely large shape containing the target
+-- surface. Equivalently, if infinity is too hard to grasp, one can imagine the
+-- clip region being reset to the exact bounds of the target surface.
+--
+-- Note that code meant to be reusable should not call 'resetClip' as it will
+-- cause results unexpected by higher-level code which calls 'clip'. Consider
+-- using 'save' and 'restore' around 'clip' as a more robust means of
+-- temporarily restricting the clip region.
+--
+resetClip :: Render ()
+resetClip = liftRender0 Internal.resetClip
+
+-- | Computes a bounding box in user coordinates covering the area
+-- inside the current clip.
+--
+clipExtents :: Render (Double,Double,Double,Double)
+clipExtents = liftRender0 Internal.clipExtents
+
+-- | A drawing operator that fills the current path according to the current
+-- fill rule, (each sub-path is implicitly closed before being filled).
+-- After 'fill', the current path will be cleared from the cairo context.
+--
+-- See 'setFillRule' and 'fillPreserve'.
+--
+fill :: Render ()
+fill = liftRender0 Internal.fill
+
+-- | A drawing operator that fills the current path according to the current
+-- fill rule, (each sub-path is implicitly closed before being filled).
+-- Unlike 'fill', 'fillPreserve' preserves the path within the cairo context.
+--
+-- See 'setFillRule' and 'fill'.
+--
+fillPreserve :: Render ()
+fillPreserve = liftRender0 Internal.fillPreserve
+
+-- |
+--
+fillExtents :: Render (Double,Double,Double,Double)
+fillExtents = liftRender0 Internal.fillExtents
+
+-- |
+--
+inFill :: Double -> Double -> Render Bool
+inFill = liftRender2 Internal.inFill
+
+-- | A drawing operator that paints the current source using the alpha channel
+-- of pattern as a mask. (Opaque areas of mask are painted with the source,
+-- transparent areas are not painted.)
+--
+mask ::
+ Pattern -- ^ a 'Pattern'
+ -> Render ()
+mask = liftRender1 Internal.mask
+
+-- | A drawing operator that paints the current source using the alpha channel
+-- of surface as a mask. (Opaque areas of surface are painted with the source,
+-- transparent areas are not painted.)
+--
+maskSurface ::
+ Surface -- ^ a 'Surface'
+ -> Double -- ^ X coordinate at which to place the origin of surface
+ -> Double -- ^ Y coordinate at which to place the origin of surface
+ -> Render ()
+maskSurface = liftRender3 Internal.maskSurface
+
+-- | A drawing operator that paints the current source everywhere within the
+-- current clip region.
+--
+paint :: Render ()
+paint = liftRender0 Internal.paint
+
+-- | A drawing operator that paints the current source everywhere within the
+-- current clip region using a mask of constant alpha value alpha. The effect
+-- is similar to 'paint', but the drawing is faded out using the alpha value.
+--
+paintWithAlpha ::
+ Double -- ^ alpha value, between 0 (transparent) and 1 (opaque)
+ -> Render ()
+paintWithAlpha = liftRender1 Internal.paintWithAlpha
+
+-- | A drawing operator that strokes the current path according to the current
+-- line width, line join, line cap, and dash settings. After issuing 'stroke',
+-- the current path will be cleared from the 'Render' monad.
+--
+-- See 'setLineWidth', 'setLineJoin', 'setLineCap', 'setDash', and 'strokePreserve'.
+--
+stroke :: Render ()
+stroke = liftRender0 Internal.stroke
+
+-- | A drawing operator that strokes the current path according to the current
+-- line width, line join, line cap, and dash settings. Unlike 'stroke',
+-- 'strokePreserve' preserves the path within the 'Render' monad.
+--
+-- See 'setLineWidth', 'setLineJoin', 'setLineCap', 'setDash', and 'strokePreserve'.
+--
+strokePreserve :: Render ()
+strokePreserve = liftRender0 Internal.strokePreserve
+
+-- |
+--
+strokeExtents :: Render (Double,Double,Double,Double)
+strokeExtents = liftRender0 Internal.strokeExtents
+
+-- |
+--
+inStroke :: Double -> Double -> Render Bool
+inStroke = liftRender2 Internal.inStroke
+
+-- |
+--
+copyPage :: Render ()
+copyPage = liftRender0 Internal.copyPage
+
+-- |
+--
+showPage :: Render ()
+showPage = liftRender0 Internal.showPage
+
+
+-- | Gets the current point of the current path, which is conceptually the final
+-- point reached by the path so far.
+--
+-- The current point is returned in the user-space coordinate system. If there
+-- is no defined current point then x and y will both be set to 0.0.
+--
+-- Most path construction functions alter the current point. See the following
+-- for details on how they affect the current point: 'newPath', 'moveTo',
+-- 'lineTo', 'curveTo', 'arc', 'relMoveTo', 'relLineTo', 'relCurveTo',
+-- 'arcNegative', 'textPath', 'strokeToPath'.
+--
+getCurrentPoint :: Render (Double,Double)
+getCurrentPoint = liftRender0 Internal.getCurrentPoint
+
+-- | Clears the current path. After this call there will be no current point.
+--
+newPath :: Render ()
+newPath = liftRender0 Internal.newPath
+
+-- | Adds a line segment to the path from the current point to the beginning of
+-- the current subpath, (the most recent point passed to 'moveTo'), and closes
+-- this subpath.
+--
+-- The behavior of 'closePath' is distinct from simply calling 'lineTo' with the
+-- equivalent coordinate in the case of stroking. When a closed subpath is
+-- stroked, there are no caps on the ends of the subpath. Instead, their is a
+-- line join connecting the final and initial segments of the subpath.
+--
+closePath :: Render ()
+closePath = liftRender0 Internal.closePath
+
+-- | Adds a circular arc of the given radius to the current path. The arc is
+-- centered at (@xc@, @yc@), begins at @angle1@ and proceeds in the direction of
+-- increasing angles to end at @angle2@. If @angle2@ is less than @angle1@ it
+-- will be progressively increased by @2*pi@ until it is greater than @angle1@.
+--
+-- If there is a current point, an initial line segment will be added to the
+-- path to connect the current point to the beginning of the arc.
+--
+-- Angles are measured in radians. An angle of 0 is in the direction of the
+-- positive X axis (in user-space). An angle of @pi/2@ radians (90 degrees) is in
+-- the direction of the positive Y axis (in user-space). Angles increase in the
+-- direction from the positive X axis toward the positive Y axis. So with the
+-- default transformation matrix, angles increase in a clockwise direction.
+--
+-- (To convert from degrees to radians, use @degrees * (pi \/ 180)@.)
+--
+-- This function gives the arc in the direction of increasing angles; see
+-- 'arcNegative' to get the arc in the direction of decreasing angles.
+--
+-- The arc is circular in user-space. To achieve an elliptical arc, you can
+-- scale the current transformation matrix by different amounts in the X and Y
+-- directions. For example, to draw an ellipse in the box given by x, y, width,
+-- height:
+--
+-- > save
+-- > translate (x + width / 2) (y + height / 2)
+-- > scale (1 / (height / 2.)) (1 / (width / 2))
+-- > arc 0 0 1 0 (2 * pi)
+-- > restore
+--
+arc ::
+ Double -- ^ @xc@ - X position of the center of the arc
+ -> Double -- ^ @yc@ - Y position of the center of the arc
+ -> Double -- ^ @radius@ - the radius of the arc
+ -> Double -- ^ @angle1@ - the start angle, in radians
+ -> Double -- ^ @angle2@ - the end angle, in radians
+ -> Render ()
+arc = liftRender5 Internal.arc
+
+-- | Adds a circular arc of the given radius to the current path. The arc is
+-- centered at (@xc@, @yc@), begins at @angle1@ and proceeds in the direction of
+-- decreasing angles to end at @angle2@. If @angle2@ is greater than @angle1@ it
+-- will be progressively decreased by 2*@pi@ until it is greater than @angle1@.
+--
+-- See 'arc' for more details. This function differs only in the direction of
+-- the arc between the two angles.
+--
+arcNegative ::
+ Double -- ^ @xc@ - X position of the center of the arc
+ -> Double -- ^ @yc@ - Y position of the center of the arc
+ -> Double -- ^ @radius@ - the radius of the arc
+ -> Double -- ^ @angle1@ - the start angle, in radians
+ -> Double -- ^ @angle2@ - the end angle, in radians
+ -> Render ()
+arcNegative = liftRender5 Internal.arcNegative
+
+-- | Adds a cubic Bezier spline to the path from the current point to position
+-- (@x3@, @y3@) in user-space coordinates, using (@x1@, @y1@) and (@x2@, @y2@)
+-- as the control points. After this call the current point will be (@x3@, @y3@).
+--
+curveTo ::
+ Double -- ^ @x1@ - the X coordinate of the first control point
+ -> Double -- ^ @y1@ - the Y coordinate of the first control point
+ -> Double -- ^ @x2@ - the X coordinate of the second control point
+ -> Double -- ^ @y2@ - the Y coordinate of the second control point
+ -> Double -- ^ @x3@ - the X coordinate of the end of the curve
+ -> Double -- ^ @y3@ - the Y coordinate of the end of the curve
+ -> Render ()
+curveTo = liftRender6 Internal.curveTo
+
+-- | Adds a line to the path from the current point to position (@x@, @y@) in
+-- user-space coordinates. After this call the current point will be (@x@, @y@).
+--
+lineTo ::
+ Double -- ^ @x@ - the X coordinate of the end of the new line
+ -> Double -- ^ @y@ - the Y coordinate of the end of the new line
+ -> Render ()
+lineTo = liftRender2 Internal.lineTo
+
+-- | If the current subpath is not empty, begin a new subpath. After this call
+-- the current point will be (@x@, @y@).
+--
+moveTo ::
+ Double -- ^ @x@ - the X coordinate of the new position
+ -> Double -- ^ @y@ - the Y coordinate of the new position
+ -> Render ()
+moveTo = liftRender2 Internal.moveTo
+
+-- | Adds a closed-subpath rectangle of the given size to the current path at
+-- position (@x@, @y@) in user-space coordinates.
+--
+rectangle ::
+ Double -- ^ @x@ - the X coordinate of the top left corner of the rectangle
+ -> Double -- ^ @y@ - the Y coordinate of the top left corner of the rectangle
+ -> Double -- ^ @width@ - the width of the rectangle
+ -> Double -- ^ @height@ - the height of the rectangle
+ -> Render ()
+rectangle = liftRender4 Internal.rectangle
+
+-- | Render text at the current path.
+--
+-- * See 'showText' for why you should use Gtk functions.
+--
+textPath ::
+ CairoString string
+ => string -- ^ -
+ -> Render ()
+textPath = liftRender1 Internal.textPath
+
+-- | Relative-coordinate version of 'curveTo'. All offsets are relative to the
+-- current point. Adds a cubic Bezier spline to the path from the current point
+-- to a point offset from the current point by (@dx3@, @dy3@), using points
+-- offset by (@dx1@, @dy1@) and (@dx2@, @dy2@) as the control points. After this
+-- call the current point will be offset by (@dx3@, @dy3@).
+--
+-- Given a current point of (x, y), relCurveTo @dx1@ @dy1@ @dx2@ @dy2@ @dx3@ @dy3@
+-- is logically equivalent to curveTo (x + @dx1@) (y + @dy1@) (x + @dx2@) (y + @dy2@) (x + @dx3@) (y + @dy3@).
+--
+relCurveTo ::
+ Double -- ^ @dx1@ - the X offset to the first control point
+ -> Double -- ^ @dy1@ - the Y offset to the first control point
+ -> Double -- ^ @dx2@ - the X offset to the second control point
+ -> Double -- ^ @dy2@ - the Y offset to the second control point
+ -> Double -- ^ @dx3@ - the X offset to the end of the curve
+ -> Double -- ^ @dy3@ - the Y offset to the end of the curve
+ -> Render ()
+relCurveTo = liftRender6 Internal.relCurveTo
+
+-- | Relative-coordinate version of 'lineTo'. Adds a line to the path from the
+-- current point to a point that is offset from the current point by (@dx@, @dy@)
+-- in user space. After this call the current point will be offset by (@dx@, @dy@).
+--
+-- Given a current point of (x, y), relLineTo @dx@ @dy@ is logically equivalent
+-- to lineTo (x + @dx@) (y + @dy@).
+--
+relLineTo ::
+ Double -- ^ @dx@ - the X offset to the end of the new line
+ -> Double -- ^ @dy@ - the Y offset to the end of the new line
+ -> Render ()
+relLineTo = liftRender2 Internal.relLineTo
+
+-- | If the current subpath is not empty, begin a new subpath. After this call
+-- the current point will offset by (x, y).
+--
+-- Given a current point of (x, y), relMoveTo @dx@ @dy@ is logically equivalent
+-- to moveTo (x + @dx@) (y + @dy@)
+--
+relMoveTo ::
+ Double -- ^ @dx@ - the X offset
+ -> Double -- ^ @dy@ - the Y offset
+ -> Render ()
+relMoveTo = liftRender2 Internal.relMoveTo
+
+
+-- | Creates a new 'Pattern' corresponding to an opaque color. The color
+-- components are floating point numbers in the range 0 to 1. If the values
+-- passed in are outside that range, they will be clamped.
+--
+-- For example to create a solid red pattern:
+--
+-- > withRBGPattern 1 0 0 $ do
+-- > ...
+-- > ...
+--
+withRGBPattern ::
+ Double -- ^ red component of the color
+ -> Double -- ^ green component of the color
+ -> Double -- ^ blue component of the color
+ -> (Pattern -> Render a) -- ^ a nested render action using the pattern
+ -> Render a
+withRGBPattern r g b f =
+ bracketR (Internal.patternCreateRGB r g b)
+ (\pattern -> do status <- Internal.patternStatus pattern
+ liftIO $ Internal.patternDestroy pattern
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status)
+ (\pattern -> f pattern)
+
+-- | Creates a new 'Pattern' corresponding to a translucent color. The color
+-- components are floating point numbers in the range 0 to 1. If the values
+-- passed in are outside that range, they will be clamped.
+--
+-- For example to create a solid red pattern at 50% transparency:
+--
+-- > withRBGPattern 1 0 0 0.5 $ do
+-- > ...
+-- > ...
+--
+withRGBAPattern ::
+ Double -- ^ red component of color
+ -> Double -- ^ green component of color
+ -> Double -- ^ blue component of color
+ -> Double -- ^ alpha component of color
+ -> (Pattern -> Render a) -- ^ a nested render action using the pattern
+ -> Render a
+withRGBAPattern r g b a f =
+ bracketR (Internal.patternCreateRGBA r g b a)
+ (\pattern -> do status <- Internal.patternStatus pattern
+ liftIO $ Internal.patternDestroy pattern
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status)
+ (\pattern -> f pattern)
+
+-- | Create a new 'Pattern' for the given surface.
+--
+withPatternForSurface ::
+ Surface
+ -> (Pattern -> Render a) -- ^ a nested render action using the pattern
+ -> Render a
+withPatternForSurface surface f =
+ bracketR (Internal.patternCreateForSurface surface)
+ (\pattern -> do status <- Internal.patternStatus pattern
+ liftIO $ Internal.patternDestroy pattern
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status)
+ (\pattern -> f pattern)
+
+-- | Pop the current group from the group stack and use it as a pattern. The
+-- group should be populated first by calling 'pushGroup' or
+-- 'pushGroupWithContent' and doing some drawing operations. This also calls
+-- 'restore' to balance the 'save' called in 'pushGroup'.
+withGroupPattern :: (Pattern -> Render a) -- ^ a nested render action using the pattern
+ -> Render a
+withGroupPattern f = do
+ context <- ask
+ bracketR (Internal.popGroup context)
+ (\pattern -> do status <- Internal.patternStatus pattern
+ liftIO $ Internal.patternDestroy pattern
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status)
+ f
+
+-- | Create a new linear gradient 'Pattern' along the line defined by @(x0, y0)@
+-- and @(x1, y1)@. Before using the gradient pattern, a number of color stops
+-- should be defined using 'patternAddColorStopRGB' and 'patternAddColorStopRGBA'.
+--
+-- * Note: The coordinates here are in pattern space. For a new pattern,
+-- pattern space is identical to user space, but the relationship between the
+-- spaces can be changed with 'patternSetMatrix'.
+--
+withLinearPattern ::
+ Double -- ^ @x0@ - x coordinate of the start point
+ -> Double -- ^ @y0@ - y coordinate of the start point
+ -> Double -- ^ @x1@ - x coordinate of the end point
+ -> Double -- ^ @y1@ - y coordinate of the end point
+ -> (Pattern -> Render a) -- ^ a nested render action using the pattern
+ -> Render a
+withLinearPattern x0 y0 x1 y1 f =
+ bracketR (Internal.patternCreateLinear x0 y0 x1 y1)
+ (\pattern -> do status <- Internal.patternStatus pattern
+ liftIO $ Internal.patternDestroy pattern
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status)
+ (\pattern -> f pattern)
+
+-- | Creates a new radial gradient 'Pattern' between the two circles defined by
+-- @(x0, y0, c0)@ and @(x1, y1, c0)@. Before using the gradient pattern, a
+-- number of color stops should be defined using 'patternAddColorStopRGB'
+-- or 'patternAddColorStopRGBA'.
+--
+-- * Note: The coordinates here are in pattern space. For a new pattern,
+-- pattern space is identical to user space, but the relationship between the
+-- spaces can be changed with 'patternSetMatrix'.
+--
+withRadialPattern ::
+ Double -- ^ @cx0@ - x coordinate for the center of the start circle
+ -> Double -- ^ @cy0@ - y coordinate for the center of the start circle
+ -> Double -- ^ @radius0@ - radius of the start cirle
+ -> Double -- ^ @cx1@ - x coordinate for the center of the end circle
+ -> Double -- ^ @cy1@ - y coordinate for the center of the end circle
+ -> Double -- ^ @radius1@ - radius of the end circle
+ -> (Pattern -> Render a) -- ^ a nested render action using the pattern
+ -> Render a
+withRadialPattern cx0 cy0 radius0 cx1 cy1 radius1 f =
+ bracketR (Internal.patternCreateRadial cx0 cy0 radius0 cx1 cy1 radius1)
+ (\pattern -> do status <- Internal.patternStatus pattern
+ liftIO $ Internal.patternDestroy pattern
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status)
+ (\pattern -> f pattern)
+
+-- | Adds an opaque color stop to a gradient pattern. The offset specifies the
+-- location along the gradient's control vector. For example, a linear gradient's
+-- control vector is from (x0,y0) to (x1,y1) while a radial gradient's control
+-- vector is from any point on the start circle to the corresponding point on
+-- the end circle.
+--
+-- The color is specified in the same way as in 'setSourceRGB'.
+--
+-- Note: If the pattern is not a gradient pattern, (eg. a linear or radial
+-- pattern), then the pattern will be put into an error status with a status of
+-- 'StatusPatternTypeMismatch'.
+--
+patternAddColorStopRGB ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> Double -- ^ an offset in the range [0.0 .. 1.0]
+ -> Double -- ^ red component of color
+ -> Double -- ^ green component of color
+ -> Double -- ^ blue component of color
+ -> m ()
+patternAddColorStopRGB p offset r g b = liftIO $ Internal.patternAddColorStopRGB p offset r g b
+
+-- | Adds a translucent color stop to a gradient pattern. The offset specifies
+-- the location along the gradient's control vector. For example, a linear
+-- gradient's control vector is from (x0,y0) to (x1,y1) while a radial gradient's
+-- control vector is from any point on the start circle to the corresponding
+-- point on the end circle.
+--
+-- The color is specified in the same way as in setSourceRGBA.
+--
+-- Note: If the pattern is not a gradient pattern, (eg. a linear or radial
+-- pattern), then the pattern will be put into an error status with a status of
+-- 'StatusPatternTypeMismatch'.
+--
+patternAddColorStopRGBA ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> Double -- ^ an offset in the range [0.0 .. 1.0]
+ -> Double -- ^ red component of color
+ -> Double -- ^ green component of color
+ -> Double -- ^ blue component of color
+ -> Double -- ^ alpha component of color
+ -> m ()
+patternAddColorStopRGBA p offset r g b a = liftIO $ Internal.patternAddColorStopRGBA p offset r g b a
+
+-- | Sets the pattern's transformation matrix to matrix. This matrix is a
+-- transformation from user space to pattern space.
+--
+-- When a pattern is first created it always has the identity matrix for its
+-- transformation matrix, which means that pattern space is initially identical
+-- to user space.
+--
+-- Important: Please note that the direction of this transformation matrix is
+-- from user space to pattern space. This means that if you imagine the flow
+-- from a pattern to user space (and on to device space), then coordinates in
+-- that flow will be transformed by the inverse of the pattern matrix.
+--
+-- Also, please note the discussion of the user-space locking semantics of 'setSource'.
+--
+patternSetMatrix ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> Matrix -- ^ a 'Matrix'
+ -> m ()
+patternSetMatrix p m = liftIO $ Internal.patternSetMatrix p m
+
+-- | Get the pattern's transformation matrix.
+--
+patternGetMatrix ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> m Matrix
+patternGetMatrix p = liftIO $ Internal.patternGetMatrix p
+
+-- |
+--
+patternSetExtend ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> Extend -- ^ an 'Extent'
+ -> m ()
+patternSetExtend p e = liftIO $ Internal.patternSetExtend p e
+
+-- |
+--
+patternGetExtend ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> m Extend
+patternGetExtend p = liftIO $ Internal.patternGetExtend p
+
+-- |
+--
+patternSetFilter ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> Filter -- ^ a 'Filter'
+ -> m ()
+patternSetFilter p f = liftIO $ Internal.patternSetFilter p f
+
+-- |
+--
+patternGetFilter ::
+ MonadIO m =>
+ Pattern -- ^ a 'Pattern'
+ -> m Filter
+patternGetFilter p = liftIO $ Internal.patternGetFilter p
+
+
+-- | Modifies the current transformation matrix (CTM) by translating the
+-- user-space origin by @(tx, ty)@. This offset is interpreted as a user-space
+-- coordinate according to the CTM in place before the new call to 'translate'.
+-- In other words, the translation of the user-space origin takes place after
+-- any existing transformation.
+--
+translate ::
+ Double -- ^ @tx@ - amount to translate in the X direction
+ -> Double -- ^ @ty@ - amount to translate in the Y direction
+ -> Render ()
+translate = liftRender2 Internal.translate
+
+-- | Modifies the current transformation matrix (CTM) by scaling the X and Y
+-- user-space axes by sx and sy respectively. The scaling of the axes takes
+-- place after any existing transformation of user space.
+--
+scale ::
+ Double -- ^ @sx@ - scale factor for the X dimension
+ -> Double -- ^ @sy@ - scale factor for the Y dimension
+ -> Render ()
+scale = liftRender2 Internal.scale
+
+-- | Modifies the current transformation matrix (CTM) by rotating the user-space
+-- axes by @angle@ radians. The rotation of the axes takes places after any
+-- existing transformation of user space. The rotation direction for positive
+-- angles is from the positive X axis toward the positive Y axis.
+--
+rotate ::
+ Double -- ^ @angle@ - angle (in radians) by which the user-space axes will
+ -- be rotated
+ -> Render ()
+rotate = liftRender1 Internal.rotate
+
+-- | Modifies the current transformation matrix (CTM) by applying matrix as an
+-- additional transformation. The new transformation of user space takes place
+-- after any existing transformation.
+--
+transform ::
+ Matrix -- ^ @matrix@ - a transformation to be applied to the user-space axes
+ -> Render ()
+transform = liftRender1 Internal.transform
+
+-- | Modifies the current transformation matrix (CTM) by setting it equal to
+-- @matrix@.
+setMatrix ::
+ Matrix -- ^ @matrix@ - a transformation matrix from user space to device space
+ -> Render ()
+setMatrix = liftRender1 Internal.setMatrix
+
+-- | Gets the current transformation matrix, as set by 'setMatrix'.
+--
+getMatrix :: Render Matrix
+getMatrix = liftRender0 Internal.getMatrix
+
+-- | Resets the current transformation matrix (CTM) by setting it equal to the
+-- identity matrix. That is, the user-space and device-space axes will be
+-- aligned and one user-space unit will transform to one device-space unit.
+--
+identityMatrix :: Render ()
+identityMatrix = liftRender0 Internal.identityMatrix
+
+-- | Transform a coordinate from user space to device space by multiplying the
+-- given point by the current transformation matrix (CTM).
+--
+userToDevice ::
+ Double -- ^ X value of coordinate
+ -> Double -- ^ Y value of coordinate
+ -> Render (Double,Double)
+userToDevice = liftRender2 Internal.userToDevice
+
+-- | Transform a distance vector from user space to device space. This function
+-- is similar to 'userToDevice' except that the translation components of the
+-- CTM will be ignored when transforming @(dx,dy)@.
+--
+userToDeviceDistance ::
+ Double -- ^ @dx@ - X component of a distance vector
+ -> Double -- ^ @dy@ - Y component of a distance vector
+ -> Render (Double,Double)
+userToDeviceDistance = liftRender2 Internal.userToDeviceDistance
+
+-- | Transform a coordinate from device space to user space by multiplying the
+-- given point by the inverse of the current transformation matrix (CTM).
+--
+deviceToUser ::
+ Double -- ^ X value of coordinate
+ -> Double -- ^ Y value of coordinate
+ -> Render (Double,Double)
+deviceToUser = liftRender2 Internal.deviceToUser
+
+-- | Transform a distance vector from device space to user space. This function
+-- is similar to 'deviceToUser' except that the translation components of the
+-- inverse CTM will be ignored when transforming @(dx,dy)@.
+--
+deviceToUserDistance ::
+ Double -- ^ @dx@ - X component of a distance vector
+ -> Double -- ^ @dy@ - Y component of a distance vector
+ -> Render (Double,Double)
+deviceToUserDistance = liftRender2 Internal.deviceToUserDistance
+
+
+-- | Selects a family and style of font from a simplified description as a
+-- @family@ name, @slant@ and @weight@. This function is meant to be used only
+-- for applications with simple font needs: Cairo doesn't provide for operations
+-- such as listing all available fonts on the system, and it is expected that
+-- most applications will need to use a more comprehensive font handling and
+-- text layout library in addition to cairo.
+--
+selectFontFace ::
+ CairoString string
+ => string -- ^ @family@ - a font family name
+ -> FontSlant -- ^ @slant@ - the slant for the font
+ -> FontWeight -- ^ @weight@ - the weight of the font
+ -> Render ()
+selectFontFace = liftRender3 Internal.selectFontFace
+
+-- | Sets the current font matrix to a scale by a factor of @size@, replacing
+-- any font matrix previously set with 'setFontSize' or 'setFontMatrix'. This
+-- results in a font size of size user space units. (More precisely, this matrix
+-- will result in the font's em-square being a size by size square in user space.)
+--
+setFontSize ::
+ Double -- ^ @size@ - the new font size, in user space units
+ -> Render ()
+setFontSize = liftRender1 Internal.setFontSize
+
+-- | Sets the current font matrix to @matrix@. The font matrix gives a
+-- transformation from the design space of the font (in this space, the
+-- em-square is 1 unit by 1 unit) to user space. Normally, a simple scale is
+-- used (see 'setFontSize'), but a more complex font matrix can be used to shear
+-- the font or stretch it unequally along the two axes.
+--
+setFontMatrix ::
+ Matrix -- ^ @matrix@ - a 'Matrix' describing a transform to be applied to
+ -- the current font.
+ -> Render ()
+setFontMatrix = liftRender1 Internal.setFontMatrix
+
+-- | Gets the current font matrix, as set by 'setFontMatrix'
+--
+getFontMatrix :: Render Matrix
+getFontMatrix = liftRender0 Internal.getFontMatrix
+
+-- | Sets a set of custom font rendering options. Rendering options are
+-- derived by merging these options with the options derived from underlying
+-- surface; if the value in @options@ has a default value (like
+-- 'AntialiasDefault'), then the value from the surface is used.
+--
+setFontOptions :: FontOptions -> Render ()
+setFontOptions = liftRender1 Internal.setFontOptions
+
+-- | A drawing operator that generates the shape from a string of Unicode
+-- characters, rendered according to the current font face, font size (font
+-- matrix), and font options.
+--
+-- This function first computes a set of glyphs for the string of text. The
+-- first glyph is placed so that its origin is at the current point. The origin
+-- of each subsequent glyph is offset from that of the previous glyph by the
+-- advance values of the previous glyph.
+--
+-- After this call the current point is moved to the origin of where the next
+-- glyph would be placed in this same progression. That is, the current point
+-- will be at the origin of the final glyph offset by its advance values. This
+-- allows for easy display of a single logical string with multiple calls to
+-- 'showText'.
+--
+-- NOTE: The 'showText' function call is part of what the cairo designers call
+-- the \"toy\" text API. It is convenient for short demos and simple programs,
+-- but it is not expected to be adequate for the most serious of text-using
+-- applications.
+--
+showText ::
+ CairoString string
+ => string -- ^ a string of text
+ -> Render ()
+showText = liftRender1 Internal.showText
+
+-- | Gets the font extents for the currently selected font.
+--
+fontExtents :: Render FontExtents
+fontExtents = liftRender0 Internal.fontExtents
+
+-- | Gets the extents for a string of text. The extents describe a user-space
+-- rectangle that encloses the \"inked\" portion of the text, (as it would be
+-- drawn by 'showText'). Additionally, the 'textExtentsXadvance' and
+-- 'textExtentsYadvance' values indicate the amount by which the current point
+-- would be advanced by 'showText'.
+--
+-- Note that whitespace characters do not directly contribute to the size of
+-- the rectangle ('textExtentsWidth' and 'textExtentsHeight'). They do contribute
+-- indirectly by changing the position of non-whitespace characters.
+-- In particular, trailing whitespace characters are likely to not affect the
+-- size of the rectangle, though they will affect the 'textExtentsXadvance' and
+-- 'textExtentsYadvance' values.
+--
+textExtents ::
+ CairoString string
+ => string -- ^ a string of text
+ -> Render TextExtents
+textExtents = liftRender1 Internal.textExtents
+
+
+-- | Allocates a new font options object with all options initialized to default
+-- values.
+--
+fontOptionsCreate :: MonadIO m => m FontOptions
+fontOptionsCreate = liftIO $ Internal.fontOptionsCreate
+
+-- | Allocates a new font options object copying the option values from @original@.
+--
+fontOptionsCopy ::
+ MonadIO m =>
+ FontOptions -- ^ @original@
+ -> m FontOptions
+fontOptionsCopy a = liftIO $ Internal.fontOptionsCopy a
+
+-- | Merges non-default options from @other@ into @options@, replacing existing
+-- values. This operation can be thought of as somewhat similar to compositing
+-- @other@ onto @options@ with the operation of 'OperationOver'.
+--
+fontOptionsMerge ::
+ MonadIO m =>
+ FontOptions -- ^ @options@
+ -> FontOptions -- ^ @other@
+ -> m ()
+fontOptionsMerge a b = liftIO $ Internal.fontOptionsMerge a b
+
+-- | Compute a hash for the font options object; this value will be useful when
+-- storing an object containing a 'FontOptions' in a hash table.
+--
+fontOptionsHash :: MonadIO m => FontOptions -> m Int
+fontOptionsHash a = liftIO $ Internal.fontOptionsHash a
+
+-- | Compares two font options objects for equality.
+--
+fontOptionsEqual :: MonadIO m => FontOptions -> FontOptions -> m Bool
+fontOptionsEqual a b = liftIO $ Internal.fontOptionsEqual a b
+
+-- | Sets the antiliasing mode for the font options object. This specifies the
+-- type of antialiasing to do when rendering text.
+--
+fontOptionsSetAntialias :: MonadIO m => FontOptions -> Antialias -> m ()
+fontOptionsSetAntialias a b = liftIO $ Internal.fontOptionsSetAntialias a b
+
+-- | Gets the antialising mode for the font options object.
+--
+fontOptionsGetAntialias :: MonadIO m => FontOptions -> m Antialias
+fontOptionsGetAntialias a = liftIO $ Internal.fontOptionsGetAntialias a
+
+-- | Sets the subpixel order for the font options object. The subpixel order
+-- specifies the order of color elements within each pixel on the display device
+-- when rendering with an antialiasing mode of 'AntialiasSubpixel'.
+-- See the documentation for 'SubpixelOrder' for full details.
+--
+fontOptionsSetSubpixelOrder :: MonadIO m => FontOptions -> SubpixelOrder-> m ()
+fontOptionsSetSubpixelOrder a b = liftIO $ Internal.fontOptionsSetSubpixelOrder a b
+
+-- | Gets the subpixel order for the font options object.
+-- See the documentation for 'SubpixelOrder' for full details.
+--
+fontOptionsGetSubpixelOrder :: MonadIO m => FontOptions -> m SubpixelOrder
+fontOptionsGetSubpixelOrder a = liftIO $ Internal.fontOptionsGetSubpixelOrder a
+
+-- | Sets the hint style for font outlines for the font options object.
+-- This controls whether to fit font outlines to the pixel grid, and if so,
+-- whether to optimize for fidelity or contrast. See the documentation for
+-- 'HintStyle' for full details.
+--
+fontOptionsSetHintStyle :: MonadIO m => FontOptions -> HintStyle -> m ()
+fontOptionsSetHintStyle a b = liftIO $ Internal.fontOptionsSetHintStyle a b
+
+-- | Gets the hint style for font outlines for the font options object.
+-- See the documentation for 'HintStyle' for full details.
+--
+fontOptionsGetHintStyle :: MonadIO m => FontOptions -> m HintStyle
+fontOptionsGetHintStyle a = liftIO $ Internal.fontOptionsGetHintStyle a
+
+-- | Sets the metrics hinting mode for the font options object. This controls
+-- whether metrics are quantized to integer values in device units. See the
+-- documentation for 'HintMetrics' for full details.
+--
+fontOptionsSetHintMetrics :: MonadIO m => FontOptions -> HintMetrics -> m ()
+fontOptionsSetHintMetrics a b = liftIO $ Internal.fontOptionsSetHintMetrics a b
+
+-- | Gets the metrics hinting mode for the font options object. See the
+-- documentation for 'HintMetrics' for full details.
+--
+fontOptionsGetHintMetrics :: MonadIO m => FontOptions -> m HintMetrics
+fontOptionsGetHintMetrics a = liftIO $ Internal.fontOptionsGetHintMetrics a
+
+
+-- | Create a temporary surface that is as compatible as possible with an
+-- existing surface. The new surface will use the same backend as other unless
+-- that is not possible for some reason.
+--
+withSimilarSurface ::
+ Surface -- ^ an existing surface used to select the backend of the new surface
+ -> Content -- ^ the content type for the new surface (color, color+alpha or alpha only)
+ -> Int -- ^ width of the new surface, (in device-space units)
+ -> Int -- ^ height of the new surface (in device-space units)
+ -> (Surface -> IO a)
+ -> IO a
+withSimilarSurface surface contentType width height f =
+ bracket (Internal.surfaceCreateSimilar surface contentType width height)
+ (\surface' -> do status <- Internal.surfaceStatus surface'
+ Internal.surfaceDestroy surface'
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail)
+ (\surface' -> f surface')
+
+
+-- | Like 'withSimilarSurface' but creates a Surface that is managed by the
+-- Haskell memory manager rather than only being temporaily allocated. This
+-- is more flexible and allows you to create surfaces that persist, which
+-- can be very useful, for example to cache static elements in an animation.
+--
+-- However you should be careful because surfaces can be expensive resources
+-- and the Haskell memory manager cannot guarantee when it will release them.
+-- You can manually release the resources used by a surface with
+-- 'surfaceFinish'.
+--
+createSimilarSurface ::
+ Surface -- ^ an existing surface used to select the backend of the new surface
+ -> Content -- ^ the content type for the new surface (color, color+alpha or alpha only)
+ -> Int -- ^ width of the surface, in pixels
+ -> Int -- ^ height of the surface, in pixels
+ -> IO Surface
+createSimilarSurface surface contentType width height = do
+ surface <- Internal.surfaceCreateSimilar surface contentType width height
+ Internal.manageSurface surface
+ return surface
+
+-- | Create a temporary surface that is compatible with the current target
+-- surface (like a combination of 'withTargetSurface' and 'withSimilarSurface').
+--
+-- This is useful for drawing to a temporary surface and then compositing it
+-- into the main suface. For example, the following code draws to a temporary
+-- surface and then uses that as a mask:
+--
+-- > renderWithSimilarSurface ContentAlpha 200 200 $ \tmpSurface -> do
+-- > renderWith tmpSurface $ do
+-- > ... -- draw onto the temporary surface
+-- >
+-- > -- use the temporary surface as a mask, filling it with the
+-- > -- current source which in this example is transparent red.
+-- > setSourceRGBA 1 0 0 0.5
+-- > setOperator Operator{something} -- think of something clever to do
+-- > maskSurface tmpSurface 0 0)
+--
+renderWithSimilarSurface ::
+ Content -- ^ the content type for the new surface
+ -- (color, colour+alpha or alpha only)
+ -> Int -- ^ width of the new surface, (in device-space units)
+ -> Int -- ^ height of the new surface, (in device-space units)
+ -> (Surface -> Render a) -- ^ this action draws on the main surface,
+ -- possibly making use of the temporary surface
+ -- (which gets destroyed afterwards).
+ -> Render a
+renderWithSimilarSurface contentType width height render =
+ withTargetSurface $ \surface ->
+ bracketR (Internal.surfaceCreateSimilar surface contentType width height)
+ (\surface' -> do status <- Internal.surfaceStatus surface'
+ Internal.surfaceDestroy surface'
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail)
+ (\surface' -> render surface')
+
+-- | This function finishes the surface and drops all references to external
+-- resources. For example, for the Xlib backend it means that cairo will no
+-- longer access the drawable, which can be freed. After calling 'surfaceFinish'
+-- the only valid operations on a surface are getting and setting user data and
+-- referencing and destroying it. Further drawing to the surface will not affect
+-- the surface but will instead trigger a 'StatusSurfaceFinished' error.
+--
+-- When the last call to 'surfaceDestroy' decreases the reference count to zero,
+-- cairo will call 'surfaceFinish' if it hasn't been called already, before
+-- freeing the resources associated with the surface.
+--
+surfaceFinish :: MonadIO m => Surface -> m ()
+surfaceFinish surface = liftIO $ do
+ status <- Internal.surfaceStatus surface
+ Internal.surfaceFinish surface
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Do any pending drawing for the surface and also restore any temporary
+-- modification's cairo has made to the surface's state. This function must be
+-- called before switching from drawing on the surface with cairo to drawing on
+-- it directly with native APIs. If the surface doesn't support direct access,
+-- then this function does nothing.
+--
+surfaceFlush :: MonadIO m => Surface -> m ()
+surfaceFlush a = liftIO $ Internal.surfaceFlush a
+
+-- | Retrieves the default font rendering options for the surface. This allows
+-- display surfaces to report the correct subpixel order for rendering on them,
+-- print surfaces to disable hinting of metrics and so forth. The result can
+-- then be used with 'scaledFontCreate'.
+--
+surfaceGetFontOptions :: Surface -> Render FontOptions
+surfaceGetFontOptions surface = do
+ fontOptions <- fontOptionsCreate
+ liftIO $ Internal.surfaceGetFontOptions surface fontOptions
+ return fontOptions
+
+-- | Tells cairo that drawing has been done to surface using means other than
+-- cairo, and that cairo should reread any cached areas. Note that you must call
+-- 'surfaceFlush' before doing such drawing.
+--
+surfaceMarkDirty :: MonadIO m => Surface -> m ()
+surfaceMarkDirty a = liftIO $ Internal.surfaceMarkDirty a
+
+-- | Like 'surfaceMarkDirty', but drawing has been done only to the specified
+-- rectangle, so that cairo can retain cached contents for other parts of the
+-- surface.
+--
+surfaceMarkDirtyRectangle ::
+ MonadIO m =>
+ Surface -- ^ a 'Surface'
+ -> Int -- ^ X coordinate of dirty rectangle
+ -> Int -- ^ Y coordinate of dirty rectangle
+ -> Int -- ^ width of dirty rectangle
+ -> Int -- ^ height of dirty rectangle
+ -> m ()
+surfaceMarkDirtyRectangle a b c d e = liftIO $ Internal.surfaceMarkDirtyRectangle a b c d e
+
+-- | Sets an offset that is added to the device coordinates determined by the
+-- CTM when drawing to surface. One use case for this function is when we want
+-- to create a 'Surface' that redirects drawing for a portion of an
+-- onscreen surface to an offscreen surface in a way that is completely
+-- invisible to the user of the cairo API. Setting a transformation via
+-- 'translate' isn't sufficient to do this, since functions like 'deviceToUser'
+-- will expose the hidden offset.
+--
+-- Note that the offset only affects drawing to the surface, not using the
+-- surface in a surface pattern.
+--
+surfaceSetDeviceOffset ::
+ MonadIO m =>
+ Surface -- ^ a 'Surface'
+ -> Double -- ^ the offset in the X direction, in device units
+ -> Double -- ^ the offset in the Y direction, in device units
+ -> m ()
+surfaceSetDeviceOffset a b c = liftIO $ Internal.surfaceSetDeviceOffset a b c
+
+#if CAIRO_CHECK_VERSION(1,6,0)
+-- | This function provides a stride value that will respect all alignment
+-- requirements of the accelerated image-rendering code within cairo.
+--
+formatStrideForWidth ::
+ Format -- ^ format of pixels in the surface to create
+ -> Int -- ^ width of the surface, in pixels
+ -> Int -- ^ the stride (number of bytes necessary to store one line)
+ -- or @-1@ if the format is invalid or the width is too large
+formatStrideForWidth = Internal.formatStrideForWidth
+#endif
+
+-- | Creates an image surface of the specified format and dimensions.
+-- The initial contents of the surface is undefined; you must explicitely
+-- clear the buffer, using, for example, 'rectangle' and 'fill' if you want it
+-- cleared.
+--
+withImageSurface ::
+ Format -- ^ format of pixels in the surface to create
+ -> Int -- ^ width of the surface, in pixels
+ -> Int -- ^ height of the surface, in pixels
+ -> (Surface -> IO a) -- ^ an action that may use the surface. The surface is
+ -- only valid within in this action.
+ -> IO a
+withImageSurface format width height f =
+ bracket (Internal.imageSurfaceCreate format width height)
+ (\surface -> do status <- Internal.surfaceStatus surface
+ Internal.surfaceDestroy surface
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail)
+ (\surface -> f surface)
+
+-- | Like 'withImageSurface' but creates a Surface that is managed by the
+-- Haskell memory manager rather than only being temporaily allocated. This
+-- is more flexible and allows you to create surfaces that persist, which
+-- can be very useful, for example to cache static elements in an animation.
+--
+-- However you should be careful because surfaces can be expensive resources
+-- and the Haskell memory manager cannot guarantee when it will release them.
+-- You can manually release the resources used by a surface with
+-- 'surfaceFinish'.
+--
+createImageSurface ::
+ Format -- ^ format of pixels in the surface to create
+ -> Int -- ^ width of the surface, in pixels
+ -> Int -- ^ height of the surface, in pixels
+ -> IO Surface
+createImageSurface format width height = do
+ surface <- Internal.imageSurfaceCreate format width height
+ Internal.manageSurface surface
+ return surface
+
+-- | Like 'withImageSurface' but creating a surface to target external
+-- data pointed to by 'PixelData'.
+--
+withImageSurfaceForData ::
+ PixelData -- ^ pointer to pixel data
+ -> Format -- ^ format of pixels in the surface to create
+ -> Int -- ^ width of the surface, in pixels
+ -> Int -- ^ height of the surface, in pixels
+ -> Int -- ^ size of stride between rows in the surface to create
+ -> (Surface -> IO a) -- ^ an action that may use the surface. The surface is
+ -- only valid within this action
+ -> IO a
+withImageSurfaceForData pixels format width height stride f =
+ bracket (Internal.imageSurfaceCreateForData pixels format width height stride)
+ (\surface -> do status <- Internal.surfaceStatus surface
+ Internal.surfaceDestroy surface
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail)
+ (\surface -> f surface)
+
+-- | Like 'createImageSurface' but creating a surface to target external
+-- data pointed to by 'PixelData'.
+--
+createImageSurfaceForData ::
+ PixelData -- ^ pointer to pixel data
+ -> Format -- ^ format of pixels in the surface to create
+ -> Int -- ^ width of the surface, in pixels
+ -> Int -- ^ height of the surface, in pixels
+ -> Int -- ^ size of stride between rows in the surface to create
+ -> IO Surface
+createImageSurfaceForData pixels format width height stride = do
+ surface <- Internal.imageSurfaceCreateForData pixels format width height stride
+ Internal.manageSurface surface
+ return surface
+
+-- | Get the width of the image surface in pixels.
+--
+imageSurfaceGetWidth :: MonadIO m => Surface -> m Int
+imageSurfaceGetWidth a = liftIO $ Internal.imageSurfaceGetWidth a
+
+-- | Get the height of the image surface in pixels.
+--
+imageSurfaceGetHeight :: MonadIO m => Surface -> m Int
+imageSurfaceGetHeight a = liftIO $ Internal.imageSurfaceGetHeight a
+
+#if CAIRO_CHECK_VERSION(1,2,0)
+-- | Get the number of bytes from the start of one row to the start of the
+-- next. If the image data contains no padding, then this is equal to
+-- the pixel depth * the width.
+imageSurfaceGetStride :: MonadIO m => Surface -> m Int
+imageSurfaceGetStride = liftIO . Internal.imageSurfaceGetStride
+
+
+-- | Get the format of the surface.
+--
+imageSurfaceGetFormat :: MonadIO m => Surface -> m Format
+imageSurfaceGetFormat a = liftIO $ Internal.imageSurfaceGetFormat a
+
+#if __GLASGOW_HASKELL__ >= 606
+-- | Return a ByteString of the image data for a surface. In order to remain
+-- safe the returned ByteString is a copy of the data. This is a little
+-- slower than returning a pointer into the image surface object itself, but
+-- much safer
+imageSurfaceGetData :: Surface -> IO BS.ByteString
+imageSurfaceGetData a = do
+ height <- Internal.imageSurfaceGetHeight a
+ stride <- Internal.imageSurfaceGetStride a
+ ptr <- Internal.imageSurfaceGetData a
+#if __GLASGOW_HASKELL__ < 608
+ BS.copyCStringLen (castPtr ptr, height * stride)
+#else
+ BS.packCStringLen (castPtr ptr, height * stride)
+#endif
+#endif
+
+
+-- | Retrieve the internal array of raw image data.
+--
+-- * Image data in an image surface is stored in memory in uncompressed,
+-- packed format. Rows in the image are stored top to bottom, and in each
+-- row pixels are stored from left to right. There may be padding at the end
+-- of a row. The value returned by 'imageSurfaceGetStride' indicates the
+-- number of bytes between rows.
+--
+-- * The returned array is a flat representation of a three dimensional array:
+-- x-coordiante, y-coordinate and several channels for each color. The
+-- format depends on the 'Format' of the surface:
+--
+-- 'FormatARGB32': each pixel is 32 bits with alpha in the upper 8 bits,
+-- followed by 8 bits for red, green and blue. Pre-multiplied alpha is used.
+-- (That is, 50% transparent red is 0x80800000, not 0x80ff0000.)
+--
+-- 'FormatRGB24': each pixel is 32 bits with the upper 8 bits being unused,
+-- followed by 8 bits for red, green and blue.
+--
+-- 'FormatA8': each pixel is 8 bits holding an alpha value
+--
+-- 'FormatA1': each pixel is one bit where pixels are packed into 32 bit
+-- quantities. The ordering depends on the endianes of the platform. On a
+-- big-endian machine, the first pixel is in the uppermost bit, on a
+-- little-endian machine the first pixel is in the least-significant bit.
+--
+-- * To read or write a specific pixel (and assuming 'FormatARGB32' or
+-- 'FormatRGB24'), use the formula: @p = y * (rowstride `div` 4) + x@ for the
+-- pixel and force the array to have 32-bit words or integers.
+--
+-- * Calling this function without explicitly giving it a type will often lead
+-- to a compiler error since the type parameter @e@ is underspecified. If
+-- this happens the function can be explicitly typed:
+-- @surData <- (imageSurfaceGetPixels pb :: IO (SurfaceData Int Word32))@
+--
+-- * If modifying an image through Haskell\'s array interface is not fast
+-- enough, it is possible to use 'unsafeRead' and 'unsafeWrite' which have
+-- the same type signatures as 'readArray' and 'writeArray'. Note that these
+-- are internal functions that might change with GHC.
+--
+-- * After each write access to the array, you need to inform Cairo
+-- about the area that has changed using 'surfaceMarkDirty'.
+--
+-- * The function will return an error if the surface is not an image
+-- surface or if 'surfaceFinish' has been called on the surface.
+--
+imageSurfaceGetPixels :: Storable e => Surface -> IO (SurfaceData Int e)
+imageSurfaceGetPixels pb = do
+ pixPtr <- Internal.imageSurfaceGetData pb
+ when (pixPtr==nullPtr) $ do
+ fail "imageSurfaceGetPixels: image surface not available"
+ h <- imageSurfaceGetHeight pb
+ r <- imageSurfaceGetStride pb
+ return (mkSurfaceData pb (castPtr pixPtr) (h*r))
+
+-- | An array that stores the raw pixel data of an image 'Surface'.
+--
+data SurfaceData i e = SurfaceData !Surface
+ {-# UNPACK #-} !(Ptr e)
+ !(i,i)
+ {-# UNPACK #-} !Int
+
+mkSurfaceData :: Storable e => Surface -> Ptr e -> Int -> SurfaceData Int e
+mkSurfaceData pb (ptr :: Ptr e) size =
+ SurfaceData pb ptr (0, count-1) count
+ where count = fromIntegral (size `div` sizeOf (undefined :: e))
+
+#if __GLASGOW_HASKELL__ < 605
+instance HasBounds SurfaceData where
+ bounds (SurfaceData pb ptr bd cnt) = bd
+#endif
+
+-- | 'SurfaceData' is a mutable array.
+instance Storable e => MArray SurfaceData e IO where
+ newArray (l,u) e = error "GI.Cairo.Render.newArray: not implemented"
+ newArray_ (l,u) = error "GI.Cairo.Render.newArray_: not implemented"
+ {-# INLINE unsafeRead #-}
+ unsafeRead (SurfaceData (Surface pb) pixPtr _ _) idx = do
+ e <- peekElemOff pixPtr idx
+ touchForeignPtr pb
+ return e
+ {-# INLINE unsafeWrite #-}
+ unsafeWrite (SurfaceData (Surface pb) pixPtr _ _) idx elem = do
+ pokeElemOff pixPtr idx elem
+ touchForeignPtr pb
+#if __GLASGOW_HASKELL__ >= 605
+ {-# INLINE getBounds #-}
+ getBounds (SurfaceData _ _ bd _) = return bd
+#endif
+#if __GLASGOW_HASKELL__ >= 608
+ {-# INLINE getNumElements #-}
+ getNumElements (SurfaceData _ _ _ count) = return count
+#endif
+
+
+#endif
+
+#ifdef CAIRO_HAS_PDF_SURFACE
+-- | Creates a PostScript surface of the specified size in points to
+-- be written to @filename@.
+--
+-- Note that the size of individual pages of the PostScript output can
+-- vary. See 'psSurfaceSetSize'.
+--
+withPDFSurface ::
+ FilePath -- ^ @filename@ - a filename for the PS output (must be writable)
+ -> Double -- ^ width of the surface, in points (1 point == 1\/72.0 inch)
+ -> Double -- ^ height of the surface, in points (1 point == 1\/72.0 inch)
+ -> (Surface -> IO a) -- ^ an action that may use the surface. The surface is
+ -- only valid within in this action.
+ -> IO a
+withPDFSurface filename width height f = do
+ surface <- Internal.pdfSurfaceCreate filename width height
+ ret <- f surface
+ Internal.surfaceDestroy surface
+ return ret
+
+#if CAIRO_CHECK_VERSION(1,2,0)
+-- | Changes the size of a PDF surface for the current (and
+-- subsequent) pages.
+--
+-- This function should only be called before any drawing operations
+-- have been performed on the current page. The simplest way to do
+-- this is to call this function immediately after creating the
+-- surface or immediately after completing a page with either
+-- 'showPage' or 'copyPage'.
+--
+pdfSurfaceSetSize :: MonadIO m => Surface -> Double -> Double -> m ()
+pdfSurfaceSetSize s x y = liftIO $ Internal.pdfSurfaceSetSize s x y
+#endif
+#endif
+
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+-- | Creates a new image surface and initializes the contents to the given PNG
+-- file.
+--
+withImageSurfaceFromPNG :: FilePath -> (Surface -> IO a) -> IO a
+withImageSurfaceFromPNG filename f =
+ bracket (Internal.imageSurfaceCreateFromPNG filename)
+ (\surface -> do status <- Internal.surfaceStatus surface
+ Internal.surfaceDestroy surface
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail)
+ (\surface -> f surface)
+
+-- | Writes the contents of surface to a new file @filename@ as a PNG image.
+--
+surfaceWriteToPNG ::
+ Surface -- ^ a 'Surface'
+ -> FilePath -- ^ @filename@ - the name of a file to write to
+ -> IO ()
+surfaceWriteToPNG surface filename = do
+ status <- Internal.surfaceWriteToPNG surface filename
+ unless (status == StatusSuccess) $
+ fail =<< Internal.statusToString status
+ return ()
+#endif
+
+#ifdef CAIRO_HAS_PS_SURFACE
+-- | Creates a PostScript surface of the specified size in points to
+-- be written to @filename@.
+--
+-- Note that the size of individual pages of the PostScript output can
+-- vary. See 'psSurfaceSetSize'.
+--
+withPSSurface ::
+ FilePath -- ^ @filename@ - a filename for the PS output (must be writable)
+ -> Double -- ^ width of the surface, in points (1 point == 1\/72.0 inch)
+ -> Double -- ^ height of the surface, in points (1 point == 1\/72.0 inch)
+ -> (Surface -> IO a) -- ^ an action that may use the surface. The surface is
+ -- only valid within in this action.
+ -> IO a
+withPSSurface filename width height f =
+ bracket (Internal.psSurfaceCreate filename width height)
+ (\surface -> do status <- Internal.surfaceStatus surface
+ Internal.surfaceDestroy surface
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail)
+ (\surface -> f surface)
+
+#if CAIRO_CHECK_VERSION(1,2,0)
+-- | Changes the size of a PostScript surface for the current (and
+-- subsequent) pages.
+--
+-- This function should only be called before any drawing operations
+-- have been performed on the current page. The simplest way to do
+-- this is to call this function immediately after creating the
+-- surface or immediately after completing a page with either
+-- 'showPage' or 'copyPage'.
+--
+psSurfaceSetSize :: MonadIO m => Surface -> Double -> Double -> m ()
+psSurfaceSetSize s x y = liftIO $ Internal.psSurfaceSetSize s x y
+#endif
+#endif
+
+
+#ifdef CAIRO_HAS_SVG_SURFACE
+-- | Creates a SVG surface of the specified size in points
+-- be written to @filename@.
+--
+withSVGSurface ::
+ FilePath -- ^ @filename@ - a filename for the SVG output (must be writable)
+ -> Double -- ^ width of the surface, in points (1 point == 1\/72.0 inch)
+ -> Double -- ^ height of the surface, in points (1 point == 1\/72.0 inch)
+ -> (Surface -> IO a) -- ^ an action that may use the surface. The surface is
+ -- only valid within in this action.
+ -> IO a
+withSVGSurface filename width height f =
+ bracket (Internal.svgSurfaceCreate filename width height)
+ (\surface -> do status <- Internal.surfaceStatus surface
+ Internal.surfaceDestroy surface
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail)
+ (\surface -> f surface)
+#endif
+
+#if CAIRO_CHECK_VERSION(1,10,0)
+
+-- | Allocates a new empty region object.
+--
+regionCreate :: MonadIO m => m Region
+regionCreate = liftIO $ Internal.regionCreate
+
+-- | Allocates a new region object containing @rectangle@.
+--
+regionCreateRectangle ::
+ MonadIO m =>
+ RectangleInt -- ^ @rectangle@
+ -> m Region
+regionCreateRectangle a = liftIO $ Internal.regionCreateRectangle a
+
+-- | Allocates a new region object containing the union of all given @rects@.
+--
+regionCreateRectangles ::
+ MonadIO m =>
+ [RectangleInt] -- ^ @rects@
+ -> m Region
+regionCreateRectangles a = liftIO $ Internal.regionCreateRectangles a
+
+-- | Allocates a new region object copying the area from @original@.
+--
+regionCopy ::
+ MonadIO m =>
+ Region -- ^ @original@
+ -> m Region
+regionCopy a = liftIO $ Internal.regionCopy a
+
+-- | Gets the bounding rectangle of @region@ as a RectanglInt.
+--
+regionGetExtents ::
+ MonadIO m =>
+ Region -- ^ @region@
+ -> m RectangleInt
+regionGetExtents a = liftIO $ Internal.regionGetExtents a
+
+-- | Returns the number of rectangles contained in @region@.
+--
+regionNumRectangles ::
+ MonadIO m =>
+ Region -- ^ @region@
+ -> m Int
+regionNumRectangles a = liftIO $ Internal.regionNumRectangles a
+
+-- | Gets the @nth@ rectangle from the @region@.
+--
+regionGetRectangle ::
+ MonadIO m =>
+ Region -- ^ @region@
+ -> Int -- ^ @nth@
+ -> m RectangleInt
+regionGetRectangle a n = liftIO $ Internal.regionGetRectangle a n
+
+-- | Checks whether @region@ is empty.
+--
+regionIsEmpty ::
+ MonadIO m =>
+ Region -- ^ @region@
+ -> m Bool
+regionIsEmpty a = liftIO $ Internal.regionIsEmpty a
+
+-- | Checks whether (@x@, @y@) is contained in @region@.
+--
+regionContainsPoint ::
+ MonadIO m =>
+ Region -- ^ @region@
+ -> Int -- ^ @x@
+ -> Int -- ^ @y@
+ -> m Bool
+regionContainsPoint a x y = liftIO $ Internal.regionContainsPoint a x y
+
+-- | Checks whether @rectangle@ is inside, outside or partially contained in @region@.
+--
+regionContainsRectangle ::
+ MonadIO m =>
+ Region -- ^ @region@
+ -> RectangleInt -- ^ @rectangle@
+ -> m RegionOverlap
+regionContainsRectangle a rect = liftIO $ Internal.regionContainsRectangle a rect
+
+-- | Compares whether @region_a@ is equivalent to @region_b@.
+--
+regionEqual ::
+ MonadIO m =>
+ Region -- ^ @region_a@
+ -> Region -- ^ @region_b@
+ -> m Bool
+regionEqual a b = liftIO $ Internal.regionEqual a b
+
+-- | Translates @region@ by (@dx@, @dy@).
+--
+regionTranslate ::
+ MonadIO m =>
+ Region -- ^ @region@
+ -> Int -- ^ @dx@
+ -> Int -- ^ @dy@
+ -> m ()
+regionTranslate a dx dy = liftIO $ Internal.regionTranslate a dx dy
+
+-- | Computes the intersection of @dst@ with @other@ and places the result in @dst@.
+--
+regionIntersect ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> Region -- ^ @other@
+ -> m ()
+regionIntersect a b = liftIO $ do
+ status <- Internal.regionIntersect a b
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Computes the intersection of @dst@ with @rectangle@ and places the result in @dst@.
+--
+regionIntersectRectangle ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> RectangleInt -- ^ @rectangle@
+ -> m ()
+regionIntersectRectangle a rect = liftIO $ do
+ status <- Internal.regionIntersectRectangle a rect
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Subtracts @other@ from @dst@ and places the result in @dst@.
+--
+regionSubtract ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> Region -- ^ @other@
+ -> m ()
+regionSubtract a b = liftIO $ do
+ status <- Internal.regionSubtract a b
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Subtracts @rectangle@ from @dst@ and places the result in @dst@.
+--
+regionSubtractRectangle ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> RectangleInt -- ^ @rectangle@
+ -> m ()
+regionSubtractRectangle a rect = liftIO $ do
+ status <- Internal.regionSubtractRectangle a rect
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Computes the union of @dst@ with @other@ and places the result in @dst@.
+--
+regionUnion ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> Region -- ^ @other@
+ -> m ()
+regionUnion a b = liftIO $ do
+ status <- Internal.regionUnion a b
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Computes the union of @dst@ with @rectangle@ and places the result in @dst@.
+--
+regionUnionRectangle ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> RectangleInt -- ^ @rectangle@
+ -> m ()
+regionUnionRectangle a rect = liftIO $ do
+ status <- Internal.regionUnionRectangle a rect
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Computes the exclusive difference of @dst@ with @other@ and places the result in @dst@.
+-- That is, @dst@ will be set to contain all areas that are either in @dst@ or in @other@, but not in both.
+--
+regionXor ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> Region -- ^ @other@
+ -> m ()
+regionXor a b = liftIO $ do
+ status <- Internal.regionXor a b
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+-- | Computes the exclusive difference of @dst@ with @rectangle@ and places the result in @dst@.
+-- That is, @dst@ will be set to contain all areas that are either in @dst@ or in @rectangle@, but not in both
+--
+regionXorRectangle ::
+ MonadIO m =>
+ Region -- ^ @dst@
+ -> RectangleInt -- ^ @rectangle@
+ -> m ()
+regionXorRectangle a rect = liftIO $ do
+ status <- Internal.regionXorRectangle a rect
+ unless (status == StatusSuccess) $
+ Internal.statusToString status >>= fail
+
+#endif
+
+-- | Returns the version of the cairo library encoded in a single integer.
+--
+version :: Int
+version = Internal.version
+
+-- | Returns the version of the cairo library as a human-readable string of the
+-- form \"X.Y.Z\".
+--
+versionString :: String
+versionString = Internal.versionString
+
diff --git a/GI/Cairo/Render/Internal.hs b/GI/Cairo/Render/Internal.hs
new file mode 100644
index 0000000..3520b7a
--- /dev/null
+++ b/GI/Cairo/Render/Internal.hs
@@ -0,0 +1,70 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_HADDOCK hide #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Direct bindings to the cairo library.
+-----------------------------------------------------------------------------
+-- #hide
+--
+module GI.Cairo.Render.Internal (
+ Render(..), bracketR
+ , module GI.Cairo.Render.Types
+ , module GI.Cairo.Render.Internal.Drawing.Cairo
+ , module GI.Cairo.Render.Internal.Drawing.Paths
+ , module GI.Cairo.Render.Internal.Drawing.Patterns
+ , module GI.Cairo.Render.Internal.Drawing.Text
+ , module GI.Cairo.Render.Internal.Drawing.Transformations
+ , module GI.Cairo.Render.Internal.Fonts.FontOptions
+ , module GI.Cairo.Render.Internal.Surfaces.Image
+ , module GI.Cairo.Render.Internal.Surfaces.PDF
+ , module GI.Cairo.Render.Internal.Surfaces.PNG
+ , module GI.Cairo.Render.Internal.Surfaces.PS
+ , module GI.Cairo.Render.Internal.Surfaces.SVG
+ , module GI.Cairo.Render.Internal.Surfaces.Surface
+ , module GI.Cairo.Render.Internal.Region
+ , module GI.Cairo.Render.Internal.Utilities
+
+ ) where
+
+import GI.Cairo.Render.Types
+import GI.Cairo.Render.Internal.Drawing.Cairo
+import GI.Cairo.Render.Internal.Drawing.Paths
+import GI.Cairo.Render.Internal.Drawing.Patterns
+import GI.Cairo.Render.Internal.Drawing.Text
+import GI.Cairo.Render.Internal.Drawing.Transformations
+import GI.Cairo.Render.Internal.Fonts.FontOptions
+import GI.Cairo.Render.Internal.Surfaces.Image
+import GI.Cairo.Render.Internal.Surfaces.PDF
+import GI.Cairo.Render.Internal.Surfaces.PNG
+import GI.Cairo.Render.Internal.Surfaces.PS
+import GI.Cairo.Render.Internal.Surfaces.SVG
+import GI.Cairo.Render.Internal.Surfaces.Surface
+import GI.Cairo.Render.Internal.Region
+import GI.Cairo.Render.Internal.Utilities
+
+import Control.Monad.Reader
+import Control.Applicative
+import Control.Exception (bracket)
+
+-- | The Render monad. All drawing operations take place in a Render context.
+-- You can obtain a Render context for a 'Surface' using 'renderWith'.
+--
+newtype Render m = Render { runRender :: ReaderT Cairo IO m }
+ deriving (Functor, Applicative, Monad, MonadIO, MonadReader Cairo)
+
+{-# INLINE bracketR #-}
+bracketR :: IO a -> (a -> IO b) -> (a -> Render c) -> Render c
+bracketR begin end action =
+ Render $
+ ReaderT $ \r ->
+ bracket begin end
+ (\s -> runReaderT (runRender $ action s) r)
+
diff --git a/GI/Cairo/Render/Internal/Drawing/Cairo.chs b/GI/Cairo/Render/Internal/Drawing/Cairo.chs
new file mode 100644
index 0000000..5ebbd54
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Drawing/Cairo.chs
@@ -0,0 +1,77 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Drawing.Cairo
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- The cairo drawing context functions.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Drawing.Cairo where
+
+{#import GI.Cairo.Render.Types#}
+
+import Data.GI.Base(wrapBoxed, withManagedPtr)
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun create { withSurface* `Surface' } -> `CairoPtr' #}
+{#fun save { withManagedPtr* `Cairo' } -> `()' #}
+{#fun restore { withManagedPtr* `Cairo' } -> `()' #}
+{#fun status as status { withManagedPtr* `Cairo' } -> `Status' cToEnum#}
+{#fun get_target as getTarget { withManagedPtr* `Cairo' } -> `Surface' mkSurface*#}
+{#fun push_group as ^ { withManagedPtr* `Cairo' } -> `()' #}
+{#fun push_group_with_content as ^ { withManagedPtr* `Cairo', cFromEnum `Content' } -> `()' #}
+{#fun pop_group as ^ { withManagedPtr* `Cairo' } -> `Pattern' #}
+{#fun pop_group_to_source as ^ { withManagedPtr* `Cairo' } -> `()' #}
+{#fun set_source_rgb as setSourceRGB { withManagedPtr* `Cairo', `Double', `Double', `Double' } -> `()'#}
+{#fun set_source_rgba as setSourceRGBA { withManagedPtr* `Cairo', `Double', `Double', `Double', `Double' } -> `()'#}
+{#fun set_source as setSource { withManagedPtr* `Cairo', `Pattern' } -> `()'#}
+{#fun set_source_surface as setSourceSurface { withManagedPtr* `Cairo', withSurface* `Surface', `Double', `Double' } -> `()'#}
+{#fun get_source as getSource { withManagedPtr* `Cairo' } -> `Pattern' #}
+{#fun set_antialias as setAntialias { withManagedPtr* `Cairo', cFromEnum `Antialias' } -> `()'#}
+{#fun get_antialias as getAntialias { withManagedPtr* `Cairo' } -> `Antialias' cToEnum#}
+setDash context xs offset =
+ withManagedPtr context $ \ctxt ->
+ withArrayLen (map (cFloatConv) xs) $ \len ptr ->
+ {#call set_dash#} ctxt ptr (cIntConv len) (cFloatConv offset)
+{#fun set_fill_rule as setFillRule { withManagedPtr* `Cairo', cFromEnum `FillRule' } -> `()'#}
+{#fun get_fill_rule as getFillRule { withManagedPtr* `Cairo' } -> `FillRule' cToEnum#}
+{#fun set_line_cap as setLineCap { withManagedPtr* `Cairo', cFromEnum `LineCap' } -> `()'#}
+{#fun get_line_cap as getLineCap { withManagedPtr* `Cairo' } -> `LineCap' cToEnum#}
+{#fun set_line_join as setLineJoin { withManagedPtr* `Cairo', cFromEnum `LineJoin' } -> `()'#}
+{#fun get_line_join as getLineJoin { withManagedPtr* `Cairo' } -> `LineJoin' cToEnum#}
+{#fun set_line_width as setLineWidth { withManagedPtr* `Cairo', `Double' } -> `()'#}
+{#fun get_line_width as getLineWidth { withManagedPtr* `Cairo' } -> `Double'#}
+{#fun set_miter_limit as setMiterLimit { withManagedPtr* `Cairo', `Double' } -> `()'#}
+{#fun get_miter_limit as getMiterLimit { withManagedPtr* `Cairo' } -> `Double'#}
+{#fun set_operator as setOperator { withManagedPtr* `Cairo', cFromEnum `Operator' } -> `()'#}
+{#fun get_operator as getOperator { withManagedPtr* `Cairo' } -> `Operator' cToEnum#}
+{#fun set_tolerance as setTolerance { withManagedPtr* `Cairo', `Double' } -> `()'#}
+{#fun get_tolerance as getTolerance { withManagedPtr* `Cairo' } -> `Double'#}
+{#fun clip as clip { withManagedPtr* `Cairo' } -> `()'#}
+{#fun clip_preserve as clipPreserve { withManagedPtr* `Cairo' } -> `()'#}
+{#fun reset_clip as resetClip { withManagedPtr* `Cairo' } -> `()'#}
+{#fun clip_extents as clipExtents { withManagedPtr* `Cairo', alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv* } -> `()'#}
+{#fun fill as fill { withManagedPtr* `Cairo' } -> `()'#}
+{#fun fill_preserve as fillPreserve { withManagedPtr* `Cairo' } -> `()'#}
+{#fun fill_extents as fillExtents { withManagedPtr* `Cairo', alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv* } -> `()'#}
+{#fun in_fill as inFill { withManagedPtr* `Cairo', `Double', `Double' } -> `Bool' cToBool#}
+{#fun mask as mask { withManagedPtr* `Cairo', `Pattern' } -> `()'#}
+{#fun mask_surface as maskSurface { withManagedPtr* `Cairo', withSurface* `Surface', `Double', `Double' } -> `()'#}
+{#fun paint as paint { withManagedPtr* `Cairo' } -> `()'#}
+{#fun paint_with_alpha as paintWithAlpha { withManagedPtr* `Cairo', `Double' } -> `()'#}
+{#fun stroke as stroke { withManagedPtr* `Cairo' } -> `()'#}
+{#fun stroke_preserve as strokePreserve { withManagedPtr* `Cairo' } -> `()'#}
+{#fun stroke_extents as strokeExtents { withManagedPtr* `Cairo', alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv* } -> `()'#}
+{#fun in_stroke as inStroke { withManagedPtr* `Cairo', `Double', `Double' } -> `Bool' cToBool#}
+{#fun copy_page as copyPage { withManagedPtr* `Cairo' } -> `()'#}
+{#fun show_page as showPage { withManagedPtr* `Cairo' } -> `()'#}
diff --git a/GI/Cairo/Render/Internal/Drawing/Paths.chs b/GI/Cairo/Render/Internal/Drawing/Paths.chs
new file mode 100644
index 0000000..3412962
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Drawing/Paths.chs
@@ -0,0 +1,45 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Drawing.Paths
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Creating paths and manipulating path data.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Drawing.Paths where
+
+{#import GI.Cairo.Render.Types#}
+
+import Data.GI.Base(wrapBoxed, withManagedPtr)
+import Foreign
+import Foreign.C
+import Data.Text
+
+import GI.Cairo.Render.Internal.Utilities (CairoString(..))
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun get_current_point as getCurrentPoint { withManagedPtr* `Cairo', alloca- `Double' peekFloatConv*, alloca- `Double' peekFloatConv* } -> `()'#}
+{#fun new_path as newPath { withManagedPtr* `Cairo' } -> `()'#}
+{#fun close_path as closePath { withManagedPtr* `Cairo' } -> `()'#}
+{#fun arc as arc { withManagedPtr* `Cairo', `Double', `Double', `Double', `Double', `Double' } -> `()'#}
+{#fun arc_negative as arcNegative { withManagedPtr* `Cairo', `Double', `Double', `Double', `Double', `Double' } -> `()'#}
+{#fun curve_to as curveTo { withManagedPtr* `Cairo', `Double', `Double', `Double', `Double', `Double', `Double' } -> `()'#}
+{#fun line_to as lineTo { withManagedPtr* `Cairo', `Double', `Double' } -> `()'#}
+{#fun move_to as moveTo { withManagedPtr* `Cairo', `Double', `Double' } -> `()'#}
+{#fun rectangle as rectangle { withManagedPtr* `Cairo', `Double', `Double', `Double', `Double' } -> `()'#}
+textPath :: CairoString string => Cairo -> string -> IO ()
+textPath c string =
+ withManagedPtr c $ \ctxt ->
+ withUTFString string $ \string' ->
+ {# call text_path #} ctxt string'
+{#fun rel_curve_to as relCurveTo { withManagedPtr* `Cairo', `Double', `Double', `Double', `Double', `Double', `Double' } -> `()'#}
+{#fun rel_line_to as relLineTo { withManagedPtr* `Cairo', `Double', `Double' } -> `()'#}
+{#fun rel_move_to as relMoveTo { withManagedPtr* `Cairo', `Double', `Double' } -> `()'#}
diff --git a/GI/Cairo/Render/Internal/Drawing/Patterns.chs b/GI/Cairo/Render/Internal/Drawing/Patterns.chs
new file mode 100644
index 0000000..33f93ad
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Drawing/Patterns.chs
@@ -0,0 +1,43 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Drawing.Patterns
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Gradients and filtered sources.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Drawing.Patterns where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+import qualified Foreign.C.Types as C2HSImp
+import qualified Foreign.Ptr as C2HSImp
+import qualified Foreign.Storable as C2HSImp
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun pattern_add_color_stop_rgb as patternAddColorStopRGB { `Pattern', `Double', `Double', `Double', `Double' } -> `()'#}
+{#fun pattern_add_color_stop_rgba as patternAddColorStopRGBA { `Pattern', `Double', `Double', `Double', `Double', `Double' } -> `()'#}
+{#fun pattern_create_rgb as patternCreateRGB { `Double', `Double', `Double' } -> `Pattern' #}
+{#fun pattern_create_rgba as patternCreateRGBA { `Double', `Double', `Double', `Double' } -> `Pattern' #}
+{#fun pattern_create_for_surface as patternCreateForSurface { withSurface* `Surface' } -> `Pattern'#}
+{#fun pattern_create_linear as patternCreateLinear { `Double', `Double', `Double', `Double' } -> `Pattern'#}
+{#fun pattern_create_radial as patternCreateRadial { `Double', `Double', `Double', `Double', `Double', `Double' } -> `Pattern'#}
+{#fun pattern_destroy as patternDestroy { `Pattern' } -> `()'#}
+{#fun pattern_reference as patternReference { `Pattern' } -> `Pattern' #}
+{#fun pattern_status as patternStatus { `Pattern' } -> `Status' cToEnum#}
+{#fun pattern_set_extend as patternSetExtend { `Pattern', cFromEnum `Extend' } -> `()'#}
+{#fun pattern_get_extend as patternGetExtend { `Pattern' } -> `Extend' cToEnum#}
+{#fun pattern_set_filter as patternSetFilter { `Pattern', cFromEnum `Filter' } -> `()'#}
+{#fun pattern_get_filter as patternGetFilter { `Pattern' } -> `Filter' cToEnum#}
+{#fun pattern_set_matrix as patternSetMatrix { `Pattern', with* `Matrix' } -> `()'#}
+{#fun pattern_get_matrix as patternGetMatrix { `Pattern', alloca- `Matrix' peek*} -> `()'#}
diff --git a/GI/Cairo/Render/Internal/Drawing/Text.chs b/GI/Cairo/Render/Internal/Drawing/Text.chs
new file mode 100644
index 0000000..8327fe6
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Drawing/Text.chs
@@ -0,0 +1,56 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Drawing.Text
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Rendering text.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Drawing.Text where
+
+{#import GI.Cairo.Render.Types#}
+
+import GI.Cairo.Render.Internal.Utilities (CairoString(..))
+
+import Data.GI.Base(wrapBoxed, withManagedPtr)
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+selectFontFace :: CairoString string => Cairo -> string -> FontSlant -> FontWeight -> IO ()
+selectFontFace c string slant weight =
+ withManagedPtr c $ \ctxt ->
+ withUTFString string $ \string' ->
+ {# call select_font_face #}
+ ctxt string' (cFromEnum slant) (cFromEnum weight)
+
+{#fun set_font_size as setFontSize { withManagedPtr* `Cairo', `Double' } -> `()'#}
+{#fun set_font_matrix as setFontMatrix { withManagedPtr* `Cairo', with* `Matrix' } -> `()'#}
+{#fun get_font_matrix as getFontMatrix { withManagedPtr* `Cairo', alloca- `Matrix' peek*} -> `()'#}
+{#fun set_font_options as setFontOptions { withManagedPtr* `Cairo', withFontOptions* `FontOptions' } -> `()'#}
+
+showText :: CairoString string => Cairo -> string -> IO ()
+showText c string =
+ withManagedPtr c $ \ctxt ->
+ withUTFString string $ \string' ->
+ {# call show_text #}
+ ctxt string'
+
+{#fun font_extents as fontExtents { withManagedPtr* `Cairo', alloca- `FontExtents' peek* } -> `()'#}
+
+textExtents :: CairoString string => Cairo -> string -> IO TextExtents
+textExtents c string =
+ withManagedPtr c $ \ctxt ->
+ withUTFString string $ \string' ->
+ alloca $ \result -> do
+ {# call text_extents #}
+ ctxt string' result
+ peek result
diff --git a/GI/Cairo/Render/Internal/Drawing/Transformations.chs b/GI/Cairo/Render/Internal/Drawing/Transformations.chs
new file mode 100644
index 0000000..6b73b25
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Drawing/Transformations.chs
@@ -0,0 +1,36 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Drawing.Tranformations
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Manipulating the current transformation matrix.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Drawing.Transformations where
+
+{#import GI.Cairo.Render.Types#}
+
+import Data.GI.Base(wrapBoxed, withManagedPtr)
+import Foreign hiding (rotate)
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun translate as translate { withManagedPtr* `Cairo', `Double', `Double' } -> `()'#}
+{#fun scale as scale { withManagedPtr* `Cairo', `Double', `Double' } -> `()'#}
+{#fun rotate as rotate { withManagedPtr* `Cairo', `Double' } -> `()'#}
+{#fun transform as transform { withManagedPtr* `Cairo', with* `Matrix' } -> `()'#}
+{#fun set_matrix as setMatrix { withManagedPtr* `Cairo', with* `Matrix' } -> `()'#}
+{#fun get_matrix as getMatrix { withManagedPtr* `Cairo', alloca- `Matrix' peek*} -> `()'#}
+{#fun identity_matrix as identityMatrix { withManagedPtr* `Cairo' } -> `()'#}
+{#fun user_to_device as userToDevice { withManagedPtr* `Cairo', withFloatConv* `Double' peekFloatConv*, withFloatConv* `Double' peekFloatConv* } -> `()'#}
+{#fun user_to_device_distance as userToDeviceDistance { withManagedPtr* `Cairo', withFloatConv* `Double' peekFloatConv*, withFloatConv* `Double' peekFloatConv* } -> `()'#}
+{#fun device_to_user as deviceToUser { withManagedPtr* `Cairo', withFloatConv* `Double' peekFloatConv*, withFloatConv* `Double' peekFloatConv* } -> `()'#}
+{#fun device_to_user_distance as deviceToUserDistance { withManagedPtr* `Cairo', withFloatConv* `Double' peekFloatConv*, withFloatConv* `Double' peekFloatConv* } -> `()'#}
diff --git a/GI/Cairo/Render/Internal/Fonts/FontOptions.chs b/GI/Cairo/Render/Internal/Fonts/FontOptions.chs
new file mode 100644
index 0000000..5cfe12e
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Fonts/FontOptions.chs
@@ -0,0 +1,42 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Fonts.FontOptions
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- How a font should be rendered.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Fonts.FontOptions where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+import qualified Foreign.C.Types as C2HSImp
+import qualified Foreign.Ptr as C2HSImp
+import qualified Foreign.Storable as C2HSImp
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun font_options_create as fontOptionsCreate { } -> `FontOptions' mkFontOptions*#}
+{#fun font_options_copy as fontOptionsCopy { withFontOptions* `FontOptions' } -> `FontOptions' mkFontOptions*#}
+{#fun font_options_destroy as fontOptionsDestroy { withFontOptions* `FontOptions' } -> `()'#}
+{#fun font_options_status as fontOptionsStatus { withFontOptions* `FontOptions' } -> `Status' cToEnum#}
+{#fun font_options_merge as fontOptionsMerge { withFontOptions* `FontOptions', withFontOptions* `FontOptions' } -> `()'#}
+{#fun font_options_hash as fontOptionsHash { withFontOptions* `FontOptions' } -> `Int'#}
+{#fun font_options_equal as fontOptionsEqual { withFontOptions* `FontOptions', withFontOptions* `FontOptions' } -> `Bool'#}
+{#fun font_options_set_antialias as fontOptionsSetAntialias { withFontOptions* `FontOptions', cFromEnum `Antialias' } -> `()'#}
+{#fun font_options_get_antialias as fontOptionsGetAntialias { withFontOptions* `FontOptions' } -> `Antialias' cToEnum#}
+{#fun font_options_set_subpixel_order as fontOptionsSetSubpixelOrder { withFontOptions* `FontOptions', cFromEnum `SubpixelOrder' } -> `()'#}
+{#fun font_options_get_subpixel_order as fontOptionsGetSubpixelOrder { withFontOptions* `FontOptions' } -> `SubpixelOrder' cToEnum#}
+{#fun font_options_set_hint_style as fontOptionsSetHintStyle { withFontOptions* `FontOptions', cFromEnum `HintStyle' } -> `()'#}
+{#fun font_options_get_hint_style as fontOptionsGetHintStyle { withFontOptions* `FontOptions' } -> `HintStyle' cToEnum#}
+{#fun font_options_set_hint_metrics as fontOptionsSetHintMetrics { withFontOptions* `FontOptions', cFromEnum `HintMetrics' } -> `()'#}
+{#fun font_options_get_hint_metrics as fontOptionsGetHintMetrics { withFontOptions* `FontOptions' } -> `HintMetrics' cToEnum#}
diff --git a/GI/Cairo/Render/Internal/Region.chs b/GI/Cairo/Render/Internal/Region.chs
new file mode 100644
index 0000000..224c807
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Region.chs
@@ -0,0 +1,57 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Region
+-- Copyright : (c) Hamish Mackenzie 2013
+-- License : BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer :
+-- Stability : experimental
+-- Portability : portable
+--
+-- Region functions.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Region where
+
+#if CAIRO_CHECK_VERSION(1,10,0)
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+import qualified Foreign.C.Types as C2HSImp
+import qualified Foreign.Ptr as C2HSImp
+import qualified Foreign.Storable as C2HSImp
+
+{#context lib="cairo" prefix="cairo"#}
+
+regionCreateRectangles rects =
+ withArrayLen rects $ \ n ptr ->
+ {#call region_create_rectangles#} ptr (fromIntegral n) >>= mkRegion
+
+{#fun region_create as regionCreate {} -> `Region' mkRegion*#}
+{#fun region_create_rectangle as regionCreateRectangle { with* `RectangleInt' } -> `Region' mkRegion*#}
+{#fun region_copy as regionCopy { withRegion* `Region' } -> `Region' mkRegion*#}
+{#fun region_destroy as regionDestroy { withRegion* `Region' } -> `()'#}
+{#fun region_reference as regionReference { withRegion* `Region' } -> `()'#}
+{#fun region_status as regionStatus { withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_get_extents as regionGetExtents { withRegion* `Region', alloca- `RectangleInt' peek* } -> `()'#}
+{#fun region_num_rectangles as regionNumRectangles { withRegion* `Region' } -> `Int' fromIntegral#}
+{#fun region_get_rectangle as regionGetRectangle { withRegion* `Region', fromIntegral `Int', alloca- `RectangleInt' peek* } -> `()'#}
+{#fun region_is_empty as regionIsEmpty { withRegion* `Region' } -> `Bool' cToBool#}
+{#fun region_contains_point as regionContainsPoint { withRegion* `Region', fromIntegral `Int', fromIntegral `Int' } -> `Bool' cToBool#}
+{#fun region_contains_rectangle as regionContainsRectangle { withRegion* `Region', with* `RectangleInt' } -> `RegionOverlap' cToEnum#}
+{#fun region_equal as regionEqual { withRegion* `Region', withRegion* `Region' } -> `Bool' cToBool#}
+{#fun region_translate as regionTranslate { withRegion* `Region', fromIntegral `Int', fromIntegral `Int' } -> `()'#}
+{#fun region_intersect as regionIntersect { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_intersect_rectangle as regionIntersectRectangle { withRegion* `Region', with* `RectangleInt' } -> `Status' cToEnum#}
+{#fun region_subtract as regionSubtract { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_subtract_rectangle as regionSubtractRectangle { withRegion* `Region', with* `RectangleInt' } -> `Status' cToEnum#}
+{#fun region_union as regionUnion { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_union_rectangle as regionUnionRectangle { withRegion* `Region', with* `RectangleInt' } -> `Status' cToEnum#}
+{#fun region_xor as regionXor { withRegion* `Region', withRegion* `Region' } -> `Status' cToEnum#}
+{#fun region_xor_rectangle as regionXorRectangle { withRegion* `Region', with* `RectangleInt' } -> `Status' cToEnum#}
+
+#endif
diff --git a/GI/Cairo/Render/Internal/Surfaces/Image.chs b/GI/Cairo/Render/Internal/Surfaces/Image.chs
new file mode 100644
index 0000000..f875ac3
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Surfaces/Image.chs
@@ -0,0 +1,44 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Surfaces.Image
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Rendering to memory buffers.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Surfaces.Image where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun image_surface_create_for_data as imageSurfaceCreateForData
+ { id `Ptr CUChar'
+ , cFromEnum `Format'
+ , `Int'
+ , `Int'
+ , `Int'
+ } -> `Surface' mkSurface*#}
+
+{#fun image_surface_create as imageSurfaceCreate { cFromEnum `Format', `Int', `Int' } -> `Surface' mkSurface*#}
+{#fun image_surface_get_width as imageSurfaceGetWidth { withSurface* `Surface' } -> `Int'#}
+{#fun image_surface_get_height as imageSurfaceGetHeight { withSurface* `Surface' } -> `Int'#}
+#if CAIRO_CHECK_VERSION(1,2,0)
+{#fun image_surface_get_stride as imageSurfaceGetStride { withSurface* `Surface' } -> `Int'#}
+{#fun image_surface_get_format as imageSurfaceGetFormat { withSurface* `Surface' } -> `Format' cToEnum#}
+{#fun image_surface_get_data as imageSurfaceGetData { withSurface* `Surface' } -> `(Ptr CUChar)' id#}
+#if CAIRO_CHECK_VERSION(1,6,0)
+{#fun pure format_stride_for_width as formatStrideForWidth { cFromEnum `Format', `Int' } -> `Int'#}
+#endif
+#endif
diff --git a/GI/Cairo/Render/Internal/Surfaces/PDF.chs b/GI/Cairo/Render/Internal/Surfaces/PDF.chs
new file mode 100644
index 0000000..4f23461
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Surfaces/PDF.chs
@@ -0,0 +1,34 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Surfaces.PDF
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Rendering PDF documents.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Surfaces.PDF where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+#ifdef CAIRO_HAS_PDF_SURFACE
+
+{#fun pdf_surface_create as pdfSurfaceCreate { withCAString* `FilePath', `Double', `Double' } -> `Surface' mkSurface*#}
+
+#if CAIRO_CHECK_VERSION(1,2,0)
+{#fun pdf_surface_set_size as pdfSurfaceSetSize { withSurface* `Surface', `Double', `Double' } -> `()'#}
+#endif
+
+#endif
diff --git a/GI/Cairo/Render/Internal/Surfaces/PNG.chs b/GI/Cairo/Render/Internal/Surfaces/PNG.chs
new file mode 100644
index 0000000..5d23682
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Surfaces/PNG.chs
@@ -0,0 +1,36 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Surfaces.PNG
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Reading and writing PNG images.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Surfaces.PNG where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+
+imageSurfaceCreateFromPNG :: FilePath -> IO Surface
+imageSurfaceCreateFromPNG filename =
+ withCAString filename $ \filenamePtr ->
+ {#call unsafe image_surface_create_from_png#} filenamePtr
+ >>= mkSurface
+
+{#fun surface_write_to_png as surfaceWriteToPNG { withSurface* `Surface', withCAString* `FilePath' } -> `Status' cToEnum#}
+
+#endif
diff --git a/GI/Cairo/Render/Internal/Surfaces/PS.chs b/GI/Cairo/Render/Internal/Surfaces/PS.chs
new file mode 100644
index 0000000..4abf224
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Surfaces/PS.chs
@@ -0,0 +1,34 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Surfaces.PS
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Rendering PS documents.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Surfaces.PS where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+#ifdef CAIRO_HAS_PS_SURFACE
+
+{#fun ps_surface_create as psSurfaceCreate { withCAString* `FilePath', `Double', `Double' } -> `Surface' mkSurface*#}
+
+#if CAIRO_CHECK_VERSION(1,2,0)
+{#fun cairo_ps_surface_set_size as psSurfaceSetSize { withSurface* `Surface', `Double', `Double' } -> `()'#}
+#endif
+
+#endif
diff --git a/GI/Cairo/Render/Internal/Surfaces/SVG.chs b/GI/Cairo/Render/Internal/Surfaces/SVG.chs
new file mode 100644
index 0000000..dacc63d
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Surfaces/SVG.chs
@@ -0,0 +1,30 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Surfaces.SVG
+-- Copyright : (c) Duncan Coutts 2007
+-- License : BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Rendering SVG images.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Surfaces.SVG where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+
+{#context lib="cairo" prefix="cairo"#}
+
+#ifdef CAIRO_HAS_SVG_SURFACE
+
+{#fun svg_surface_create as svgSurfaceCreate { withCAString* `FilePath', `Double', `Double' } -> `Surface' mkSurface*#}
+
+#endif
diff --git a/GI/Cairo/Render/Internal/Surfaces/Surface.chs b/GI/Cairo/Render/Internal/Surfaces/Surface.chs
new file mode 100644
index 0000000..accf983
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Surfaces/Surface.chs
@@ -0,0 +1,38 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Surfaces.Surface
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see doc/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Base class for surfaces.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Surfaces.Surface where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+import qualified Foreign.C.Types as C2HSImp
+import qualified Foreign.Ptr as C2HSImp
+import qualified Foreign.Storable as C2HSImp
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun surface_create_similar as surfaceCreateSimilar { withSurface* `Surface', cFromEnum `Content', `Int', `Int' } -> `Surface' mkSurface*#}
+{#fun surface_destroy as surfaceDestroy { withSurface* `Surface' } -> `()'#}
+{#fun surface_finish as surfaceFinish { withSurface* `Surface' } -> `()'#}
+{#fun surface_flush as surfaceFlush { withSurface* `Surface' } -> `()'#}
+{#fun surface_get_font_options as surfaceGetFontOptions { withSurface* `Surface', withFontOptions* `FontOptions'} -> `()'#}
+{#fun surface_get_content as surfaceGetContent { withSurface* `Surface' } -> `Content' cToEnum#}
+{#fun surface_mark_dirty as surfaceMarkDirty { withSurface* `Surface' } -> `()'#}
+{#fun surface_mark_dirty_rectangle as surfaceMarkDirtyRectangle { withSurface* `Surface', `Int', `Int', `Int', `Int' } -> `()'#}
+{#fun surface_reference as surfaceReference { withSurface* `Surface' } -> `()'#}
+{#fun surface_set_device_offset as surfaceSetDeviceOffset { withSurface* `Surface', `Double', `Double' } -> `()'#}
+{#fun surface_status as surfaceStatus { withSurface* `Surface' } -> `Status' cToEnum#}
diff --git a/GI/Cairo/Render/Internal/Utilities.chs b/GI/Cairo/Render/Internal/Utilities.chs
new file mode 100644
index 0000000..c64edc6
--- /dev/null
+++ b/GI/Cairo/Render/Internal/Utilities.chs
@@ -0,0 +1,46 @@
+{-# LANGUAGE FlexibleInstances #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Internal.Utilities
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- http://cairographics.org/manual/Support.html
+-----------------------------------------------------------------------------
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Internal.Utilities where
+
+{#import GI.Cairo.Render.Types#}
+
+import Foreign
+import Foreign.C
+-- TODO work around cpphs https://ghc.haskell.org/trac/ghc/ticket/13553
+#if __GLASGOW_HASKELL__ >= 707 || __GLASGOW_HASKELL__ == 0
+import System.IO.Unsafe (unsafePerformIO)
+#endif
+
+import Codec.Binary.UTF8.String
+import Data.Char (ord, chr)
+import Data.Text (Text)
+import Data.ByteString (useAsCString)
+import qualified Data.Text.Encoding as T (encodeUtf8)
+
+{#context lib="cairo" prefix="cairo"#}
+
+{#fun status_to_string as statusToString { cFromEnum `Status' } -> `String'#}
+{#fun pure version as version {} -> `Int'#}
+{#fun pure version_string as versionString {} -> `String'#}
+
+class CairoString s where
+ withUTFString :: s -> (CString -> IO a) -> IO a
+
+instance CairoString [Char] where
+ withUTFString = withCAString . encodeString
+
+instance CairoString Text where
+ withUTFString s = useAsCString (T.encodeUtf8 s)
diff --git a/GI/Cairo/Render/Matrix.chs b/GI/Cairo/Render/Matrix.chs
new file mode 100644
index 0000000..bef1a03
--- /dev/null
+++ b/GI/Cairo/Render/Matrix.chs
@@ -0,0 +1,140 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Matrix
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Matrix math
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+module GI.Cairo.Render.Matrix (
+ Matrix(Matrix)
+ , MatrixPtr
+ , identity
+ , translate
+ , scale
+ , rotate
+ , transformDistance
+ , transformPoint
+ , scalarMultiply
+ , adjoint
+ , invert
+ ) where
+
+import Foreign hiding (rotate)
+import Foreign.C
+
+-- | Representation of a 2-D affine transformation.
+--
+-- The Matrix type represents a 2x2 transformation matrix along with a
+-- translation vector. @Matrix a1 a2 b1 b2 c1 c2@ describes the
+-- transformation of a point with coordinates x,y that is defined by
+--
+-- > / x' \ = / a1 b1 \ / x \ + / c1 \
+-- > \ y' / \ a2 b2 / \ y / \ c2 /
+--
+-- or
+--
+-- > x' = a1 * x + b1 * y + c1
+-- > y' = a2 * x + b2 * y + c2
+
+data Matrix = Matrix { xx :: !Double, yx :: !Double,
+ xy :: !Double, yy :: !Double,
+ x0 :: !Double, y0 :: !Double }
+ deriving (Show, Eq)
+
+{#pointer *cairo_matrix_t as MatrixPtr -> Matrix#}
+
+instance Storable Matrix where
+ sizeOf _ = {#sizeof cairo_matrix_t#}
+ alignment _ = alignment (undefined :: CDouble)
+ peek p = do
+ xx <- {#get cairo_matrix_t->xx#} p
+ yx <- {#get cairo_matrix_t->yx#} p
+ xy <- {#get cairo_matrix_t->xy#} p
+ yy <- {#get cairo_matrix_t->yy#} p
+ x0 <- {#get cairo_matrix_t->x0#} p
+ y0 <- {#get cairo_matrix_t->y0#} p
+ return $ Matrix (realToFrac xx) (realToFrac yx)
+ (realToFrac xy) (realToFrac yy)
+ (realToFrac x0) (realToFrac y0)
+
+ poke p (Matrix xx yx xy yy x0 y0) = do
+ {#set cairo_matrix_t->xx#} p (realToFrac xx)
+ {#set cairo_matrix_t->yx#} p (realToFrac yx)
+ {#set cairo_matrix_t->xy#} p (realToFrac xy)
+ {#set cairo_matrix_t->yy#} p (realToFrac yy)
+ {#set cairo_matrix_t->x0#} p (realToFrac x0)
+ {#set cairo_matrix_t->y0#} p (realToFrac y0)
+ return ()
+
+instance Num Matrix where
+ (*) (Matrix xx yx xy yy x0 y0) (Matrix xx' yx' xy' yy' x0' y0') =
+ Matrix (xx * xx' + yx * xy')
+ (xx * yx' + yx * yy')
+ (xy * xx' + yy * xy')
+ (xy * yx' + yy * yy')
+ (x0 * xx' + y0 * xy' + x0')
+ (x0 * yx' + y0 * yy' + y0')
+
+ (+) = pointwise2 (+)
+ (-) = pointwise2 (-)
+
+ negate = pointwise negate
+ abs = pointwise abs
+ signum = pointwise signum
+
+ -- this definition of fromInteger means that 2*m = scale 2 m
+ -- and it means 1 = identity
+ fromInteger n = Matrix (fromInteger n) 0 0 (fromInteger n) 0 0
+
+{-# INLINE pointwise #-}
+pointwise f (Matrix xx yx xy yy x0 y0) =
+ Matrix (f xx) (f yx) (f xy) (f yy) (f x0) (f y0)
+
+{-# INLINE pointwise2 #-}
+pointwise2 f (Matrix xx yx xy yy x0 y0) (Matrix xx' yx' xy' yy' x0' y0') =
+ Matrix (f xx xx') (f yx yx') (f xy xy') (f yy yy') (f x0 x0') (f y0 y0')
+
+identity :: Matrix
+identity = Matrix 1 0 0 1 0 0
+
+translate :: Double -> Double -> Matrix -> Matrix
+translate tx ty m = m * (Matrix 1 0 0 1 tx ty)
+
+scale :: Double -> Double -> Matrix -> Matrix
+scale sx sy m = m * (Matrix sx 0 0 sy 0 0)
+
+rotate :: Double -> Matrix -> Matrix
+rotate r m = m * (Matrix c s (-s) c 0 0)
+ where s = sin r
+ c = cos r
+
+transformDistance :: Matrix -> (Double,Double) -> (Double,Double)
+transformDistance (Matrix xx yx xy yy _ _) (dx,dy) =
+ newX `seq` newY `seq` (newX,newY)
+ where newX = xx * dx + xy * dy
+ newY = yx * dx + yy * dy
+
+transformPoint :: Matrix -> (Double,Double) -> (Double,Double)
+transformPoint (Matrix xx yx xy yy x0 y0) (dx,dy) =
+ newX `seq` newY `seq` (newX,newY)
+ where newX = xx * dx + xy * dy + x0
+ newY = yx * dx + yy * dy + y0
+
+scalarMultiply :: Double -> Matrix -> Matrix
+scalarMultiply scalar = pointwise (*scalar)
+
+adjoint :: Matrix -> Matrix
+adjoint (Matrix a b c d tx ty) =
+ Matrix d (-b) (-c) a (c*ty - d*tx) (b*tx - a*ty)
+
+invert :: Matrix -> Matrix
+invert m@(Matrix xx yx xy yy _ _) = scalarMultiply (recip det) $ adjoint m
+ where det = xx*yy - yx*xy
diff --git a/GI/Cairo/Render/Types.chs b/GI/Cairo/Render/Types.chs
new file mode 100644
index 0000000..15986a4
--- /dev/null
+++ b/GI/Cairo/Render/Types.chs
@@ -0,0 +1,454 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# OPTIONS_HADDOCK hide #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : GI.Cairo.Render.Types
+-- Copyright : (c) Paolo Martini 2005
+-- License : BSD-style (see cairo/COPYRIGHT)
+--
+-- Maintainer : p.martini@neuralnoise.com
+-- Stability : experimental
+-- Portability : portable
+--
+-- Haskell bindings to the cairo types.
+-----------------------------------------------------------------------------
+
+#include "gi-cairo-render.h"
+
+-- #hide
+module GI.Cairo.Render.Types (
+ PixelData
+ , Matrix(Matrix), MatrixPtr
+ , Cairo(Cairo), CairoPtr, unCairo
+ , Surface(Surface), SurfacePtr, withSurface, mkSurface, manageSurface
+ , Pattern(Pattern), unPattern
+ , Status(..)
+ , Operator(..)
+ , Antialias(..)
+ , FillRule(..)
+ , LineCap(..)
+ , LineJoin(..)
+ , ScaledFont(..), unScaledFont
+ , FontFace(..), unFontFace
+ , Glyph, unGlyph
+ , TextExtentsPtr
+ , TextExtents(..)
+ , FontExtentsPtr
+ , FontExtents(..)
+ , FontSlant(..)
+ , FontWeight(..)
+ , SubpixelOrder(..)
+ , HintStyle(..)
+ , HintMetrics(..)
+ , FontOptions(..), FontOptionsPtr, withFontOptions, mkFontOptions
+ , Path(..), unPath
+#if CAIRO_CHECK_VERSION(1,10,0)
+ , RectangleInt(..), RectangleIntPtr
+ , RegionOverlap(..)
+ , Region(..), RegionPtr, withRegion, mkRegion
+#endif
+ , Content(..)
+ , Format(..)
+ , Extend(..)
+ , Filter(..)
+
+ , cIntConv
+ , cFloatConv
+ , cFromBool
+ , cToBool
+ , cToEnum
+ , cFromEnum
+ , peekFloatConv
+ , withFloatConv
+
+ ) where
+
+{#import GI.Cairo.Render.Matrix#}
+
+import Data.GI.Base (ManagedPtr, BoxedObject(..), GType(..))
+import Foreign hiding (rotate)
+import Foreign.C
+
+import Control.Monad (liftM)
+
+{#context lib="cairo" prefix="cairo"#}
+
+type PixelData = Ptr CUChar
+
+foreign import ccall "cairo_gobject_context_get_type"
+ c_cairo_gobject_context_get_type :: IO GType
+
+-- not visible
+newtype Cairo = Cairo (ManagedPtr Cairo)
+{#pointer *cairo_t as CairoPtr -> Cairo#}
+unCairo (Cairo x) = x
+
+instance BoxedObject Cairo where
+ boxedType _ = c_cairo_gobject_context_get_type
+
+-- | The medium to draw on.
+newtype Surface = Surface { unSurface :: ForeignPtr Surface }
+{#pointer *surface_t as SurfacePtr -> Surface #}
+withSurface = withForeignPtr . unSurface
+
+mkSurface :: Ptr Surface -> IO Surface
+mkSurface surfacePtr = do
+ surfaceForeignPtr <- newForeignPtr_ surfacePtr
+ return (Surface surfaceForeignPtr)
+
+manageSurface :: Surface -> IO ()
+manageSurface (Surface surfaceForeignPtr) = do
+ addForeignPtrFinalizer surfaceDestroy surfaceForeignPtr
+
+foreign import ccall unsafe "&cairo_surface_destroy"
+ surfaceDestroy :: FinalizerPtr Surface
+
+-- | Patterns can be simple solid colors, various kinds of gradients or
+-- bitmaps. The current pattern for a 'Render' context is used by the 'stroke',
+-- 'fill' and paint operations. These operations composite the current pattern
+-- with the target surface using the currently selected 'Operator'.
+--
+{#pointer *pattern_t as Pattern newtype#}
+unPattern (Pattern x) = x
+
+-- | Cairo status.
+--
+-- * 'Status' is used to indicate errors that can occur when using
+-- Cairo. In some cases it is returned directly by functions. When using
+-- 'GI.Cairo.Render.Render', the last error, if any, is stored
+-- in the monad and can be retrieved with 'GI.Cairo.Render.status'.
+--
+{#enum status_t as Status {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Composition operator for all drawing operations.
+--
+{#enum operator_t as Operator {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specifies the type of antialiasing to do when rendering text or shapes
+--
+-- ['AntialiasDefault'] Use the default antialiasing for the subsystem
+-- and target device.
+--
+-- ['AntialiasNone'] Use a bilevel alpha mask.
+--
+-- ['AntialiasGray'] Perform single-color antialiasing (using shades of
+-- gray for black text on a white background, for example).
+--
+-- ['AntialiasSubpixel'] Perform antialiasing by taking advantage of
+-- the order of subpixel elements on devices such as LCD panels.
+--
+{#enum antialias_t as Antialias {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specify how paths are filled.
+--
+-- * For both fill rules, whether or not a point is included in the fill is
+-- determined by taking a ray from that point to infinity and looking at
+-- intersections with the path. The ray can be in any direction, as long
+-- as it doesn't pass through the end point of a segment or have a tricky
+-- intersection such as intersecting tangent to the path. (Note that
+-- filling is not actually implemented in this way. This is just a
+-- description of the rule that is applied.)
+--
+-- ['FillRuleWinding'] If the path crosses the ray from left-to-right,
+-- counts +1. If the path crosses the ray from right to left, counts -1.
+-- (Left and right are determined from the perspective of looking along
+-- the ray from the starting point.) If the total count is non-zero, the
+-- point will be filled.
+--
+-- ['FillRuleEvenOdd'] Counts the total number of intersections,
+-- without regard to the orientation of the contour. If the total number
+-- of intersections is odd, the point will be filled.
+--
+{#enum fill_rule_t as FillRule {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specify line endings.
+--
+-- ['LineCapButt'] Start(stop) the line exactly at the start(end) point.
+--
+-- ['LineCapRound'] Use a round ending, the center of the circle is the
+-- end point.
+--
+-- ['LineCapSquare'] Use squared ending, the center of the square is the
+-- end point
+--
+{#enum line_cap_t as LineCap {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specify how lines join.
+--
+{#enum line_join_t as LineJoin {underscoreToCase} deriving(Eq,Show)#}
+
+{#pointer *scaled_font_t as ScaledFont newtype#}
+unScaledFont (ScaledFont x) = x
+
+{#pointer *font_face_t as FontFace newtype#}
+unFontFace (FontFace x) = x
+
+{#pointer *glyph_t as Glyph newtype#}
+unGlyph (Glyph x) = x
+
+{#pointer *text_extents_t as TextExtentsPtr -> TextExtents#}
+
+-- | Specify the extents of a text.
+data TextExtents = TextExtents {
+ textExtentsXbearing :: Double
+ , textExtentsYbearing :: Double
+ , textExtentsWidth :: Double
+ , textExtentsHeight :: Double
+ , textExtentsXadvance :: Double
+ , textExtentsYadvance :: Double
+ }
+
+instance Storable TextExtents where
+ sizeOf _ = {#sizeof text_extents_t#}
+ alignment _ = alignment (undefined :: CDouble)
+ peek p = do
+ x_bearing <- {#get text_extents_t->x_bearing#} p
+ y_bearing <- {#get text_extents_t->y_bearing#} p
+ width <- {#get text_extents_t->width#} p
+ height <- {#get text_extents_t->height#} p
+ x_advance <- {#get text_extents_t->x_advance#} p
+ y_advance <- {#get text_extents_t->y_advance#} p
+ return $ TextExtents (cFloatConv x_bearing) (cFloatConv y_bearing)
+ (cFloatConv width) (cFloatConv height)
+ (cFloatConv x_advance) (cFloatConv y_advance)
+ poke p (TextExtents x_bearing y_bearing width height x_advance y_advance) = do
+ {#set text_extents_t->x_bearing#} p (cFloatConv x_bearing)
+ {#set text_extents_t->y_bearing#} p (cFloatConv y_bearing)
+ {#set text_extents_t->width#} p (cFloatConv width)
+ {#set text_extents_t->height#} p (cFloatConv height)
+ {#set text_extents_t->x_advance#} p (cFloatConv x_advance)
+ {#set text_extents_t->y_advance#} p (cFloatConv y_advance)
+ return ()
+
+{#pointer *font_extents_t as FontExtentsPtr -> FontExtents#}
+
+-- | Result of querying the font extents.
+data FontExtents = FontExtents {
+ fontExtentsAscent :: Double
+ , fontExtentsDescent :: Double
+ , fontExtentsHeight :: Double
+ , fontExtentsMaxXadvance :: Double
+ , fontExtentsMaxYadvance :: Double
+ }
+
+instance Storable FontExtents where
+ sizeOf _ = {#sizeof font_extents_t#}
+ alignment _ = alignment (undefined :: CDouble)
+ peek p = do
+ ascent <- {#get font_extents_t->ascent#} p
+ descent <- {#get font_extents_t->descent#} p
+ height <- {#get font_extents_t->height#} p
+ max_x_advance <- {#get font_extents_t->max_x_advance#} p
+ max_y_advance <- {#get font_extents_t->max_y_advance#} p
+ return $ FontExtents (cFloatConv ascent) (cFloatConv descent) (cFloatConv height)
+ (cFloatConv max_x_advance) (cFloatConv max_y_advance)
+ poke p (FontExtents ascent descent height max_x_advance max_y_advance) = do
+ {#set font_extents_t->ascent#} p (cFloatConv ascent)
+ {#set font_extents_t->descent#} p (cFloatConv descent)
+ {#set font_extents_t->height#} p (cFloatConv height)
+ {#set font_extents_t->max_x_advance#} p (cFloatConv max_x_advance)
+ {#set font_extents_t->max_y_advance#} p (cFloatConv max_y_advance)
+ return ()
+
+-- | Specify font slant.
+{#enum font_slant_t as FontSlant {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specify font weight.
+{#enum font_weight_t as FontWeight {underscoreToCase} deriving(Eq,Show)#}
+
+-- | The subpixel order specifies the order of color elements within each pixel
+-- on the display device when rendering with an antialiasing mode of
+-- 'AntialiasSubpixel'.
+--
+-- ['SubpixelOrderDefault'] Use the default subpixel order for for the
+-- target device
+--
+-- ['SubpixelOrderRgb'] Subpixel elements are arranged horizontally
+-- with red at the left
+--
+-- ['SubpixelOrderBgr'] Subpixel elements are arranged horizontally
+-- with blue at the left
+--
+-- ['SubpixelOrderVrgb'] Subpixel elements are arranged vertically
+-- with red at the top
+--
+-- ['SubpixelOrderVbgr'] Subpixel elements are arranged vertically
+-- with blue at the top
+--
+{#enum subpixel_order_t as SubpixelOrder {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specifies the type of hinting to do on font outlines.
+--
+-- Hinting is the process of fitting outlines to the pixel grid in order to
+-- improve the appearance of the result. Since hinting outlines involves
+-- distorting them, it also reduces the faithfulness to the original outline
+-- shapes. Not all of the outline hinting styles are supported by all font
+-- backends.
+--
+-- ['HintStyleDefault'] Use the default hint style for for font backend and
+-- target device
+--
+-- ['HintStyleNone'] Do not hint outlines
+--
+-- ['HintStyleSlight'] Hint outlines slightly to improve contrast while
+-- retaining good fidelity to the original shapes.
+--
+-- ['HintStyleMedium'] Hint outlines with medium strength giving a compromise
+-- between fidelity to the original shapes and contrast
+--
+-- ['HintStyleFull'] Hint outlines to maximize contrast
+--
+{#enum hint_style_t as HintStyle {underscoreToCase}#}
+
+-- | Specifies whether to hint font metrics.
+--
+-- Hinting font metrics means quantizing them so that they are integer values
+-- in device space. Doing this improves the consistency of letter and line
+-- spacing, however it also means that text will be laid out differently at
+-- different zoom factors.
+--
+-- ['HintMetricsDefault'] Hint metrics in the default manner for the font
+-- backend and target device
+--
+-- ['HintMetricsOff'] Do not hint font metrics
+--
+-- ['HintMetricsOn'] Hint font metrics
+--
+--
+{#enum hint_metrics_t as HintMetrics {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specifies how to render text.
+newtype FontOptions = FontOptions { unFontOption :: ForeignPtr FontOptions }
+{#pointer *font_options_t as FontOptionsPtr -> FontOptions #}
+
+withFontOptions fptr = withForeignPtr $ unFontOption fptr
+
+mkFontOptions :: Ptr FontOptions -> IO FontOptions
+mkFontOptions fontOptionsPtr = do
+ fontOptionsForeignPtr <- newForeignPtr fontOptionsDestroy fontOptionsPtr
+ return (FontOptions fontOptionsForeignPtr)
+
+foreign import ccall unsafe "&cairo_font_options_destroy"
+ fontOptionsDestroy :: FinalizerPtr FontOptions
+
+-- XXX: pathToList :: Path -> [PathData]
+--
+-- http://cairographics.org/manual/bindings-path.html
+--
+-- {#enum path_data_type_t as PathDataType {underscoreToCase}#}
+--
+-- type Point = (Double, Double)
+-- data PathData = PathMoveTo Point
+-- | PathLineTo Point
+-- | PathCurveTo Point Point Point
+-- | PathClose
+
+-- | A Cairo path.
+--
+-- * A path is a sequence of drawing operations that are accumulated until
+-- 'GI.Cairo.Render.stroke' is called. Using a path is particularly
+-- useful when drawing lines with special join styles and
+-- 'GI.Cairo.Render.closePath'.
+--
+{#pointer *path_t as Path newtype#}
+unPath (Path x) = x
+
+#if CAIRO_CHECK_VERSION(1,10,0)
+
+{#pointer *rectangle_int_t as RectangleIntPtr -> RectangleInt#}
+
+-- | A data structure for holding a rectangle with integer coordinates.
+data RectangleInt = RectangleInt {
+ x :: Int
+ , y :: Int
+ , width :: Int
+ , height :: Int
+ }
+
+instance Storable RectangleInt where
+ sizeOf _ = {#sizeof rectangle_int_t#}
+ alignment _ = alignment (undefined :: CInt)
+ peek p = do
+ x <- {#get rectangle_int_t->x#} p
+ y <- {#get rectangle_int_t->y#} p
+ width <- {#get rectangle_int_t->width#} p
+ height <- {#get rectangle_int_t->height#} p
+ return $ RectangleInt (fromIntegral x) (fromIntegral y) (fromIntegral width) (fromIntegral height)
+ poke p (RectangleInt {..}) = do
+ {#set rectangle_int_t->x#} p (fromIntegral x)
+ {#set rectangle_int_t->y#} p (fromIntegral y)
+ {#set rectangle_int_t->width#} p (fromIntegral width)
+ {#set rectangle_int_t->height#} p (fromIntegral height)
+ return ()
+
+-- | Used as the return value for regionContainsRectangle.
+{#enum cairo_region_overlap_t as RegionOverlap {underscoreToCase} deriving(Eq,Show)#}
+
+-- | A Cairo region. Represents a set of integer-aligned rectangles.
+--
+-- It allows set-theoretical operations like regionUnion and regionIntersect to be performed on them.
+newtype Region = Region { unRegion :: ForeignPtr Region }
+{#pointer *region_t as RegionPtr -> Region #}
+withRegion = withForeignPtr . unRegion
+
+mkRegion :: Ptr Region -> IO Region
+mkRegion regionPtr = do
+ regionForeignPtr <- newForeignPtr regionDestroy regionPtr
+ return (Region regionForeignPtr)
+
+foreign import ccall unsafe "&cairo_region_destroy"
+ regionDestroy :: FinalizerPtr Region
+
+#endif
+
+{#enum content_t as Content {underscoreToCase} deriving(Eq,Show)#}
+
+data Format = FormatARGB32
+ | FormatRGB24
+ | FormatA8
+ | FormatA1
+ deriving (Enum,Show,Eq)
+
+-- | FIXME: We should find out about this.
+{#enum extend_t as Extend {underscoreToCase} deriving(Eq,Show)#}
+
+-- | Specify how filtering is done.
+{#enum filter_t as Filter {underscoreToCase} deriving(Eq,Show)#}
+
+-- Marshalling functions
+
+{-# INLINE cIntConv #-}
+cIntConv :: (Integral a, Integral b) => a -> b
+cIntConv = fromIntegral
+
+{-# INLINE cFloatConv #-}
+cFloatConv :: (RealFloat a, RealFloat b) => a -> b
+cFloatConv = realToFrac
+
+{-# INLINE cFromBool #-}
+cFromBool :: Num a => Bool -> a
+cFromBool = fromBool
+
+{-# INLINE cToBool #-}
+cToBool :: (Eq a, Num a) => a -> Bool
+cToBool = toBool
+
+{-# INLINE cToEnum #-}
+cToEnum :: (Integral i, Enum e) => i -> e
+cToEnum = toEnum . cIntConv
+
+{-# INLINE cFromEnum #-}
+cFromEnum :: (Enum e, Integral i) => e -> i
+cFromEnum = cIntConv . fromEnum
+
+{-# INLINE peekFloatConv #-}
+peekFloatConv :: (Storable a, RealFloat a, RealFloat b) => Ptr a -> IO b
+peekFloatConv = liftM cFloatConv . peek
+
+{-# INLINE withFloatConv #-}
+withFloatConv :: (Storable b, RealFloat a, RealFloat b) => a -> (Ptr b -> IO c) -> IO c
+withFloatConv = with . cFloatConv
+
+{-# INLINE withArrayFloatConv #-}
+withArrayFloatConv :: (Storable b, RealFloat a, RealFloat b) => [a] -> (Ptr b -> IO b1) -> IO b1
+withArrayFloatConv = withArray . map (cFloatConv)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b881109
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,11 @@
+All content in this folder (including subdirectories) is under the BSD License (follows), except where explicitly noted otherwise.
+
+Copyright (c) Kilian Kilger 2018, Paolo Martini 2005, (c) Abraham Egnor 2003, 2004, (c) Aetion Technologies LLC 2004
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * 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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
diff --git a/gi-cairo-render.cabal b/gi-cairo-render.cabal
new file mode 100644
index 0000000..7a965f1
--- /dev/null
+++ b/gi-cairo-render.cabal
@@ -0,0 +1,75 @@
+Name: gi-cairo-render
+Version: 0.0.1
+License: BSD3
+License-file: LICENSE
+Copyright: (c) 2018 Kilian Kilger, (c) 2001-2010 The Gtk2Hs Team, (c) Paolo Martini 2005, (c) Abraham Egnor 2003, 2004, (c) Aetion Technologies LLC 2004
+Author: Axel Simon, Duncan Coutts
+Maintainer: Kilian Kilger (kkilger@gmail.com)
+Build-Type: Simple
+Cabal-Version: >= 1.24
+Stability: experimental
+homepage: https://github.com/cohomology/gi-cairo-render
+bug-reports: https://github.com/cohomology/gi-cairo-render/issues
+Synopsis: GI friendly Binding to the Cairo library.
+Description: Cairo is a library to render high quality vector graphics. There
+ exist various backends that allows rendering to Gtk windows, PDF,
+ PS, PNG and SVG documents, amongst others.
+Category: Graphics
+Tested-With: GHC == 8.2.2, GHC == 8.0.2
+extra-source-files: include/gi-cairo-render.h
+
+Source-Repository head
+ type: git
+ location: https://github.com/cohomology/gi-cairo-render
+ subdir: gi-cairo-render
+
+Flag cairo_pdf
+ Description: Build the PDF backend of Cairo.
+
+Flag cairo_ps
+ Description: Build the PostScript backend of Cairo.
+
+Flag cairo_svg
+ Description: Build the Scalable Vector Graphics (SVG) backend of Cairo.
+
+Library
+ build-depends: base >= 4 && < 5,
+ utf8-string >= 0.2 && < 1.1,
+ text >= 1.0.0.0 && < 1.3,
+ haskell-gi-base >= 0.21.0 && <0.22,
+ bytestring, mtl, array
+ build-tools: c2hs >= 0.28 && <0.30
+ exposed-modules: GI.Cairo.Render
+ GI.Cairo.Render.Matrix
+ GI.Cairo.Render.Types
+ -- this module is only meant to be used by other
+ -- modules implementing a Cairo interface
+ GI.Cairo.Render.Internal
+ other-modules:
+ GI.Cairo.Render.Internal.Drawing.Cairo
+ GI.Cairo.Render.Internal.Drawing.Paths
+ GI.Cairo.Render.Internal.Drawing.Patterns
+ GI.Cairo.Render.Internal.Drawing.Text
+ GI.Cairo.Render.Internal.Drawing.Transformations
+ GI.Cairo.Render.Internal.Fonts.FontOptions
+ GI.Cairo.Render.Internal.Surfaces.Image
+ GI.Cairo.Render.Internal.Surfaces.PNG
+ GI.Cairo.Render.Internal.Surfaces.Surface
+ GI.Cairo.Render.Internal.Utilities
+ GI.Cairo.Render.Internal.Surfaces.PDF
+ GI.Cairo.Render.Internal.Surfaces.PS
+ GI.Cairo.Render.Internal.Surfaces.SVG
+ GI.Cairo.Render.Internal.Region
+ default-language: Haskell2010
+ default-extensions: ForeignFunctionInterface
+ Include-dirs: include
+ pkgconfig-depends: cairo >= 1.2.0,
+ cairo-gobject >= 1.13
+ if flag(cairo_pdf)
+ pkgconfig-depends: cairo-pdf
+ if flag(cairo_ps)
+ pkgconfig-depends: cairo-ps
+ if flag(cairo_svg)
+ pkgconfig-depends: cairo-svg
+ if os(darwin) || os(freebsd)
+ cpp-options: -D__attribute__(A)= -D_Nullable= -D_Nonnull=
diff --git a/include/gi-cairo-render.h b/include/gi-cairo-render.h
new file mode 100755
index 0000000..2a0956c
--- /dev/null
+++ b/include/gi-cairo-render.h
@@ -0,0 +1,13 @@
+#include<cairo.h>
+#define CAIRO_CHECK_VERSION(major,minor,micro) \
+ (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(major,minor,micro))
+#ifdef CAIRO_HAS_PDF_SURFACE
+#include<cairo-pdf.h>
+#endif
+#ifdef CAIRO_HAS_PS_SURFACE
+#include<cairo-ps.h>
+#endif
+#ifdef CAIRO_HAS_SVG_SURFACE
+#include<cairo-svg.h>
+#endif
+