poppler-0.12.2: Graphics/UI/Gtk/Poppler/Page.chs
{-# LANGUAGE CPP, DeriveDataTypeable #-}
-- GIMP Toolkit (GTK) Binding for Haskell: binding to poppler -*-haskell-*-
--
-- Author : Andy Stewart
-- Created: 18-Jun-2010
--
-- Copyright (c) 2010 Andy Stewart
--
-- 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 3 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.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this program. If not, see
-- <http://www.gnu.org/licenses/>.
--
-- POPPLER, the C library which this Haskell library depends on, is
-- available under LGPL Version 2. The documentation included with
-- this library is based on the original POPPLER documentation.
--
-- | Maintainer : gtk2hs-devel@lists.sourceforge.net
-- Stability : alpha
-- Portability : portable (depends on GHC)
module Graphics.UI.Gtk.Poppler.Page (
-- * Types
Cairo,
PopplerRectangle (..),
PopplerColor (..),
ImageMapping,
PageTransition,
LinkMapping,
FormFieldMapping,
-- * Enums
SelectionStyle (..),
-- * Methods
pageRender,
pageRenderToPixbuf,
pageGetSize,
pageGetIndex,
pageGetThumbnail,
pageGetThumbnailSize,
pageRenderToPs,
pageFindText,
pageGetText,
pageGetDuration,
pageGetTransition,
pageGetLinkMapping,
pageGetImageMapping,
pageGetFormFieldMapping,
pageGetSelectionRegion,
pageRenderSelection,
pageRenderSelectionToPixbuf,
) where
import Control.Monad
import Data.Typeable
import System.Glib.FFI
import System.Glib.Flags
import System.Glib.GError
import System.Glib.GObject
import System.Glib.GList
import System.Glib.UTFString
import Graphics.UI.Gtk.Poppler.Enums
import Graphics.UI.Gtk.Abstract.Widget (Rectangle (..), Color (..))
{#import Graphics.UI.GtkInternals#}
{#import Graphics.Rendering.Cairo.Types#}
{#import Graphics.UI.Gtk.Poppler.Types#}
import Graphics.UI.Gtk.Poppler.Structs
import Control.Monad.Reader (ReaderT(runReaderT), ask, MonadIO, liftIO)
import Graphics.Rendering.Cairo.Internal (Render(..), bracketR)
{# context lib="poppler" prefix="poppler" #}
-- | Render the page to the given cairo context. This function is for rendering a page that will be
-- displayed. If you want to render a page that will be printed use 'pageRenderForPrinting'
-- instead
pageRender :: PageClass page => page
-> Render ()
pageRender page =
ask >>= \ x -> liftIO ({#call poppler_page_render #} (toPage page) x)
-- | First scale the document to match the specified pixels per point, then render the rectangle given by
-- the upper left corner at (@srcX@, @srcY@) and @srcWidth@ and @srcHeight@. This function is for rendering
-- a page that will be displayed. If you want to render a page that will be printed use
-- 'pageRenderToPixbufForPrinting' instead
pageRenderToPixbuf :: PageClass page => page
-> Rectangle -- ^ @rect@ rectangle to render
-> Double -- ^ @scale@ scale specified as pixels per point
-> Int -- ^ @rotation@ rotate the document by the specified degree
-> Pixbuf -- ^ @pixbuf@ pixbuf to render into
-> IO ()
pageRenderToPixbuf page (Rectangle x y width height) scale rotation pixbuf =
{#call poppler_page_render_to_pixbuf #}
(toPage page)
(fromIntegral x)
(fromIntegral y)
(fromIntegral width)
(fromIntegral height)
(realToFrac scale)
(fromIntegral rotation)
pixbuf
-- | Gets the size of page at the current scale and rotation.
pageGetSize :: PageClass page => page
-> IO (Double, Double)
pageGetSize page =
alloca $ \ widthPtr ->
alloca $ \ heightPtr -> do
{#call poppler_page_get_size #}
(toPage page)
widthPtr
heightPtr
width <- peek widthPtr
height <- peek heightPtr
return (realToFrac width, realToFrac height)
-- | Returns the index of page
pageGetIndex :: PageClass page => page
-> IO Int -- ^ returns index value of page
pageGetIndex page =
liftM fromIntegral $
{#call poppler_page_get_index #} (toPage page)
-- | Get the embedded thumbnail for the specified page. If the document doesn't have an embedded
-- thumbnail for the page, this function returns 'Nothing'.
pageGetThumbnail :: PageClass page => page
-> IO (Maybe Surface) -- ^ returns the tumbnail as a @cairoSurfaceT@ or 'Nothing' if the document doesn't have a thumbnail for this page.
pageGetThumbnail page = do
surfacePtr <- {#call poppler_page_get_thumbnail #} (toPage page)
if surfacePtr == nullPtr
then return Nothing
else liftM Just (mkSurface surfacePtr)
-- | Returns 'True' if page has a thumbnail associated with it. It also fills in width and height with the
-- width and height of the thumbnail. The values of width and height are not changed if no appropriate
-- thumbnail exists.
pageGetThumbnailSize :: PageClass page => page
-> IO (Maybe (Int, Int))
pageGetThumbnailSize page =
alloca $ \ widthPtr ->
alloca $ \ heightPtr -> do
success <- liftM toBool $
{#call poppler_page_get_thumbnail_size #}
(toPage page)
widthPtr
heightPtr
if success
then do
width <- peek widthPtr
height <- peek heightPtr
return $ Just (fromIntegral width, fromIntegral height)
else return Nothing
-- | Render the page on a postscript file
pageRenderToPs :: (PageClass page, PSFileClass psFile) => page -> psFile -> IO ()
pageRenderToPs page psFile =
{#call poppler_page_render_to_ps #} (toPage page) (toPSFile psFile)
-- | A GList of rectangles for each occurance of the text on the page. The coordinates are in PDF points.
pageFindText :: PageClass page => page
-> String -- ^ @text@ the text to search for (UTF-8 encoded)
-> IO [PopplerRectangle]
pageFindText page text =
withUTFString text $ \ textPtr -> do
glistPtr <- {#call poppler_page_find_text #} (toPage page) textPtr
list <- fromGList glistPtr
mapM peekPopplerRectangle list
-- | Retrieves the contents of the specified selection as text.
pageGetText :: PageClass page => page -> IO String -- ^ returns selection string
pageGetText page =
{#call poppler_page_get_text #} (toPage page)
>>= peekUTFString
-- | Returns the duration of page
pageGetDuration :: PageClass page => page
-> IO Double -- ^ returns duration in seconds of page or -1.
pageGetDuration page =
liftM realToFrac $
{#call poppler_page_get_duration #} (toPage page)
-- | Returns the transition effect of page
pageGetTransition :: PageClass page => page
-> IO (Maybe PageTransition) -- ^ returns a 'PageTransition' or 'Nothing'.
pageGetTransition page = do
ptr <- {#call poppler_page_get_transition #} (toPage page)
if ptr == nullPtr
then return Nothing
else liftM Just $ makeNewPageTransition (castPtr ptr)
{#pointer *PageTransition foreign newtype #}
makeNewPageTransition :: Ptr PageTransition -> IO PageTransition
makeNewPageTransition rPtr = do
transition <- newForeignPtr rPtr page_transition_free
return (PageTransition transition)
foreign import ccall unsafe "&poppler_page_transition_free"
page_transition_free :: FinalizerPtr PageTransition
-- | Returns a list of 'LinkMapping' items that map from a location on page to a 'Action'.
pageGetLinkMapping :: PageClass page => page
-> IO [LinkMapping]
pageGetLinkMapping page = do
glistPtr <- {#call poppler_page_get_link_mapping #} (toPage page)
list <- fromGList glistPtr
mappings <- mapM makeNewLinkMapping list
{#call unsafe poppler_page_free_link_mapping #} (castPtr glistPtr)
return mappings
{#pointer *LinkMapping foreign newtype #}
makeNewLinkMapping :: Ptr LinkMapping -> IO LinkMapping
makeNewLinkMapping rPtr = do
linkMapping <- newForeignPtr rPtr poppler_link_mapping_free
return (LinkMapping linkMapping)
foreign import ccall unsafe "&poppler_link_mapping_free"
poppler_link_mapping_free :: FinalizerPtr LinkMapping
-- | Returns a list of 'ImageMapping' items that map from a location on page to a 'Action'.
pageGetImageMapping :: PageClass page => page
-> IO [ImageMapping]
pageGetImageMapping page = do
glistPtr <- {#call poppler_page_get_image_mapping #} (toPage page)
list <- fromGList glistPtr
mappings <- mapM makeNewImageMapping list
{#call unsafe poppler_page_free_image_mapping #} (castPtr glistPtr)
return mappings
{#pointer *ImageMapping foreign newtype #}
makeNewImageMapping :: Ptr ImageMapping -> IO ImageMapping
makeNewImageMapping rPtr = do
imageMapping <- newForeignPtr rPtr poppler_image_mapping_free
return (ImageMapping imageMapping)
foreign import ccall unsafe "&poppler_image_mapping_free"
poppler_image_mapping_free :: FinalizerPtr ImageMapping
-- | Returns a list of 'FormFieldMapping' items that map from a location on page to a 'Action'.
pageGetFormFieldMapping :: PageClass page => page
-> IO [FormFieldMapping]
pageGetFormFieldMapping page = do
glistPtr <- {#call poppler_page_get_form_field_mapping #} (toPage page)
list <- fromGList glistPtr
mappings <- mapM makeNewFormFieldMapping list
{#call unsafe poppler_page_free_image_mapping #} (castPtr glistPtr)
return mappings
{#pointer *FormFieldMapping foreign newtype #}
makeNewFormFieldMapping :: Ptr FormFieldMapping -> IO FormFieldMapping
makeNewFormFieldMapping rPtr = do
formFieldMapping <- newForeignPtr rPtr poppler_form_field_mapping_free
return (FormFieldMapping formFieldMapping)
foreign import ccall unsafe "&poppler_form_field_mapping_free"
poppler_form_field_mapping_free :: FinalizerPtr FormFieldMapping
-- | Returns a region containing the area that would be rendered by 'pageRenderSelection' or
-- 'pageRenderSelectionToPixbuf' as a GList of PopplerRectangle.
pageGetSelectionRegion :: PageClass page => page
-> Double -- ^ @scale@ scale specified as pixels per point
-> SelectionStyle -- ^ @style@ a 'SelectionStyle'
-> PopplerRectangle -- ^ @selection@ start and end point of selection as a rectangle
-> IO [PopplerRectangle]
pageGetSelectionRegion page scale style selection =
with selection $ \ selectionPtr -> do
glistPtr <- {#call poppler_page_get_selection_region #}
(toPage page)
(realToFrac scale)
((fromIntegral . fromEnum) style)
(castPtr selectionPtr)
list <- fromGList glistPtr
rectangles <- mapM peekPopplerRectangle list
{#call unsafe poppler_page_selection_region_free #} (castPtr glistPtr)
return rectangles
-- | Render the selection specified by selection for page to the given cairo context. The selection will
-- be rendered, using @glyphColor@ for the glyphs and @backgroundColor@ for the selection background.
--
-- If non-'Nothing', @oldSelection@ specifies the selection that is already rendered to cairo, in which case
-- this function will (some day) only render the changed part of the selection.
pageRenderSelection :: PageClass page => page
-> PopplerRectangle -- ^ @selection@ start and end point of selection as a rectangle
-> PopplerRectangle -- ^ @oldSelection@ previous selection
-> SelectionStyle -- ^ @style@ a 'SelectionStyle'
-> PopplerColor -- ^ @glyphColor@ color to use for drawing glyphs
-> PopplerColor -- ^ @backgroundColor@ color to use for the selection background
-> Render ()
pageRenderSelection page selection oldSelection style glyphColor backgroundColor = do
cairo <- ask
liftIO $
with selection $ \ selectionPtr ->
with oldSelection $ \ oldSelectionPtr ->
with glyphColor $ \ glyphColorPtr ->
with backgroundColor $ \ backgroundColorPtr ->
{#call poppler_page_render_selection #}
(toPage page)
cairo
(castPtr selectionPtr)
(castPtr oldSelectionPtr)
((fromIntegral . fromEnum) style)
(castPtr glyphColorPtr)
(castPtr backgroundColorPtr)
-- | Render the selection specified by selection for page into pixbuf. The selection will be rendered at
-- scale, using @glyphColor@ for the glyphs and @backgroundColor@ for the selection background.
--
-- If non-'Nothing', @oldSelection@ specifies the selection that is already rendered in pixbuf, in which case
-- this function will (some day) only render the changed part of the selection.
pageRenderSelectionToPixbuf :: PageClass page => page
-> Double -- ^ @scale@ scale specified as pixels per point
-> Int -- ^ @rotation@ rotate the document by the specified degree
-> Pixbuf -- ^ @pixbuf@ pixbuf to render to
-> PopplerRectangle -- ^ @selection@ start and end point of selection as a rectangle
-> PopplerRectangle -- ^ @oldSelection@ previous selection
-> SelectionStyle -- ^ @style@ a 'SelectionStyle'
-> Color -- ^ @glyphColor@ color to use for drawing glyphs
-> Color -- ^ @backgroundColor@ color to use for the selection background
-> IO ()
pageRenderSelectionToPixbuf page scale rotation pixbuf selection oldSelection style glyphColor backgroundColor =
with selection $ \ selectionPtr ->
with oldSelection $ \ oldSelectionPtr ->
with glyphColor $ \ glyphColorPtr ->
with backgroundColor $ \ backgroundColorPtr ->
{#call poppler_page_render_selection_to_pixbuf #}
(toPage page)
(realToFrac scale)
(fromIntegral rotation)
pixbuf
(castPtr selectionPtr)
(castPtr oldSelectionPtr)
((fromIntegral . fromEnum) style)
(castPtr glyphColorPtr)
(castPtr backgroundColorPtr)