packages feed

OpenVG-0.7.0: src/Graphics/Rendering/OpenVG/VG/RenderingQuality.hs

{-# OPTIONS -Wall #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenVG.VG.RenderingQuality
-- Copyright   :  (c) Stephen Tetley 2008-2014
-- License     :  BSD3
--
-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>
-- Stability   :  unstable
-- Portability :  GHC
--
-- This module corresponds to section 6 (Rendering Quality and 
-- Antialiasing) of the OpenVG 1.0.1 specs.
--
-- Acknowledgement - the matrix code is derived from Sven 
-- Panne\'s HOpenGL.
--
--------------------------------------------------------------------------------

module Graphics.Rendering.OpenVG.VG.RenderingQuality (
  
  -- * Rendering quality
  RenderingQuality(..), 
  renderingQuality,
  
  -- * Additional quality settings
  PixelLayout(..), 
  pixelLayout,
  
  -- * Matrix manipulation
  VGmatrix,
  withNewMatrix,
  withMatrix,
  newMatrix,
  getMatrixComponents,

  MatrixMode(..),
  matrixMode, 
  
  loadIdentity,
  matrix,
  multMatrix,
  translate, 
  scale, 
  shear, 
  rotate

) where

import Graphics.Rendering.OpenVG.VG.Parameters

import Graphics.Rendering.OpenVG.Raw.VG.Core101 ( VGenum, VGfloat )
import Graphics.Rendering.OpenVG.Raw.VG.RenderingQuality

import Graphics.Rendering.OpenGL.GL.StateVar (
    StateVar(), makeStateVar, SettableStateVar, makeSettableStateVar )   

import Control.Monad
import Foreign.ForeignPtr ( 
    ForeignPtr, withForeignPtr, mallocForeignPtrArray )
import Foreign.Marshal.Array ( peekArray, pokeArray )
import Foreign.Ptr ( Ptr )   


--------------------------------------------------------------------------------
-- Rendering quality
                     
-- | 'RenderingQuality' enumerates the settings available for
-- rendering quality. 
-- 
data RenderingQuality = 
     Nonantialiased'
   | Faster'
   | Better'
   deriving ( Eq, Ord, Show )

-- | Set the rendering quality.
--
-- 'renderingQuality' is a write-only state variable corresponding to
-- @VG_RENDERING_QUALITY@:
--
-- The default value for 'renderingQuality' is @Better\'@.
--
renderingQuality :: SettableStateVar RenderingQuality  
renderingQuality = makeSettableStateVar $
    seti RenderingQuality . fromIntegral . marshalRenderingQuality
    
--------------------------------------------------------------------------------
-- Additional quality settings 

-- | 'PixelLayout' enumerates the possible geometric layouts of 
-- color emissions within pixel elements.
--
data PixelLayout = 
     Unknown
   | RgbVertical
   | BgrVertical
   | RgbHorizontal
   | BgrHorizontal
   deriving ( Eq, Ord, Show )

-- | Set and query the pixel layout.
--
-- 'pixelLayout' is a read-write state variable corresponding to
-- @VG_PIXEL_LAYOUT@.
--
pixelLayout :: StateVar PixelLayout
pixelLayout = makeStateVar getPixelLayout setPixelLayout
  where
    getPixelLayout :: IO PixelLayout
    getPixelLayout = liftM (unmarshalPixelLayout . fromIntegral) 
                           (geti ScreenLayout)
        
    setPixelLayout :: PixelLayout -> IO ()  
    setPixelLayout = seti ScreenLayout . fromIntegral . marshalPixelLayout
    
--------------------------------------------------------------------------------
-- Matrix manipulation

-- NOTE - VGmatrix is simpler than the corresponding GLmatrix.
-- Firstly VGmatrix only needs to store Floats (GLmatrix has to 
-- store Floats or Doubles). Secondly VG matrices are always 
-- stored in the same order (GL matrices can be row-major or
-- column-major).


-- Represent a 3x3 matrix.
--
-- > { sx, shy, w0, shx, sy, w1, tx, ty, w2 }
--
-- > | sx  shx tx  |
-- > | shy sy  ty  |
-- > | w0  w1  w2  |
--
newtype VGmatrix = VGmatrix (ForeignPtr VGfloat)
  deriving (Eq,Ord,Show)

-- |  Create a new matrix (containing undefined elements)
-- and call the action to fill it with 3x3 elements.
--
-- (See HOpenGL\'s @withNewMatrix@).
--
withNewMatrix :: (Ptr VGfloat -> IO ()) -> IO VGmatrix
withNewMatrix f = do
    fp <- mallocForeignPtrArray 9
    withForeignPtr fp f
    return $ VGmatrix fp

-- | Call the action with the given matrix. 
-- /Note:/ The action is /not/ allowed to modify the matrix 
-- elements!
-- 
-- (See HOpenGL\'s @withMatrix@).
--
withMatrix :: VGmatrix -> (Ptr VGfloat -> IO a) -> IO a
withMatrix (VGmatrix fp) f = withForeignPtr fp f

-- | Create a new matrix (as a foreign pointer) from the supplied
-- list of components. The list should have 9 elements and be in
-- the form:
--
-- > [ sx, shy, w0, shx, sy, w1, tx, ty, w2 ]
--
newMatrix :: [VGfloat] -> IO VGmatrix
newMatrix components = withNewMatrix $ flip pokeArray (take 9 components)


-- | Extract the components from a matrix.
--
getMatrixComponents :: VGmatrix -> IO [VGfloat]
getMatrixComponents mat = withMatrix mat $ \p -> peekArray 9 p




-- | 'MatrixMode' enumerates the manipulable matrices.  
data MatrixMode =
     PathUserToSurface
   | ImageUserToSurface
   | FillPaintToUser
   | StrokePaintToUser
   deriving ( Eq, Ord, Show )   

-- | Set the matrix mode.
--
-- 'matrixMode' is a write-only state variable corresponding to
-- @VG_MATRIX_MODE@:
--
matrixMode :: SettableStateVar MatrixMode  
matrixMode = makeSettableStateVar $  
    seti MatrixMode . fromIntegral . marshalMatrixMode


-- | Set the current matrix to the identity matrix.
--
-- 'loadIdentity' corresponds to the OpenVG function 
-- @vgLoadIdentity@. 
--
loadIdentity :: IO ()
loadIdentity = vgLoadIdentity

-- | Query and set the current matrix.
-- 
-- 'matrix' is a read-write state variable corresponding to 
-- OpenVG operations @vgGetMatrix@ (query) and vgLoadMatrix (set). 
--
matrix :: StateVar VGmatrix
matrix = makeStateVar getMatrix loadMatrix




-- | Set the current matrix to the supplied matrix.
--
-- 'loadMatrix' corresponds to the OpenVG function @vgLoadMatrix@.
-- 
loadMatrix :: VGmatrix -> IO ()
loadMatrix mat = withMatrix mat vgLoadMatrix

-- | Get the current matrix.
--
-- 'getMatrix' corresponds to the OpenVG function @vgGetMatrix@.
--
getMatrix :: IO VGmatrix
getMatrix = withNewMatrix vgGetMatrix

-- | Multiply the current matrix by the supplied matrix.
-- 
-- 'multMatrix' corresponds to the OpenVG function @vgMultMatrix@.
--
multMatrix :: VGmatrix -> IO ()
multMatrix mat = withMatrix mat vgMultMatrix

-- | Apply a translation to the current matrix.
--
-- 'translate' corresponds to the OpenVG function @vgTranslate@. 
--
translate :: VGfloat -> VGfloat -> IO ()
translate = vgTranslate

-- | Apply a scaling to the current matrix.
--
-- 'scale' corresponds to the OpenVG function @vgScale@. 
--
scale :: VGfloat -> VGfloat -> IO ()
scale = vgScale

-- | Apply a shear to the current matrix.
--
-- 'shear' corresponds to the OpenVG function @vgShear@.
--
shear :: VGfloat -> VGfloat -> IO ()
shear = vgShear

-- | Apply a rotation to the current matrix.
--
-- 'rotate' corresponds to the OpenVG function @vgRotate@.
--
rotate :: VGfloat -> IO ()
rotate = vgRotate    
    

--------------------------------------------------------------------------------
   
marshalRenderingQuality :: RenderingQuality -> VGenum
marshalRenderingQuality x = case x of
    Nonantialiased' -> vg_RENDERING_QUALITY_NONANTIALIASED  
    Faster'         -> vg_RENDERING_QUALITY_FASTER
    Better'         -> vg_RENDERING_QUALITY_BETTER


marshalPixelLayout :: PixelLayout -> VGenum
marshalPixelLayout x = case x of
    Unknown       -> vg_PIXEL_LAYOUT_UNKNOWN
    RgbVertical   -> vg_PIXEL_LAYOUT_RGB_VERTICAL
    BgrVertical   -> vg_PIXEL_LAYOUT_BGR_VERTICAL
    RgbHorizontal -> vg_PIXEL_LAYOUT_RGB_HORIZONTAL
    BgrHorizontal -> vg_PIXEL_LAYOUT_BGR_HORIZONTAL



unmarshalPixelLayout :: VGenum -> PixelLayout 
unmarshalPixelLayout x
    | x == vg_PIXEL_LAYOUT_UNKNOWN        = Unknown
    | x == vg_PIXEL_LAYOUT_RGB_VERTICAL   = RgbVertical 
    | x == vg_PIXEL_LAYOUT_BGR_VERTICAL   = BgrVertical 
    | x == vg_PIXEL_LAYOUT_RGB_HORIZONTAL = RgbHorizontal 
    | x == vg_PIXEL_LAYOUT_BGR_HORIZONTAL = BgrHorizontal 
    | otherwise                           = error  $ 
          "unmarshalPixelLayout: illegal value " ++ show x
    
    
marshalMatrixMode :: MatrixMode -> VGenum
marshalMatrixMode x = case x of 
    PathUserToSurface  -> vg_MATRIX_PATH_USER_TO_SURFACE
    ImageUserToSurface -> vg_MATRIX_IMAGE_USER_TO_SURFACE
    FillPaintToUser    -> vg_MATRIX_FILL_PAINT_TO_USER
    StrokePaintToUser  -> vg_MATRIX_STROKE_PAINT_TO_USER