{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (garetxe@gmail.com)

A structure specifying a transformation between user-space
coordinates and device coordinates. The transformation
is given by

\<programlisting>
x_device = x_user * matrix->xx + y_user * matrix->xy + matrix->x0;
y_device = x_user * matrix->yx + y_user * matrix->yy + matrix->y0;
\<\/programlisting>

/Since: 1.6/
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.Pango.Structs.Matrix
    (

-- * Exported types
    Matrix(..)                              ,
    newZeroMatrix                           ,
    noMatrix                                ,


 -- * Methods
-- ** concat #method:concat#

#if ENABLE_OVERLOADING
    MatrixConcatMethodInfo                  ,
#endif
    matrixConcat                            ,


-- ** copy #method:copy#

#if ENABLE_OVERLOADING
    MatrixCopyMethodInfo                    ,
#endif
    matrixCopy                              ,


-- ** free #method:free#

#if ENABLE_OVERLOADING
    MatrixFreeMethodInfo                    ,
#endif
    matrixFree                              ,


-- ** getFontScaleFactor #method:getFontScaleFactor#

#if ENABLE_OVERLOADING
    MatrixGetFontScaleFactorMethodInfo      ,
#endif
    matrixGetFontScaleFactor                ,


-- ** getFontScaleFactors #method:getFontScaleFactors#

#if ENABLE_OVERLOADING
    MatrixGetFontScaleFactorsMethodInfo     ,
#endif
    matrixGetFontScaleFactors               ,


-- ** rotate #method:rotate#

#if ENABLE_OVERLOADING
    MatrixRotateMethodInfo                  ,
#endif
    matrixRotate                            ,


-- ** scale #method:scale#

#if ENABLE_OVERLOADING
    MatrixScaleMethodInfo                   ,
#endif
    matrixScale                             ,


-- ** transformDistance #method:transformDistance#

#if ENABLE_OVERLOADING
    MatrixTransformDistanceMethodInfo       ,
#endif
    matrixTransformDistance                 ,


-- ** transformPixelRectangle #method:transformPixelRectangle#

#if ENABLE_OVERLOADING
    MatrixTransformPixelRectangleMethodInfo ,
#endif
    matrixTransformPixelRectangle           ,


-- ** transformPoint #method:transformPoint#

#if ENABLE_OVERLOADING
    MatrixTransformPointMethodInfo          ,
#endif
    matrixTransformPoint                    ,


-- ** translate #method:translate#

#if ENABLE_OVERLOADING
    MatrixTranslateMethodInfo               ,
#endif
    matrixTranslate                         ,




 -- * Properties
-- ** x0 #attr:x0#
{- | x translation
-}
    getMatrixX0                             ,
#if ENABLE_OVERLOADING
    matrix_x0                               ,
#endif
    setMatrixX0                             ,


-- ** xx #attr:xx#
{- | 1st component of the transformation matrix
-}
    getMatrixXx                             ,
#if ENABLE_OVERLOADING
    matrix_xx                               ,
#endif
    setMatrixXx                             ,


-- ** xy #attr:xy#
{- | 2nd component of the transformation matrix
-}
    getMatrixXy                             ,
#if ENABLE_OVERLOADING
    matrix_xy                               ,
#endif
    setMatrixXy                             ,


-- ** y0 #attr:y0#
{- | y translation
-}
    getMatrixY0                             ,
#if ENABLE_OVERLOADING
    matrix_y0                               ,
#endif
    setMatrixY0                             ,


-- ** yx #attr:yx#
{- | 3rd component of the transformation matrix
-}
    getMatrixYx                             ,
#if ENABLE_OVERLOADING
    matrix_yx                               ,
#endif
    setMatrixYx                             ,


-- ** yy #attr:yy#
{- | 4th component of the transformation matrix
-}
    getMatrixYy                             ,
#if ENABLE_OVERLOADING
    matrix_yy                               ,
#endif
    setMatrixYy                             ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP

import {-# SOURCE #-} qualified GI.Pango.Structs.Rectangle as Pango.Rectangle

-- | Memory-managed wrapper type.
newtype Matrix = Matrix (ManagedPtr Matrix)
foreign import ccall "pango_matrix_get_type" c_pango_matrix_get_type ::
    IO GType

instance BoxedObject Matrix where
    boxedType _ = c_pango_matrix_get_type

-- | Construct a `Matrix` struct initialized to zero.
newZeroMatrix :: MonadIO m => m Matrix
newZeroMatrix = liftIO $ callocBoxedBytes 48 >>= wrapBoxed Matrix

instance tag ~ 'AttrSet => Constructible Matrix tag where
    new _ attrs = do
        o <- newZeroMatrix
        GI.Attributes.set o attrs
        return o


-- | A convenience alias for `Nothing` :: `Maybe` `Matrix`.
noMatrix :: Maybe Matrix
noMatrix = Nothing

{- |
Get the value of the “@xx@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' matrix #xx
@
-}
getMatrixXx :: MonadIO m => Matrix -> m Double
getMatrixXx s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 0) :: IO CDouble
    let val' = realToFrac val
    return val'

{- |
Set the value of the “@xx@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' matrix [ #xx 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMatrixXx :: MonadIO m => Matrix -> Double -> m ()
setMatrixXx s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = realToFrac val
    poke (ptr `plusPtr` 0) (val' :: CDouble)

#if ENABLE_OVERLOADING
data MatrixXxFieldInfo
instance AttrInfo MatrixXxFieldInfo where
    type AttrAllowedOps MatrixXxFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint MatrixXxFieldInfo = (~) Double
    type AttrBaseTypeConstraint MatrixXxFieldInfo = (~) Matrix
    type AttrGetType MatrixXxFieldInfo = Double
    type AttrLabel MatrixXxFieldInfo = "xx"
    type AttrOrigin MatrixXxFieldInfo = Matrix
    attrGet _ = getMatrixXx
    attrSet _ = setMatrixXx
    attrConstruct = undefined
    attrClear _ = undefined

matrix_xx :: AttrLabelProxy "xx"
matrix_xx = AttrLabelProxy

#endif


{- |
Get the value of the “@xy@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' matrix #xy
@
-}
getMatrixXy :: MonadIO m => Matrix -> m Double
getMatrixXy s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 8) :: IO CDouble
    let val' = realToFrac val
    return val'

{- |
Set the value of the “@xy@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' matrix [ #xy 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMatrixXy :: MonadIO m => Matrix -> Double -> m ()
setMatrixXy s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = realToFrac val
    poke (ptr `plusPtr` 8) (val' :: CDouble)

#if ENABLE_OVERLOADING
data MatrixXyFieldInfo
instance AttrInfo MatrixXyFieldInfo where
    type AttrAllowedOps MatrixXyFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint MatrixXyFieldInfo = (~) Double
    type AttrBaseTypeConstraint MatrixXyFieldInfo = (~) Matrix
    type AttrGetType MatrixXyFieldInfo = Double
    type AttrLabel MatrixXyFieldInfo = "xy"
    type AttrOrigin MatrixXyFieldInfo = Matrix
    attrGet _ = getMatrixXy
    attrSet _ = setMatrixXy
    attrConstruct = undefined
    attrClear _ = undefined

matrix_xy :: AttrLabelProxy "xy"
matrix_xy = AttrLabelProxy

#endif


{- |
Get the value of the “@yx@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' matrix #yx
@
-}
getMatrixYx :: MonadIO m => Matrix -> m Double
getMatrixYx s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 16) :: IO CDouble
    let val' = realToFrac val
    return val'

{- |
Set the value of the “@yx@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' matrix [ #yx 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMatrixYx :: MonadIO m => Matrix -> Double -> m ()
setMatrixYx s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = realToFrac val
    poke (ptr `plusPtr` 16) (val' :: CDouble)

#if ENABLE_OVERLOADING
data MatrixYxFieldInfo
instance AttrInfo MatrixYxFieldInfo where
    type AttrAllowedOps MatrixYxFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint MatrixYxFieldInfo = (~) Double
    type AttrBaseTypeConstraint MatrixYxFieldInfo = (~) Matrix
    type AttrGetType MatrixYxFieldInfo = Double
    type AttrLabel MatrixYxFieldInfo = "yx"
    type AttrOrigin MatrixYxFieldInfo = Matrix
    attrGet _ = getMatrixYx
    attrSet _ = setMatrixYx
    attrConstruct = undefined
    attrClear _ = undefined

matrix_yx :: AttrLabelProxy "yx"
matrix_yx = AttrLabelProxy

#endif


{- |
Get the value of the “@yy@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' matrix #yy
@
-}
getMatrixYy :: MonadIO m => Matrix -> m Double
getMatrixYy s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 24) :: IO CDouble
    let val' = realToFrac val
    return val'

{- |
Set the value of the “@yy@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' matrix [ #yy 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMatrixYy :: MonadIO m => Matrix -> Double -> m ()
setMatrixYy s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = realToFrac val
    poke (ptr `plusPtr` 24) (val' :: CDouble)

#if ENABLE_OVERLOADING
data MatrixYyFieldInfo
instance AttrInfo MatrixYyFieldInfo where
    type AttrAllowedOps MatrixYyFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint MatrixYyFieldInfo = (~) Double
    type AttrBaseTypeConstraint MatrixYyFieldInfo = (~) Matrix
    type AttrGetType MatrixYyFieldInfo = Double
    type AttrLabel MatrixYyFieldInfo = "yy"
    type AttrOrigin MatrixYyFieldInfo = Matrix
    attrGet _ = getMatrixYy
    attrSet _ = setMatrixYy
    attrConstruct = undefined
    attrClear _ = undefined

matrix_yy :: AttrLabelProxy "yy"
matrix_yy = AttrLabelProxy

#endif


{- |
Get the value of the “@x0@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' matrix #x0
@
-}
getMatrixX0 :: MonadIO m => Matrix -> m Double
getMatrixX0 s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 32) :: IO CDouble
    let val' = realToFrac val
    return val'

{- |
Set the value of the “@x0@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' matrix [ #x0 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMatrixX0 :: MonadIO m => Matrix -> Double -> m ()
setMatrixX0 s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = realToFrac val
    poke (ptr `plusPtr` 32) (val' :: CDouble)

#if ENABLE_OVERLOADING
data MatrixX0FieldInfo
instance AttrInfo MatrixX0FieldInfo where
    type AttrAllowedOps MatrixX0FieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint MatrixX0FieldInfo = (~) Double
    type AttrBaseTypeConstraint MatrixX0FieldInfo = (~) Matrix
    type AttrGetType MatrixX0FieldInfo = Double
    type AttrLabel MatrixX0FieldInfo = "x0"
    type AttrOrigin MatrixX0FieldInfo = Matrix
    attrGet _ = getMatrixX0
    attrSet _ = setMatrixX0
    attrConstruct = undefined
    attrClear _ = undefined

matrix_x0 :: AttrLabelProxy "x0"
matrix_x0 = AttrLabelProxy

#endif


{- |
Get the value of the “@y0@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' matrix #y0
@
-}
getMatrixY0 :: MonadIO m => Matrix -> m Double
getMatrixY0 s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 40) :: IO CDouble
    let val' = realToFrac val
    return val'

{- |
Set the value of the “@y0@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' matrix [ #y0 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMatrixY0 :: MonadIO m => Matrix -> Double -> m ()
setMatrixY0 s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = realToFrac val
    poke (ptr `plusPtr` 40) (val' :: CDouble)

#if ENABLE_OVERLOADING
data MatrixY0FieldInfo
instance AttrInfo MatrixY0FieldInfo where
    type AttrAllowedOps MatrixY0FieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint MatrixY0FieldInfo = (~) Double
    type AttrBaseTypeConstraint MatrixY0FieldInfo = (~) Matrix
    type AttrGetType MatrixY0FieldInfo = Double
    type AttrLabel MatrixY0FieldInfo = "y0"
    type AttrOrigin MatrixY0FieldInfo = Matrix
    attrGet _ = getMatrixY0
    attrSet _ = setMatrixY0
    attrConstruct = undefined
    attrClear _ = undefined

matrix_y0 :: AttrLabelProxy "y0"
matrix_y0 = AttrLabelProxy

#endif



#if ENABLE_OVERLOADING
instance O.HasAttributeList Matrix
type instance O.AttributeList Matrix = MatrixAttributeList
type MatrixAttributeList = ('[ '("xx", MatrixXxFieldInfo), '("xy", MatrixXyFieldInfo), '("yx", MatrixYxFieldInfo), '("yy", MatrixYyFieldInfo), '("x0", MatrixX0FieldInfo), '("y0", MatrixY0FieldInfo)] :: [(Symbol, *)])
#endif

-- method Matrix::concat
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "new_matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_concat" pango_matrix_concat ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    Ptr Matrix ->                           -- new_matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    IO ()

{- |
Changes the transformation represented by /@matrix@/ to be the
transformation given by first applying transformation
given by /@newMatrix@/ then applying the original transformation.

/Since: 1.6/
-}
matrixConcat ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix' -}
    -> Matrix
    {- ^ /@newMatrix@/: a 'GI.Pango.Structs.Matrix.Matrix' -}
    -> m ()
matrixConcat matrix newMatrix = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    newMatrix' <- unsafeManagedPtrGetPtr newMatrix
    pango_matrix_concat matrix' newMatrix'
    touchManagedPtr matrix
    touchManagedPtr newMatrix
    return ()

#if ENABLE_OVERLOADING
data MatrixConcatMethodInfo
instance (signature ~ (Matrix -> m ()), MonadIO m) => O.MethodInfo MatrixConcatMethodInfo Matrix signature where
    overloadedMethod _ = matrixConcat

#endif

-- method Matrix::copy
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix, may be %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Pango", name = "Matrix"}))
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_copy" pango_matrix_copy ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    IO (Ptr Matrix)

{- |
Copies a 'GI.Pango.Structs.Matrix.Matrix'.

/Since: 1.6/
-}
matrixCopy ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix', may be 'Nothing' -}
    -> m (Maybe Matrix)
    {- ^ __Returns:__ the newly allocated 'GI.Pango.Structs.Matrix.Matrix', which
              should be freed with 'GI.Pango.Structs.Matrix.matrixFree', or 'Nothing' if
              /@matrix@/ was 'Nothing'. -}
matrixCopy matrix = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    result <- pango_matrix_copy matrix'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- (wrapBoxed Matrix) result'
        return result''
    touchManagedPtr matrix
    return maybeResult

#if ENABLE_OVERLOADING
data MatrixCopyMethodInfo
instance (signature ~ (m (Maybe Matrix)), MonadIO m) => O.MethodInfo MatrixCopyMethodInfo Matrix signature where
    overloadedMethod _ = matrixCopy

#endif

-- method Matrix::free
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix, may be %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_free" pango_matrix_free ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    IO ()

{- |
Free a 'GI.Pango.Structs.Matrix.Matrix' created with 'GI.Pango.Structs.Matrix.matrixCopy'.

/Since: 1.6/
-}
matrixFree ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix', may be 'Nothing' -}
    -> m ()
matrixFree matrix = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    pango_matrix_free matrix'
    touchManagedPtr matrix
    return ()

#if ENABLE_OVERLOADING
data MatrixFreeMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo MatrixFreeMethodInfo Matrix signature where
    overloadedMethod _ = matrixFree

#endif

-- method Matrix::get_font_scale_factor
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix, may be %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TDouble)
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_get_font_scale_factor" pango_matrix_get_font_scale_factor ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    IO CDouble

{- |
Returns the scale factor of a matrix on the height of the font.
That is, the scale factor in the direction perpendicular to the
vector that the X coordinate is mapped to.  If the scale in the X
coordinate is needed as well, use 'GI.Pango.Structs.Matrix.matrixGetFontScaleFactors'.

/Since: 1.12/
-}
matrixGetFontScaleFactor ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix', may be 'Nothing' -}
    -> m Double
    {- ^ __Returns:__ the scale factor of /@matrix@/ on the height of the font,
or 1.0 if /@matrix@/ is 'Nothing'. -}
matrixGetFontScaleFactor matrix = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    result <- pango_matrix_get_font_scale_factor matrix'
    let result' = realToFrac result
    touchManagedPtr matrix
    return result'

#if ENABLE_OVERLOADING
data MatrixGetFontScaleFactorMethodInfo
instance (signature ~ (m Double), MonadIO m) => O.MethodInfo MatrixGetFontScaleFactorMethodInfo Matrix signature where
    overloadedMethod _ = matrixGetFontScaleFactor

#endif

-- method Matrix::get_font_scale_factors
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "xscale", argType = TBasicType TDouble, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "output scale factor in the x direction, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "yscale", argType = TBasicType TDouble, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "output scale factor perpendicular to the x direction, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_get_font_scale_factors" pango_matrix_get_font_scale_factors ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    Ptr CDouble ->                          -- xscale : TBasicType TDouble
    Ptr CDouble ->                          -- yscale : TBasicType TDouble
    IO ()

{- |
Calculates the scale factor of a matrix on the width and height of the font.
That is, /@xscale@/ is the scale factor in the direction of the X coordinate,
and /@yscale@/ is the scale factor in the direction perpendicular to the
vector that the X coordinate is mapped to.

Note that output numbers will always be non-negative.

/Since: 1.38/
-}
matrixGetFontScaleFactors ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix', or 'Nothing' -}
    -> m ((Double, Double))
matrixGetFontScaleFactors matrix = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    xscale <- allocMem :: IO (Ptr CDouble)
    yscale <- allocMem :: IO (Ptr CDouble)
    pango_matrix_get_font_scale_factors matrix' xscale yscale
    xscale' <- peek xscale
    let xscale'' = realToFrac xscale'
    yscale' <- peek yscale
    let yscale'' = realToFrac yscale'
    touchManagedPtr matrix
    freeMem xscale
    freeMem yscale
    return (xscale'', yscale'')

#if ENABLE_OVERLOADING
data MatrixGetFontScaleFactorsMethodInfo
instance (signature ~ (m ((Double, Double))), MonadIO m) => O.MethodInfo MatrixGetFontScaleFactorsMethodInfo Matrix signature where
    overloadedMethod _ = matrixGetFontScaleFactors

#endif

-- method Matrix::rotate
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "degrees", argType = TBasicType TDouble, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "degrees to rotate counter-clockwise", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_rotate" pango_matrix_rotate ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    CDouble ->                              -- degrees : TBasicType TDouble
    IO ()

{- |
Changes the transformation represented by /@matrix@/ to be the
transformation given by first rotating by /@degrees@/ degrees
counter-clockwise then applying the original transformation.

/Since: 1.6/
-}
matrixRotate ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix' -}
    -> Double
    {- ^ /@degrees@/: degrees to rotate counter-clockwise -}
    -> m ()
matrixRotate matrix degrees = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    let degrees' = realToFrac degrees
    pango_matrix_rotate matrix' degrees'
    touchManagedPtr matrix
    return ()

#if ENABLE_OVERLOADING
data MatrixRotateMethodInfo
instance (signature ~ (Double -> m ()), MonadIO m) => O.MethodInfo MatrixRotateMethodInfo Matrix signature where
    overloadedMethod _ = matrixRotate

#endif

-- method Matrix::scale
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "scale_x", argType = TBasicType TDouble, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "amount to scale by in X direction", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "scale_y", argType = TBasicType TDouble, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "amount to scale by in Y direction", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_scale" pango_matrix_scale ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    CDouble ->                              -- scale_x : TBasicType TDouble
    CDouble ->                              -- scale_y : TBasicType TDouble
    IO ()

{- |
Changes the transformation represented by /@matrix@/ to be the
transformation given by first scaling by /@sx@/ in the X direction
and /@sy@/ in the Y direction then applying the original
transformation.

/Since: 1.6/
-}
matrixScale ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix' -}
    -> Double
    {- ^ /@scaleX@/: amount to scale by in X direction -}
    -> Double
    {- ^ /@scaleY@/: amount to scale by in Y direction -}
    -> m ()
matrixScale matrix scaleX scaleY = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    let scaleX' = realToFrac scaleX
    let scaleY' = realToFrac scaleY
    pango_matrix_scale matrix' scaleX' scaleY'
    touchManagedPtr matrix
    return ()

#if ENABLE_OVERLOADING
data MatrixScaleMethodInfo
instance (signature ~ (Double -> Double -> m ()), MonadIO m) => O.MethodInfo MatrixScaleMethodInfo Matrix signature where
    overloadedMethod _ = matrixScale

#endif

-- method Matrix::transform_distance
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "dx", argType = TBasicType TDouble, direction = DirectionInout, mayBeNull = False, argDoc = Documentation {rawDocText = Just "in/out X component of a distance vector", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "dy", argType = TBasicType TDouble, direction = DirectionInout, mayBeNull = False, argDoc = Documentation {rawDocText = Just "in/out Y component of a distance vector", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_transform_distance" pango_matrix_transform_distance ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    Ptr CDouble ->                          -- dx : TBasicType TDouble
    Ptr CDouble ->                          -- dy : TBasicType TDouble
    IO ()

{- |
Transforms the distance vector (/@dx@/,/@dy@/) by /@matrix@/. This is
similar to 'GI.Pango.Structs.Matrix.matrixTransformPoint' except that the translation
components of the transformation are ignored. The calculation of
the returned vector is as follows:

\<programlisting>
dx2 = dx1 * xx + dy1 * xy;
dy2 = dx1 * yx + dy1 * yy;
\<\/programlisting>

Affine transformations are position invariant, so the same vector
always transforms to the same vector. If (/@x1@/,/@y1@/) transforms
to (/@x2@/,/@y2@/) then (/@x1@/+/@dx1@/,/@y1@/+/@dy1@/) will transform to
(/@x1@/+/@dx2@/,/@y1@/+/@dy2@/) for all values of /@x1@/ and /@x2@/.

/Since: 1.16/
-}
matrixTransformDistance ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix', or 'Nothing' -}
    -> Double
    {- ^ /@dx@/: in\/out X component of a distance vector -}
    -> Double
    {- ^ /@dy@/: in\/out Y component of a distance vector -}
    -> m ((Double, Double))
matrixTransformDistance matrix dx dy = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    let dx' = realToFrac dx
    dx'' <- allocMem :: IO (Ptr CDouble)
    poke dx'' dx'
    let dy' = realToFrac dy
    dy'' <- allocMem :: IO (Ptr CDouble)
    poke dy'' dy'
    pango_matrix_transform_distance matrix' dx'' dy''
    dx''' <- peek dx''
    let dx'''' = realToFrac dx'''
    dy''' <- peek dy''
    let dy'''' = realToFrac dy'''
    touchManagedPtr matrix
    freeMem dx''
    freeMem dy''
    return (dx'''', dy'''')

#if ENABLE_OVERLOADING
data MatrixTransformDistanceMethodInfo
instance (signature ~ (Double -> Double -> m ((Double, Double))), MonadIO m) => O.MethodInfo MatrixTransformDistanceMethodInfo Matrix signature where
    overloadedMethod _ = matrixTransformDistance

#endif

-- method Matrix::transform_pixel_rectangle
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "rect", argType = TInterface (Name {namespace = "Pango", name = "Rectangle"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "in/out bounding box in device units, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_transform_pixel_rectangle" pango_matrix_transform_pixel_rectangle ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    Ptr Pango.Rectangle.Rectangle ->        -- rect : TInterface (Name {namespace = "Pango", name = "Rectangle"})
    IO ()

{- |
First transforms the /@rect@/ using /@matrix@/, then calculates the bounding box
of the transformed rectangle.  The rectangle should be in device units
(pixels).

This function is useful for example when you want to draw a rotated
/@pangoLayout@/ to an image buffer, and want to know how large the image
should be and how much you should shift the layout when rendering.

For better accuracy, you should use 'GI.Pango.Structs.Matrix.matrixTransformRectangle' on
original rectangle in Pango units and convert to pixels afterward
using 'GI.Pango.Functions.extentsToPixels'\'s first argument.

/Since: 1.16/
-}
matrixTransformPixelRectangle ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix', or 'Nothing' -}
    -> Maybe (Pango.Rectangle.Rectangle)
    {- ^ /@rect@/: in\/out bounding box in device units, or 'Nothing' -}
    -> m ()
matrixTransformPixelRectangle matrix rect = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    maybeRect <- case rect of
        Nothing -> return nullPtr
        Just jRect -> do
            jRect' <- unsafeManagedPtrGetPtr jRect
            return jRect'
    pango_matrix_transform_pixel_rectangle matrix' maybeRect
    touchManagedPtr matrix
    whenJust rect touchManagedPtr
    return ()

#if ENABLE_OVERLOADING
data MatrixTransformPixelRectangleMethodInfo
instance (signature ~ (Maybe (Pango.Rectangle.Rectangle) -> m ()), MonadIO m) => O.MethodInfo MatrixTransformPixelRectangleMethodInfo Matrix signature where
    overloadedMethod _ = matrixTransformPixelRectangle

#endif

-- method Matrix::transform_point
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "x", argType = TBasicType TDouble, direction = DirectionInout, mayBeNull = False, argDoc = Documentation {rawDocText = Just "in/out X position", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "y", argType = TBasicType TDouble, direction = DirectionInout, mayBeNull = False, argDoc = Documentation {rawDocText = Just "in/out Y position", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_transform_point" pango_matrix_transform_point ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    Ptr CDouble ->                          -- x : TBasicType TDouble
    Ptr CDouble ->                          -- y : TBasicType TDouble
    IO ()

{- |
Transforms the point (/@x@/, /@y@/) by /@matrix@/.

/Since: 1.16/
-}
matrixTransformPoint ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix', or 'Nothing' -}
    -> Double
    {- ^ /@x@/: in\/out X position -}
    -> Double
    {- ^ /@y@/: in\/out Y position -}
    -> m ((Double, Double))
matrixTransformPoint matrix x y = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    let x' = realToFrac x
    x'' <- allocMem :: IO (Ptr CDouble)
    poke x'' x'
    let y' = realToFrac y
    y'' <- allocMem :: IO (Ptr CDouble)
    poke y'' y'
    pango_matrix_transform_point matrix' x'' y''
    x''' <- peek x''
    let x'''' = realToFrac x'''
    y''' <- peek y''
    let y'''' = realToFrac y'''
    touchManagedPtr matrix
    freeMem x''
    freeMem y''
    return (x'''', y'''')

#if ENABLE_OVERLOADING
data MatrixTransformPointMethodInfo
instance (signature ~ (Double -> Double -> m ((Double, Double))), MonadIO m) => O.MethodInfo MatrixTransformPointMethodInfo Matrix signature where
    overloadedMethod _ = matrixTransformPoint

#endif

-- XXX Could not generate method Matrix::transform_rectangle
-- Error was : Not implemented: "Nullable inout structs not supported"
-- method Matrix::translate
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "matrix", argType = TInterface (Name {namespace = "Pango", name = "Matrix"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #PangoMatrix", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "tx", argType = TBasicType TDouble, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "amount to translate in the X direction", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "ty", argType = TBasicType TDouble, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "amount to translate in the Y direction", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "pango_matrix_translate" pango_matrix_translate ::
    Ptr Matrix ->                           -- matrix : TInterface (Name {namespace = "Pango", name = "Matrix"})
    CDouble ->                              -- tx : TBasicType TDouble
    CDouble ->                              -- ty : TBasicType TDouble
    IO ()

{- |
Changes the transformation represented by /@matrix@/ to be the
transformation given by first translating by (/@tx@/, /@ty@/)
then applying the original transformation.

/Since: 1.6/
-}
matrixTranslate ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Matrix
    {- ^ /@matrix@/: a 'GI.Pango.Structs.Matrix.Matrix' -}
    -> Double
    {- ^ /@tx@/: amount to translate in the X direction -}
    -> Double
    {- ^ /@ty@/: amount to translate in the Y direction -}
    -> m ()
matrixTranslate matrix tx ty = liftIO $ do
    matrix' <- unsafeManagedPtrGetPtr matrix
    let tx' = realToFrac tx
    let ty' = realToFrac ty
    pango_matrix_translate matrix' tx' ty'
    touchManagedPtr matrix
    return ()

#if ENABLE_OVERLOADING
data MatrixTranslateMethodInfo
instance (signature ~ (Double -> Double -> m ()), MonadIO m) => O.MethodInfo MatrixTranslateMethodInfo Matrix signature where
    overloadedMethod _ = matrixTranslate

#endif

#if ENABLE_OVERLOADING
type family ResolveMatrixMethod (t :: Symbol) (o :: *) :: * where
    ResolveMatrixMethod "concat" o = MatrixConcatMethodInfo
    ResolveMatrixMethod "copy" o = MatrixCopyMethodInfo
    ResolveMatrixMethod "free" o = MatrixFreeMethodInfo
    ResolveMatrixMethod "rotate" o = MatrixRotateMethodInfo
    ResolveMatrixMethod "scale" o = MatrixScaleMethodInfo
    ResolveMatrixMethod "transformDistance" o = MatrixTransformDistanceMethodInfo
    ResolveMatrixMethod "transformPixelRectangle" o = MatrixTransformPixelRectangleMethodInfo
    ResolveMatrixMethod "transformPoint" o = MatrixTransformPointMethodInfo
    ResolveMatrixMethod "translate" o = MatrixTranslateMethodInfo
    ResolveMatrixMethod "getFontScaleFactor" o = MatrixGetFontScaleFactorMethodInfo
    ResolveMatrixMethod "getFontScaleFactors" o = MatrixGetFontScaleFactorsMethodInfo
    ResolveMatrixMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveMatrixMethod t Matrix, O.MethodInfo info Matrix p) => O.IsLabelProxy t (Matrix -> p) where
    fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveMatrixMethod t Matrix, O.MethodInfo info Matrix p) => O.IsLabel t (Matrix -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif
#endif

#endif