~alcinnz/fontconfig-pure

ref: d3bb3d92191d9e740c1d827e5c56f58d725d8c42 fontconfig-pure/Graphics/Text/Font/Choose/Strings.hs -rw-r--r-- 2.5 KiB
d3bb3d92 — Adrian Cochrane Upload documentation on initialization/finalization routines. 2 years ago
                                                                                
e21707cb Adrian Cochrane
9a276931 Adrian Cochrane
e21707cb Adrian Cochrane
fcf1e371 Adrian Cochrane
e21707cb Adrian Cochrane
fcf1e371 Adrian Cochrane
e21707cb Adrian Cochrane
fcf1e371 Adrian Cochrane
e21707cb Adrian Cochrane
fcf1e371 Adrian Cochrane
e21707cb Adrian Cochrane
7b41b9f8 Adrian Cochrane
e21707cb Adrian Cochrane
fcf1e371 Adrian Cochrane
e21707cb Adrian Cochrane
9a276931 Adrian Cochrane
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
module Graphics.Text.Font.Choose.Strings (StrSet, StrSet_, StrList, StrList_,
    withStrSet, withFilenameSet, thawStrSet, thawStrSet_,
    withStrList, thawStrList, thawStrList_) where

import Data.Set (Set)
import qualified Data.Set as Set
import Graphics.Text.Font.Choose.Result (throwNull, throwFalse)

import Foreign.Ptr (Ptr, nullPtr)
import Foreign.C.String (CString, withCString, peekCString)
import Control.Exception (bracket)
import Control.Monad (forM)

type StrSet = Set String

data StrSet'
type StrSet_ = Ptr StrSet'

withNewStrSet :: (StrSet_ -> IO a) -> IO a
withNewStrSet = bracket (throwNull <$> fcStrSetCreate) fcStrSetDestroy
foreign import ccall "FcStrSetCreate" fcStrSetCreate :: IO StrSet_
foreign import ccall "FcStrSetDestroy" fcStrSetDestroy :: StrSet_ -> IO ()

withStrSet :: StrSet -> (StrSet_ -> IO a) -> IO a
withStrSet strs cb = withNewStrSet $ \strs' -> do
    forM (Set.elems strs) $ \str ->
        throwFalse <$> (withCString str $ fcStrSetAdd strs')
    cb strs'
foreign import ccall "FcStrSetAdd" fcStrSetAdd :: StrSet_ -> CString -> IO Bool

withFilenameSet :: StrSet -> (StrSet_ -> IO a) -> IO a
withFilenameSet paths cb = withNewStrSet $ \paths' -> do
    forM (Set.elems paths) $ \path ->
        throwFalse <$> (withCString path $ fcStrSetAddFilename paths')
    cb paths'
foreign import ccall "FcStrSetAddFilename" fcStrSetAddFilename ::
    StrSet_ -> CString -> IO Bool

thawStrSet :: StrSet_ -> IO StrSet
thawStrSet strs = Set.fromList <$> withStrList strs thawStrList

thawStrSet_ :: IO StrSet_ -> IO StrSet
thawStrSet_ cb = bracket (throwNull <$> cb) fcStrSetDestroy thawStrSet

------------

type StrList = [String]

data StrList'
type StrList_ = Ptr StrList'

withStrList :: StrSet_ -> (StrList_ -> IO a) -> IO a
withStrList strs = bracket (throwNull <$> fcStrListCreate strs) fcStrListDone
foreign import ccall "FcStrListCreate" fcStrListCreate :: StrSet_ -> IO StrList_
foreign import ccall "FcStrListDone" fcStrListDone :: StrList_ -> IO ()

thawStrList :: StrList_ -> IO StrList
thawStrList strs' = do
    fcStrListFirst strs'
    go
  where
    go = do
        item' <- fcStrListNext strs'
        if item' == nullPtr then return []
        else do
            item <- peekCString item'
            items <- go
            return (item : items)
foreign import ccall "FcStrListFirst" fcStrListFirst :: StrList_ -> IO ()
foreign import ccall "FcStrListNext" fcStrListNext :: StrList_ -> IO CString

thawStrList_ :: IO StrList_ -> IO StrList
thawStrList_ cb = bracket (throwNull <$> cb) fcStrListDone thawStrList