{-# LANGUAGE DeriveGeneric #-}
module Graphics.Text.Font.Choose.Range where

import Foreign.Ptr (Ptr)
import Control.Exception (bracket)
import Foreign.Marshal.Alloc (alloca)
import Foreign.Storable (peek)

import GHC.Generics (Generic)
import Data.Hashable (Hashable)
import Graphics.Text.Font.Choose.Result (throwNull, throwFalse)

-- | Matches a numeric range.
data Range = Range Double Double deriving (Range -> Range -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Range -> Range -> Bool
$c/= :: Range -> Range -> Bool
== :: Range -> Range -> Bool
$c== :: Range -> Range -> Bool
Eq, Int -> Range -> ShowS
[Range] -> ShowS
Range -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Range] -> ShowS
$cshowList :: [Range] -> ShowS
show :: Range -> String
$cshow :: Range -> String
showsPrec :: Int -> Range -> ShowS
$cshowsPrec :: Int -> Range -> ShowS
Show, Eq Range
Range -> Range -> Bool
Range -> Range -> Ordering
Range -> Range -> Range
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Range -> Range -> Range
$cmin :: Range -> Range -> Range
max :: Range -> Range -> Range
$cmax :: Range -> Range -> Range
>= :: Range -> Range -> Bool
$c>= :: Range -> Range -> Bool
> :: Range -> Range -> Bool
$c> :: Range -> Range -> Bool
<= :: Range -> Range -> Bool
$c<= :: Range -> Range -> Bool
< :: Range -> Range -> Bool
$c< :: Range -> Range -> Bool
compare :: Range -> Range -> Ordering
$ccompare :: Range -> Range -> Ordering
Ord, forall x. Rep Range x -> Range
forall x. Range -> Rep Range x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Range x -> Range
$cfrom :: forall x. Range -> Rep Range x
Generic)
-- | Matches an integral range.
iRange :: Int -> Int -> Range
iRange Int
i Int
j = forall a. Enum a => Int -> a
toEnum Int
i Double -> Double -> Range
`Range` forall a. Enum a => Int -> a
toEnum Int
j

instance Hashable Range

------
--- Low-level
------
data Range'
type Range_ = Ptr Range'

withRange :: Range -> (Range_ -> IO a) -> IO a
withRange :: forall a. Range -> (Range_ -> IO a) -> IO a
withRange (Range Double
i Double
j) = forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (forall a. Ptr a -> Ptr a
throwNull forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Double -> Double -> IO Range_
fcRangeCreateDouble Double
i Double
j) Range_ -> IO ()
fcRangeDestroy
foreign import ccall "FcRangeCreateDouble" fcRangeCreateDouble ::
    Double -> Double -> IO Range_
foreign import ccall "FcRangeDestroy" fcRangeDestroy :: Range_ -> IO ()

thawRange :: Range_ -> IO Range
thawRange :: Range_ -> IO Range
thawRange Range_
range' = forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$ \Ptr Double
i' -> forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$ \Ptr Double
j' -> do
    Bool -> IO ()
throwFalse forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range_ -> Ptr Double -> Ptr Double -> IO Bool
fcRangeGetDouble Range_
range' Ptr Double
i' Ptr Double
j'
    Double
i <- forall a. Storable a => Ptr a -> IO a
peek Ptr Double
i'
    Double
j <- forall a. Storable a => Ptr a -> IO a
peek Ptr Double
j'
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Double -> Double -> Range
Range Double
i Double
j
foreign import ccall "FcRangeGetDouble" fcRangeGetDouble ::
    Range_ -> Ptr Double -> Ptr Double -> IO Bool