module Graphics.Text.Font.Choose.LangSet where import Data.Set (Set) import qualified Data.Set as Set import Graphics.Text.Font.Choose.Strings (thawStrSet, StrSet_) import Graphics.Text.Font.Choose.CharSet (thawCharSet, CharSet_, CharSet) import Foreign.Ptr (Ptr) import Foreign.C.String (CString, withCString, peekCString) import Control.Exception (bracket) import Control.Monad (forM) import System.IO.Unsafe (unsafePerformIO) type LangSet = Set String defaultLangs :: IO LangSet defaultLangs = thawStrSet =<< fcGetDefaultLangs foreign import ccall "FcGetDefaultLangs" fcGetDefaultLangs :: IO StrSet_ langs :: LangSet langs = unsafePerformIO (thawStrSet =<< fcGetLangs) foreign import ccall "FcGetLangs" fcGetLangs :: IO StrSet_ langNormalize :: String -> String langNormalize = unsafePerformIO $ flip withCString (peekCString . fcLangNormalize) foreign import ccall "FcLangNormalize" fcLangNormalize :: CString -> CString langCharSet :: String -> CharSet langCharSet = unsafePerformIO $ flip withCString (thawCharSet . fcLangGetCharSet) foreign import ccall "FcLangGetCharSet" fcLangGetCharSet :: CString -> CharSet_ ------ --- Low-level ------ data LangSet' type LangSet_ = Ptr LangSet' withNewLangSet :: (LangSet_ -> IO a) -> IO a withNewLangSet = bracket fcLangSetCreate fcLangSetDestroy foreign import ccall "FcLangSetCreate" fcLangSetCreate :: IO LangSet_ foreign import ccall "FcLangSetDestroy" fcLangSetDestroy :: LangSet_ -> IO () withLangSet :: LangSet -> (LangSet_ -> IO a) -> IO a withLangSet langs cb = withNewLangSet $ \langs' -> do forM (Set.elems langs) $ flip withCString $ fcLangSetAdd langs' cb langs' thawLangSet :: LangSet_ -> IO LangSet thawLangSet langs' = thawStrSet =<< fcLangSetGetLangs langs' foreign import ccall "FcLangSetGetLangs" fcLangSetGetLangs :: LangSet_ -> IO StrSet_