{-# 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
(Range -> Range -> Bool) -> (Range -> Range -> Bool) -> Eq Range
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
(Int -> Range -> ShowS)
-> (Range -> String) -> ([Range] -> ShowS) -> Show Range
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
Eq Range =>
(Range -> Range -> Ordering)
-> (Range -> Range -> Bool)
-> (Range -> Range -> Bool)
-> (Range -> Range -> Bool)
-> (Range -> Range -> Bool)
-> (Range -> Range -> Range)
-> (Range -> Range -> Range)
-> Ord 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
$cp1Ord :: Eq Range
Ord, (forall x. Range -> Rep Range x)
-> (forall x. Rep Range x -> Range) -> Generic Range
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 i :: Int
i j :: Int
j = Int -> Double
forall a. Enum a => Int -> a
toEnum Int
i Double -> Double -> Range
`Range` Int -> Double
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 :: Range -> (Range_ -> IO a) -> IO a
withRange (Range i :: Double
i j :: Double
j) = IO Range_ -> (Range_ -> IO ()) -> (Range_ -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Range_ -> Range_
forall a. Ptr a -> Ptr a
throwNull (Range_ -> Range_) -> IO Range_ -> IO Range_
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_
range' = (Ptr Double -> IO Range) -> IO Range
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Double -> IO Range) -> IO Range)
-> (Ptr Double -> IO Range) -> IO Range
forall a b. (a -> b) -> a -> b
$ \i' :: Ptr Double
i' -> (Ptr Double -> IO Range) -> IO Range
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Double -> IO Range) -> IO Range)
-> (Ptr Double -> IO Range) -> IO Range
forall a b. (a -> b) -> a -> b
$ \j' :: Ptr Double
j' -> do
    Bool -> IO ()
throwFalse (Bool -> IO ()) -> IO Bool -> IO (IO ())
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 <- Ptr Double -> IO Double
forall a. Storable a => Ptr a -> IO a
peek Ptr Double
i'
    Double
j <- Ptr Double -> IO Double
forall a. Storable a => Ptr a -> IO a
peek Ptr Double
j'
    Range -> IO Range
forall (m :: * -> *) a. Monad m => a -> m a
return (Range -> IO Range) -> Range -> IO Range
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