gtk3-0.13.8: Graphics/UI/Gtk/Gdk/Pixbuf.chs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE EmptyDataDecls #-}
-- -*-haskell-*-
-- GIMP Toolkit (GTK) Pixbuf
--
-- Author : Vincenzo Ciancia, Axel Simon
--
-- Created: 26 March 2002
--
-- Copyright (C) 2002-2005 Axel Simon, Vincenzo Ciancia
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- TODO
--
-- if anybody writes an image manipulation program, do the checker board
-- functions: gdk_pixbuf_composite_color_simple and
-- gdk_pixbuf_composite_color. Moreover, do: pixbuf_saturate_and_pixelate
--
--
-- pixbuf loader
--
-- module interface
--
-- rendering function for Bitmaps and Pixmaps when the latter are added
--
-- |
-- Maintainer : gtk2hs-users@lists.sourceforge.net
-- Stability : provisional
-- Portability : portable (depends on GHC)
--
-- 'Pixbuf's are bitmap images in memory.
--
-- * A Pixbuf is used to represent images. It contains information
-- about the image's pixel data, its color space, bits per sample, width
-- and height, and the rowstride or number of bytes between rows.
--
-- * This module contains functions to scale and crop
-- 'Pixbuf's and to scale and crop a 'Pixbuf' and
-- compose the result with an existing image.
--
-- * 'Pixbuf's can be displayed on screen by either creating an 'Image' that
-- from the 'Pixbuf' or by rendering (part of) the 'Pixbuf' into a
-- vanilla widget like 'DrawWindow' using
-- 'Graphics.UI.Gtk.Gdk.Drawable.drawPixbuf'.
--
module Graphics.UI.Gtk.Gdk.Pixbuf (
-- * Class Hierarchy
-- |
-- @
-- | 'GObject'
-- | +----Pixbuf
-- @
-- * Types
Pixbuf,
PixbufClass,
castToPixbuf, gTypePixbuf,
toPixbuf,
PixbufError(..),
Colorspace(..),
-- * Constructors
pixbufNew,
pixbufNewFromData,
pixbufNewFromFile,
#if GTK_CHECK_VERSION(2,4,0)
pixbufNewFromFileAtSize,
#endif
#if GTK_CHECK_VERSION(2,6,0)
pixbufNewFromFileAtScale,
#endif
#if GTK_CHECK_VERSION(3,0,0)
pixbufNewFromSurface,
#endif
pixbufNewFromInline,
InlineImage,
pixbufNewSubpixbuf,
pixbufNewFromXPMData,
-- * Methods
pixbufGetColorSpace,
pixbufGetNChannels,
pixbufGetHasAlpha,
pixbufGetBitsPerSample,
PixbufData,
pixbufGetPixels,
pixbufGetWidth,
pixbufGetHeight,
pixbufGetRowstride,
pixbufGetOption,
ImageFormat,
pixbufGetFormats,
pixbufSave,
pixbufCopy,
InterpType(..),
pixbufScaleSimple,
pixbufScale,
pixbufComposite,
#if GTK_CHECK_VERSION(2,6,0)
pixbufFlipHorizontally,
pixbufFlipHorazontally,
pixbufFlipVertically,
pixbufRotateSimple,
PixbufRotation(..),
#endif
pixbufAddAlpha,
pixbufCopyArea,
pixbufFill,
#if GTK_MAJOR_VERSION < 3
pixbufGetFromDrawable,
pixbufRenderThresholdAlpha,
pixbufRenderPixmapAndMaskForColormap
#endif
) where
import Control.Monad (liftM)
import System.Glib.FFI
import System.Glib.UTFString
import System.Glib.GObject
{#import Graphics.UI.Gtk.Types#}
#if GTK_MAJOR_VERSION < 3
import Graphics.UI.Gtk.General.Structs (Rectangle(..))
#endif
import System.Glib.GError (GError(..), GErrorClass(..), GErrorDomain,
propagateGError)
import Graphics.UI.Gtk.Gdk.PixbufData ( PixbufData, mkPixbufData )
#if GTK_MAJOR_VERSION < 3
import Graphics.UI.Gtk.Gdk.Pixmap (Bitmap)
#else
import Graphics.Rendering.Cairo
import Graphics.Rendering.Cairo.Types
#endif
{# context prefix="gdk" #}
-- | Error codes for loading image files.
--
{#enum PixbufError {underscoreToCase} #}
-- | Enumerate all supported color spaces.
--
-- * Only RGB is supported right now.
--
{#enum Colorspace {underscoreToCase} #}
-- | Queries the color space of a pixbuf.
--
pixbufGetColorSpace :: Pixbuf -> IO Colorspace
pixbufGetColorSpace pb = liftM (toEnum . fromIntegral) $
{#call unsafe pixbuf_get_colorspace#} pb
-- | Queries the number of colors for each pixel.
--
-- * This function returns 3 for an RGB image without alpha (transparency)
-- channel, 4 for an RGB image with alpha channel.
--
pixbufGetNChannels :: Pixbuf -> IO Int
pixbufGetNChannels pb = liftM fromIntegral $
{#call unsafe pixbuf_get_n_channels#} pb
-- | Query if the image has an alpha channel.
--
-- * The alpha channel determines the opaqueness of the pixel.
--
pixbufGetHasAlpha :: Pixbuf -> IO Bool
pixbufGetHasAlpha pb =
liftM toBool $ {#call unsafe pixbuf_get_has_alpha#} pb
-- | Queries the number of bits for each color.
--
-- * Each pixel is has a number of cannels for each pixel, each channel
-- has this many bits.
--
pixbufGetBitsPerSample :: Pixbuf -> IO Int
pixbufGetBitsPerSample pb = liftM fromIntegral $
{#call unsafe pixbuf_get_bits_per_sample#} pb
-- | Retrieve the internal array of raw image data.
--
-- * Image data in a pixbuf 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 "rowstride" value of a pixbuf, as returned by
-- 'pixbufGetRowstride', 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 number of channels is usually 3 for plain RGB data or 4 for
-- RGB data with an alpha channel. To read or write a specific pixel
-- use the formula: @p = y * rowstride + x * nChannels@ for the pixel.
-- If the array contains bytes (or 'Word8's), @p+0@ is the red value,
-- @p+1@ green, @p+2@ blue and @p+3@ the alpha (transparency) channel
-- if present. If the alpha channel is present, the array can accessed
-- as an array over 'Word32' to modify a whole pixel at a time. See also
-- 'pixbufGetBitsPerSample' and 'pixbufGetNChannels'.
--
-- * 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:
-- @pbData <- (pixbufGetPixels pb :: IO (PixbufData Int Word8))@
--
-- * 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.
--
pixbufGetPixels :: Storable e => Pixbuf -> IO (PixbufData Int e)
pixbufGetPixels pb = do
pixPtr_ <- {#call unsafe pixbuf_get_pixels#} pb
chan <- pixbufGetNChannels pb
bits <- pixbufGetBitsPerSample pb
w <- pixbufGetWidth pb
h <- pixbufGetHeight pb
r <- pixbufGetRowstride pb
let pixPtr = castPtr pixPtr_
let bytes = (h-1)*r+w*((chan*bits+7) `div` 8)
return (mkPixbufData pb pixPtr bytes)
-- | Queries the width of this image.
--
pixbufGetWidth :: Pixbuf -> IO Int
pixbufGetWidth pb = liftM fromIntegral $
{#call unsafe pixbuf_get_width#} pb
-- | Queries the height of this image.
--
pixbufGetHeight :: Pixbuf -> IO Int
pixbufGetHeight pb = liftM fromIntegral $
{#call unsafe pixbuf_get_height#} pb
-- | Queries the rowstride of this image.
--
-- * Queries the rowstride of a pixbuf, which is the number of bytes between
-- rows. Use this value to caculate the offset to a certain row.
--
pixbufGetRowstride :: Pixbuf -> IO Int
pixbufGetRowstride pb = liftM fromIntegral $
{#call unsafe pixbuf_get_rowstride#} pb
-- | Returns an attribut of an image.
--
-- * Looks up if some information was stored under the @key@ when
-- this image was saved.
--
pixbufGetOption :: (GlibString string) => Pixbuf -> string -> IO (Maybe string)
pixbufGetOption pb key = withUTFString key $ \strPtr -> do
resPtr <- {#call unsafe pixbuf_get_option#} pb strPtr
if (resPtr==nullPtr) then return Nothing else
liftM Just $ peekUTFString resPtr
-- helper functions
pixbufErrorDomain :: GErrorDomain
pixbufErrorDomain = {#call pure unsafe pixbuf_error_quark#}
instance GErrorClass PixbufError where
gerrorDomain _ = pixbufErrorDomain
-- | Load an image synchonously.
--
-- * Use this function to load only small images as this call will block.
--
-- * If an error occurs, the function will throw an exception that can
-- be caught using e.g. 'System.Glib.GError.catchGErrorJust' and one of the
-- error codes in 'PixbufError'.
--
pixbufNewFromFile :: GlibFilePath fp => fp -> IO Pixbuf
pixbufNewFromFile fname =
wrapNewGObject mkPixbuf $
propagateGError $ \errPtrPtr ->
withUTFFilePath fname $ \strPtr ->
#if defined (WIN32) && GTK_CHECK_VERSION(2,6,0)
{#call unsafe pixbuf_new_from_file_utf8#}
#else
{#call unsafe pixbuf_new_from_file#}
#endif
strPtr errPtrPtr
#if GTK_CHECK_VERSION(2,4,0)
-- | Creates a new pixbuf by loading an image from a file. The file format is
-- detected automatically. The image will be scaled to fit in the requested
-- size, preserving the image's aspect ratio.
--
-- * If an error occurs, the function will throw an exception that can
-- be caught using e.g. 'System.Glib.GError.catchGErrorJust' and one of the
-- error codes in 'PixbufError'.
--
-- * Available since Gtk+ version 2.4
--
pixbufNewFromFileAtSize :: GlibString string => string -> Int -> Int -> IO Pixbuf
pixbufNewFromFileAtSize filename width height =
wrapNewGObject mkPixbuf $
propagateGError $ \errPtrPtr ->
withUTFString filename $ \filenamePtr ->
#if defined (WIN32) && GTK_CHECK_VERSION(2,6,0)
{# call gdk_pixbuf_new_from_file_at_size_utf8 #}
#else
{# call gdk_pixbuf_new_from_file_at_size #}
#endif
filenamePtr
(fromIntegral width)
(fromIntegral height)
errPtrPtr
#endif
#if GTK_CHECK_VERSION(2,6,0)
-- | Creates a new pixbuf by loading an image from a file. The file format is
-- detected automatically. The image will be scaled to fit in the requested
-- size, optionally preserving the image's aspect ratio.
--
-- When preserving the aspect ratio, a width of -1 will cause the image to be
-- scaled to the exact given height, and a height of -1 will cause the image to
-- be scaled to the exact given width. When not preserving aspect ratio, a width
-- or height of -1 means to not scale the image at all in that dimension.
-- Negative values for width and height are allowed since Gtk+ 2.8.
--
-- * If an error occurs, the function will throw an exception that can
-- be caught using e.g. 'System.Glib.GError.catchGErrorJust' and one of the
-- error codes in 'PixbufError'.
--
-- * Available since Gtk+ version 2.6
--
pixbufNewFromFileAtScale :: GlibString string
=> string -- ^ the name of the file
-> Int -- ^ target width
-> Int -- ^ target height
-> Bool -- ^ whether to preserve the aspect ratio
-> IO Pixbuf
pixbufNewFromFileAtScale filename width height preserveAspectRatio =
wrapNewGObject mkPixbuf $
propagateGError $ \errPtrPtr ->
withUTFString filename $ \filenamePtr ->
#if defined (WIN32) && GTK_CHECK_VERSION(2,6,0)
{# call gdk_pixbuf_new_from_file_at_scale_utf8 #}
#else
{# call gdk_pixbuf_new_from_file_at_scale #}
#endif
filenamePtr
(fromIntegral width)
(fromIntegral height)
(fromBool preserveAspectRatio)
errPtrPtr
#endif
#if GTK_CHECK_VERSION(3,0,0)
-- | Creates a new pixbuf from a cairo Surface.
--
-- Transfers image data from a cairo Surface and converts it to an RGB(A) representation inside a Pixbuf. This allows you to efficiently read individual pixels from cairo surfaces. For GdkWindows, use gdk_pixbuf_get_from_window() instead.
--
-- This function will create an RGB pixbuf with 8 bits per channel. The pixbuf will contain an alpha channel if the surface contains one.
pixbufNewFromSurface :: Surface -> Int -> Int -> Int -> Int -> IO Pixbuf
pixbufNewFromSurface surface srcX srcY width height =
withSurface surface $ \ss -> wrapNewGObject mkPixbuf $
{# call gdk_pixbuf_get_from_surface #}
(castPtr ss)
(fromIntegral srcX)
(fromIntegral srcY)
(fromIntegral width)
(fromIntegral height)
#endif
-- | A string representing an image file format.
--
type ImageFormat = DefaultGlibString
-- constant pixbufGetFormats A list of valid image file formats.
--
pixbufGetFormats :: [ImageFormat]
pixbufGetFormats = ["png","bmp","wbmp", "gif","ico","ani","jpeg","pnm",
"ras","tiff","xpm","xbm","tga"]
-- | Save an image to disk.
--
-- * The function takes a list of key - value pairs to specify
-- either how an image is saved or to actually save this additional
-- data with the image. JPEG images can be saved with a \"quality\"
-- parameter; its value should be in the range [0,100]. Text chunks
-- can be attached to PNG images by specifying parameters of the form
-- \"tEXt::key\", where key is an ASCII string of length 1-79.
-- The values are Unicode strings.
--
-- * If an error occurs, the function will throw an exception that can
-- be caught using e.g. 'System.Glib.GError.catchGErrorJust' and one of the
-- error codes in 'PixbufError'.
--
pixbufSave :: (GlibString string, GlibFilePath fp) => Pixbuf -> fp -> ImageFormat -> [(string, string)] ->
IO ()
pixbufSave pb fname iType options =
let (keys, values) = unzip options in
propagateGError $ \errPtrPtr ->
withUTFFilePath fname $ \fnPtr ->
withUTFString iType $ \tyPtr ->
withUTFStringArray0 keys $ \keysPtr ->
withUTFStringArray values $ \valuesPtr -> do
#if defined (WIN32) && GTK_CHECK_VERSION(2,6,5)
{# call unsafe pixbuf_savev_utf8 #}
#else
{# call unsafe pixbuf_savev #}
#endif
pb fnPtr tyPtr keysPtr valuesPtr errPtrPtr
return ()
-- | Create a new image in memory.
--
-- * Creates a new pixbuf structure and allocates a buffer for
-- it. Note that the buffer is not cleared initially.
--
-- * The boolean flag is true if the pixbuf should have an alpha
-- (transparency) channel. The next integer denotes the bits per
-- color sample, e.g. 8 bits per color for 2^24 colors. The last
-- two integers denote the width and height, respectively.
--
pixbufNew :: Colorspace -> Bool -> Int -> Int -> Int -> IO Pixbuf
pixbufNew colorspace hasAlpha bitsPerSample width height =
wrapNewGObject mkPixbuf $
{#call pixbuf_new#} ((fromIntegral . fromEnum) colorspace)
(fromBool hasAlpha) (fromIntegral bitsPerSample) (fromIntegral width)
(fromIntegral height)
pixbufNewFromData :: Ptr CUChar -> Colorspace -> Bool -> Int -> Int -> Int -> Int -> IO Pixbuf
pixbufNewFromData imData cSpace hasAlpha bitsPerSample width height rowStride
= wrapNewGObject mkPixbuf $
{#call pixbuf_new_from_data #}
imData
(fromIntegral . fromEnum $ cSpace)
(fromBool hasAlpha)
(fromIntegral bitsPerSample)
(fromIntegral width)
(fromIntegral height)
(fromIntegral rowStride)
nullFunPtr nullPtr
-- | Create a new image from a string.
--
-- * Creates a new pixbuf from a string description.
--
pixbufNewFromXPMData :: GlibString string => [string] -> IO Pixbuf
pixbufNewFromXPMData s =
withUTFStringArray0 s $ \strsPtr ->
wrapNewGObject mkPixbuf $ {#call pixbuf_new_from_xpm_data#} strsPtr
-- | A dymmy type for inline picture data.
--
-- * This dummy type is used to declare pointers to image data
-- that is embedded in the executable. See
-- 'pixbufNewFromInline' for an example.
--
data InlineImage
-- | Create a new image from a static pointer.
--
-- * Like 'pixbufNewFromXPMData', this function allows to
-- include images in the final binary program. The method used by this
-- function uses a binary representation and therefore needs less space
-- in the final executable. Save the image you want to include as
-- @png@ and run:
--
-- > @echo #include "my_image.h" > my_image.c
-- > gdk-pixbuf-csource --raw --extern --name=my_image myimage.png >> my_image.c
--
-- on it. Write a header file @my_image.h@ containing:
--
-- > #include <gdk/gdk.h>
-- > extern guint8 my_image[];
--
-- and save it in the current directory.
-- The created file can be compiled with:
--
-- > cc -c my_image.c `pkg-config --cflags gdk-2.0`
--
-- into an object file which must be linked into your Haskell program by
-- specifying @my_image.o@ and @\"-#include my_image.h\"@ on
-- the command line of GHC.
-- Within you application you delcare a pointer to this image:
--
-- > foreign label "my_image" myImage :: Ptr InlineImage
--
-- Calling 'pixbufNewFromInline' with this pointer will
-- return the image in the object file. Creating the C file with
-- the @--raw@ flag will result in a non-compressed image in the
-- object file. The advantage is that the picture will not be
-- copied when this function is called.
--
--
pixbufNewFromInline :: Ptr InlineImage -> IO Pixbuf
pixbufNewFromInline iPtr = alloca $ \errPtrPtr -> do
pbPtr <- {#call unsafe pixbuf_new_from_inline#} (-1) (castPtr iPtr)
(fromBool False) (castPtr errPtrPtr)
if pbPtr/=nullPtr then wrapNewGObject mkPixbuf (return pbPtr)
else do
errPtr <- peek errPtrPtr
(GError dom code msg) <- peek errPtr
error $ glibToString msg
-- | Create a restricted view of an image.
--
-- * This function returns a 'Pixbuf' object which shares
-- the image of the original one but only shows a part of it.
-- Modifying either buffer will affect the other.
--
-- * This function throw an exception if the requested bounds are invalid.
--
pixbufNewSubpixbuf :: Pixbuf -> Int -> Int -> Int -> Int -> IO Pixbuf
pixbufNewSubpixbuf pb srcX srcY height width =
wrapNewGObject mkPixbuf $ do
pbPtr <- {#call unsafe pixbuf_new_subpixbuf#} pb
(fromIntegral srcX) (fromIntegral srcY)
(fromIntegral height) (fromIntegral width)
if pbPtr==nullPtr then error "pixbufNewSubpixbuf: invalid bounds"
else return pbPtr
-- | Create a deep copy of an image.
--
pixbufCopy :: Pixbuf -> IO Pixbuf
pixbufCopy pb = wrapNewGObject mkPixbuf $ {#call unsafe pixbuf_copy#} pb
-- | How an image is scaled.
--
-- [@InterpNearest@] Nearest neighbor sampling; this is the
-- fastest and lowest quality mode. Quality is normally unacceptable when
-- scaling down, but may be OK when scaling up.
--
-- [@InterpTiles@] This is an accurate simulation of the
-- PostScript image operator without any interpolation enabled. Each
-- pixel is rendered as a tiny parallelogram of solid color, the edges of
-- which are implemented with antialiasing. It resembles nearest neighbor
-- for enlargement, and bilinear for reduction.
--
-- [@InterpBilinear@] Best quality\/speed balance; use this
-- mode by default. Bilinear interpolation. For enlargement, it is
-- equivalent to point-sampling the ideal bilinear-interpolated
-- image. For reduction, it is equivalent to laying down small tiles and
-- integrating over the coverage area.
--
-- [@InterpHyper@] This is the slowest and highest quality
-- reconstruction function. It is derived from the hyperbolic filters in
-- Wolberg's \"Digital Image Warping\", and is formally defined as the
-- hyperbolic-filter sampling the ideal hyperbolic-filter interpolated
-- image (the filter is designed to be idempotent for 1:1 pixel mapping).
--
{#enum InterpType {underscoreToCase} #}
-- | Scale an image.
--
-- * Creates a new 'Pixbuf' containing a copy of
-- @src@ scaled to the given measures. Leaves @src@
-- unaffected.
--
-- * @interp@ affects the quality and speed of the scaling function.
-- 'InterpNearest' is the fastest option but yields very poor quality
-- when scaling down. 'InterpBilinear' is a good trade-off between
-- speed and quality and should thus be used as a default.
--
pixbufScaleSimple ::
Pixbuf -- ^ @src@ - the source image
-> Int -- ^ @width@ - the target width
-> Int -- ^ @height@ the target height
-> InterpType -- ^ interpolation type
-> IO Pixbuf
pixbufScaleSimple pb width height interp =
wrapNewGObject mkPixbuf $ liftM castPtr $
{#call pixbuf_scale_simple#} (toPixbuf pb)
(fromIntegral width) (fromIntegral height)
(fromIntegral $ fromEnum interp)
-- | Copy a scaled image part to another image.
--
-- * This function is the generic version of 'pixbufScaleSimple'. It scales
-- @src@ by @scaleX@ and @scaleY@ and translate the image by @offsetX@ and
-- @offsetY@. Whatever is in the intersection with the rectangle @destX@,
-- @destY@, @destWidth@, @destHeight@ will be rendered into @dest@.
--
-- * The rectangle in the destination is simply overwritten. Use
-- 'pixbufComposite' if you need to blend the source image onto the
-- destination.
--
pixbufScale ::
Pixbuf -- ^ @src@ - the source pixbuf
-> Pixbuf -- ^ @dest@ - the pixbuf into which to render the results
-> Int -- ^ @destX@ - the left coordinate for region to render
-> Int -- ^ @destY@ - the top coordinate for region to render
-> Int -- ^ @destWidth@ - the width of the region to render
-> Int -- ^ @destHeight@ - the height of the region to render
-> Double -- ^ @offsetX@ - the offset in the X direction (currently
-- rounded to an integer)
-> Double -- ^ @offsetY@ - the offset in the Y direction
-- (currently rounded to an integer)
-> Double -- ^ @scaleX@ - the scale factor in the X direction
-> Double -- ^ @scaleY@ - the scale factor in the Y direction
-> InterpType -- ^ the interpolation type for the transformation.
-> IO ()
pixbufScale src dest destX destY destWidth destHeight offsetX offsetY
scaleX scaleY interp =
{#call unsafe pixbuf_scale#} src dest
(fromIntegral destX) (fromIntegral destY)
(fromIntegral destWidth) (fromIntegral destHeight)
(realToFrac offsetX) (realToFrac offsetY)
(realToFrac scaleX) (realToFrac scaleY)
((fromIntegral . fromEnum) interp)
-- | Blend a scaled image part onto another image.
--
-- * This function is similar to 'pixbufScale' but allows the
-- original image to \"shine through\". The @alpha@ value determines
-- how opaque the source image is. Passing @0@ is
-- equivalent to not calling this function at all, passing
-- @255@ has the
-- same effect as calling 'pixbufScale'.
--
pixbufComposite ::
Pixbuf -- ^ @src@ - the source pixbuf
-> Pixbuf -- ^ @dest@ - the pixbuf into which to render the results
-> Int -- ^ @destX@ - the left coordinate for region to render
-> Int -- ^ @destY@ - the top coordinate for region to render
-> Int -- ^ @destWidth@ - the width of the region to render
-> Int -- ^ @destHeight@ - the height of the region to render
-> Double -- ^ @offsetX@ - the offset in the X direction (currently
-- rounded to an integer)
-> Double -- ^ @offsetY@ - the offset in the Y direction
-- (currently rounded to an integer)
-> Double -- ^ @scaleX@ - the scale factor in the X direction
-> Double -- ^ @scaleY@ - the scale factor in the Y direction
-> InterpType -- ^ the interpolation type for the transformation.
-> Word8 -- ^ @alpha@ - the transparency
-> IO ()
pixbufComposite src dest destX destY destWidth destHeight
offsetX offsetY scaleX scaleY interp alpha =
{#call unsafe pixbuf_composite#} src dest
(fromIntegral destX) (fromIntegral destY) (fromIntegral destWidth)
(fromIntegral destHeight) (realToFrac offsetX) (realToFrac offsetY)
(realToFrac scaleX) (realToFrac scaleY)
((fromIntegral . fromEnum) interp) (fromIntegral alpha)
#if GTK_CHECK_VERSION(2,6,0)
-- | Flips a pixbuf horizontally and returns the result in a new pixbuf.
--
pixbufFlipHorizontally :: Pixbuf -> IO Pixbuf
pixbufFlipHorizontally self =
wrapNewGObject mkPixbuf $
{# call pixbuf_flip #}
self
(fromBool True)
pixbufFlipHorazontally = pixbufFlipHorizontally
-- | Flips a pixbuf vertically and returns the result in a new pixbuf.
--
pixbufFlipVertically :: Pixbuf -> IO Pixbuf
pixbufFlipVertically self =
wrapNewGObject mkPixbuf $
{# call pixbuf_flip #}
self
(fromBool False)
-- | Rotates a pixbuf by a multiple of 90 degrees, and returns the result in a
-- new pixbuf.
--
pixbufRotateSimple :: Pixbuf -> PixbufRotation -> IO Pixbuf
pixbufRotateSimple self angle =
wrapNewGObject mkPixbuf $
{# call pixbuf_rotate_simple #}
self
((fromIntegral . fromEnum) angle)
-- | The possible rotations which can be passed to 'pixbufRotateSimple'.
--
-- To make them easier to use, their numerical values are the actual degrees.
--
{#enum PixbufRotation {underscoreToCase} #}
#endif
-- | Add an opacity layer to the 'Pixbuf'.
--
-- * This function returns a copy of the given @src@
-- 'Pixbuf', leaving @src@ unmodified.
-- The new 'Pixbuf' has an alpha (opacity)
-- channel which defaults to @255@ (fully opaque pixels)
-- unless @src@ already had an alpha channel in which case
-- the original values are kept.
-- Passing in a color triple @(r,g,b)@ makes all
-- pixels that have this color fully transparent
-- (opacity of @0@). The pixel color itself remains unchanged
-- during this substitution.
--
pixbufAddAlpha :: Pixbuf -> Maybe (Word8, Word8, Word8) -> IO Pixbuf
pixbufAddAlpha pb Nothing = wrapNewGObject mkPixbuf $
{#call unsafe pixbuf_add_alpha#} pb (fromBool False) 0 0 0
pixbufAddAlpha pb (Just (r,g,b)) = wrapNewGObject mkPixbuf $
{#call unsafe pixbuf_add_alpha#} pb (fromBool True)
(fromIntegral r) (fromIntegral g) (fromIntegral b)
-- | Copy a rectangular portion into another 'Pixbuf'.
--
-- The source 'Pixbuf' remains unchanged. Converion between
-- different formats is done automatically.
--
pixbufCopyArea ::
Pixbuf -- ^ Source pixbuf
-> Int -- ^ Source X coordinate within the source pixbuf
-> Int -- ^ Source Y coordinate within the source pixbuf
-> Int -- ^ Width of the area to copy
-> Int -- ^ Height of the area to copy
-> Pixbuf -- ^ Destination pixbuf
-> Int -- ^ X coordinate within the destination pixbuf
-> Int -- ^ Y coordinate within the destination pixbuf
-> IO ()
pixbufCopyArea src srcX srcY srcWidth srcHeight dest destX destY =
{#call unsafe pixbuf_copy_area#} src
(fromIntegral srcX) (fromIntegral srcY)
(fromIntegral srcWidth) (fromIntegral srcHeight)
dest (fromIntegral destX) (fromIntegral destY)
-- | Fills a 'Pixbuf' with a color.
--
-- * The passed-in color is a quadruple consisting of the red, green, blue
-- and alpha component of the pixel. If the 'Pixbuf' does not
-- have an alpha channel, the alpha value is ignored.
--
pixbufFill :: Pixbuf -> Word8 -> Word8 -> Word8 -> Word8 -> IO ()
pixbufFill pb red green blue alpha = {#call unsafe pixbuf_fill#} pb
((fromIntegral red) `shiftL` 24 .|.
(fromIntegral green) `shiftL` 16 .|.
(fromIntegral blue) `shiftL` 8 .|.
(fromIntegral alpha))
#if GTK_MAJOR_VERSION < 3
-- | Take a screenshot of a 'Drawable'.
--
-- * This function creates a 'Pixbuf' and fills it with the image
-- currently in the 'Drawable' (which might be invalid if the
-- window is obscured or minimized). Note that this transfers data from
-- the server to the client on X Windows.
--
-- * This function will return a 'Pixbuf' with no alpha channel
-- containing the part of the 'Drawable' specified by the
-- rectangle. The function will return @Nothing@ if the window
-- is not currently visible.
--
-- Removed in Gtk3.
pixbufGetFromDrawable :: DrawableClass d => d -> Rectangle -> IO (Maybe Pixbuf)
pixbufGetFromDrawable d (Rectangle x y width height) =
maybeNull (wrapNewGObject mkPixbuf) $
{#call unsafe pixbuf_get_from_drawable#}
(Pixbuf nullForeignPtr) (toDrawable d) (Colormap nullForeignPtr)
(fromIntegral x) (fromIntegral y) 0 0
(fromIntegral width) (fromIntegral height)
-- | Takes the opacity values in a rectangular portion of a pixbuf and
-- thresholds them to produce a bi-level alpha mask that can be used
-- as a clipping mask for a drawable.
--
-- Removed in Gtk3.
pixbufRenderThresholdAlpha ::
Pixbuf -- ^ A pixbuf.
-> Bitmap -- ^ Bitmap where the bilevel mask will be painted to.
-> Int -- ^ Source X coordinate.
-> Int -- ^ source Y coordinate.
-> Int -- ^ Destination X coordinate.
-> Int -- ^ Destination Y coordinate.
-> Int -- ^ Width of region to threshold, or -1 to use pixbuf width
-> Int -- ^ Height of region to threshold, or -1 to use pixbuf height
-> Int -- ^ Opacity values below this will be painted as zero; all other values will be painted as one.
-> IO ()
pixbufRenderThresholdAlpha src dest srcX srcY destX destY w h at =
withForeignPtr (unPixmap dest) $ \destPtr ->
{#call unsafe pixbuf_render_threshold_alpha#} src
(castPtr destPtr)
(fromIntegral srcX)
(fromIntegral srcY)
(fromIntegral destX)
(fromIntegral destY)
(fromIntegral w)
(fromIntegral h)
(fromIntegral at)
-- | Creates a pixmap and a mask bitmap which are returned and renders
-- a pixbuf and its corresponding thresholded alpha mask to them. This
-- is merely a convenience function; applications that need to render
-- pixbufs with dither offsets or to given drawables should use
-- 'Graphics.UI.Gtk.Gdk.Drawable.drawPixbuf', and
-- 'pixbufRenderThresholdAlpha'.
--
-- The pixmap that is created uses the 'Colormap' specified by
-- colormap. This colormap must match the colormap of the window where
-- the pixmap will eventually be used or an error will result.
--
-- If the pixbuf does not have an alpha channel, then the returned
-- mask will be @Nothing@.
--
-- Removed in Gtk3.
pixbufRenderPixmapAndMaskForColormap ::
Pixbuf -- ^ A pixbuf.
-> Colormap -- ^ A Colormap
-> Int -- ^ Threshold value for opacity values
-> IO (Pixmap, Maybe Bitmap) -- ^ (Created pixmap, created mask)
pixbufRenderPixmapAndMaskForColormap pixbuf colormap threshold =
alloca $ \pmRetPtr ->
alloca $ \bmRetPtr -> do
{#call unsafe pixbuf_render_pixmap_and_mask_for_colormap#} pixbuf
colormap
(castPtr pmRetPtr) -- seems to reject Pixmap**, so cast
(castPtr bmRetPtr)
(fromIntegral threshold)
pm <- wrapNewGObject mkPixmap (peek pmRetPtr :: IO (Ptr Pixmap))
bm <- maybeNull (wrapNewGObject mkPixmap) (peek bmRetPtr :: IO (Ptr Bitmap))
return (pm, bm)
#endif