~alcinnz/fontconfig-pure

ref: 8abf298021bdbd08bbac04628ff88f5b0ad69ad0 fontconfig-pure/Graphics/Text/Font/Choose/Strings.hs -rw-r--r-- 2.6 KiB
8abf2980 — Adrian Cochrane Fix various segfaults & exercise bridging from FcPatterns to Ft_Faces. 1 year, 10 months ago
                                                                                
e21707cb Adrian Cochrane
9a276931 Adrian Cochrane
e21707cb Adrian Cochrane
fcf1e371 Adrian Cochrane
e21707cb Adrian Cochrane
b1d28833 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
b1d28833 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
74
75
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)

-- | Set of strings, as exposed by other FreeType APIs.
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

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

-- | Output string lists from FontConfig.
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