packages feed

fontconfig-pure 0.2.0.1 → 0.3.0.0

raw patch · 6 files changed

+80/−42 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Graphics.Text.Font.Choose: chr :: Int -> Char
+ Graphics.Text.Font.Choose: ord :: Char -> Int
- Graphics.Text.Font.Choose: type CharSet = Set Char
+ Graphics.Text.Font.Choose: type CharSet = IntSet

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for fontconfig-pure +## 0.3.0.0 -- 2023-10-01++* Addressing segfaults & mainloops.+* Switched underlying CharSet collection to IntSet for efficiency.+ ## 0.1.0.0 -- YYYY-mm-dd  * First version. Released on an unsuspecting world.
Graphics/Text/Font/Choose.hs view
@@ -1,5 +1,5 @@-module Graphics.Text.Font.Choose(CharSet, FontSet, ObjectSet, Pattern(..), Binding(..),-  Range(..), iRange, StrSet, StrList, Value(..), FontFaceParser(..),+module Graphics.Text.Font.Choose(CharSet, chr, ord, FontSet, ObjectSet, Pattern(..),+  Binding(..), Range(..), iRange, StrSet, StrList, Value(..), FontFaceParser(..),    Config, configCreate,   configSetCurrent, configGetCurrent, configUptoDate, configHome, configEnableHome,@@ -26,6 +26,7 @@     ) where  import Prelude hiding (init, filter)+import Data.Char (chr, ord) -- For use with CharSet  import Graphics.Text.Font.Choose.CharSet (CharSet) import Graphics.Text.Font.Choose.Config (Config, configCreate,
Graphics/Text/Font/Choose/CharSet.hs view
@@ -1,11 +1,13 @@ module Graphics.Text.Font.Choose.CharSet where -import Data.Set (Set, union)-import qualified Data.Set as Set+import Data.IntSet (IntSet, union)+import qualified Data.IntSet as IntSet import Graphics.Text.Font.Choose.Result (throwNull, throwFalse)+import System.IO.Unsafe (unsafeInterleaveIO)  import Data.Word (Word32) import Foreign.Ptr+import Foreign.ForeignPtr (newForeignPtr, withForeignPtr) import Control.Exception (bracket) import Control.Monad (forM) import Foreign.Marshal.Alloc (alloca)@@ -15,29 +17,33 @@ import Numeric (readHex)  -- | An FcCharSet is a set of Unicode chars.-type CharSet = Set Char+type CharSet = IntSet -parseChar :: String -> Char+parseChar :: String -> Int parseChar str | ((x, _):_) <- readHex str = toEnum x+replaceWild :: Char -> String -> String replaceWild ch ('?':rest) = ch:replaceWild ch rest replaceWild ch (c:cs) = c:replaceWild ch cs replaceWild _ "" = ""+parseWild :: Char -> String -> Int parseWild ch str = parseChar $ replaceWild ch str -- | Utility for parsing "unicode-range" @font-face property.+parseCharSet :: String -> Maybe CharSet parseCharSet ('U':rest) = parseCharSet ('u':rest) -- lowercase initial "u" parseCharSet ('u':'+':cs)     | (start@(_:_), '-':ends) <- span isHexDigit cs,         (end@(_:_), rest) <- span isHexDigit ends, Just set <- parseCharSet' rest =-            Just $ Set.union set $ Set.fromList [parseChar start..parseChar end]+            Just $ union set $ IntSet.fromList [parseChar start..parseChar end]     | (codepoint@(_:_), rest) <- span isHexDigit cs, Just set <- parseCharSet' rest =-        Just $ flip Set.insert set $ parseChar codepoint+        Just $ flip IntSet.insert set $ parseChar codepoint     | (codepoint@(_:_), rest) <- span (\c -> isHexDigit c || c == '?') cs,         Just set <- parseCharSet' rest =-            Just $ Set.union set $ Set.fromList [+            Just $ IntSet.union set $ IntSet.fromList [                 parseWild '0' codepoint..parseWild 'f' codepoint] parseCharSet _ = Nothing+parseCharSet' :: String -> Maybe CharSet parseCharSet' (',':rest) = parseCharSet rest-parseCharSet' "" = Just Set.empty+parseCharSet' "" = Just IntSet.empty parseCharSet' _ = Nothing  ------@@ -54,30 +60,36 @@  withCharSet :: CharSet -> (CharSet_ -> IO a) -> IO a withCharSet chars cb = withNewCharSet $ \chars' -> do-    forM (Set.elems chars) $ \ch' ->-        throwFalse <$> (fcCharSetAddChar chars' $ fromIntegral $ ord ch')+    forM (IntSet.elems chars) $ \ch' ->+        throwFalse <$> (fcCharSetAddChar chars' $ fromIntegral ch')     cb chars' foreign import ccall "FcCharSetAddChar" fcCharSetAddChar :: CharSet_ -> Word32 -> IO Bool  thawCharSet :: CharSet_ -> IO CharSet thawCharSet chars'-    | chars' == nullPtr = return Set.empty-    | otherwise = allocaArray fcCHARSET_MAP_SIZE $ \iter' -> alloca $ \next' -> do-        first <- fcCharSetFirstPage chars' iter' next'-        let go = do-                ch <- fcCharSetNextPage chars' iter' next'-                if ch == maxBound then return []-                else do-                    chs <- go-                    return (ch:chs)-        if first == maxBound then return Set.empty else do-            rest <- go-            return $ Set.fromList $ map (unsafeChr . fromIntegral) (first:rest)-foreign import ccall "my_FcCharSetFirstPage" fcCharSetFirstPage ::-    CharSet_ -> Ptr Word32 -> Ptr Word32 -> IO Word32-foreign import ccall "my_FcCharSetNextPage" fcCharSetNextPage ::-    CharSet_ -> Ptr Word32 -> Ptr Word32 -> IO Word32-foreign import ccall "my_FcCHARSET_MAP_SIZE" fcCHARSET_MAP_SIZE :: Int+    | chars' == nullPtr = return IntSet.empty+    | otherwise = do+        iter' <- throwNull <$> fcCharSetIterCreate chars'+        iter <- newForeignPtr (fcCharSetIterDestroy) iter'+        x <- withForeignPtr iter fcCharSetIterStart+        let go x' | fcCharSetIterDone x' = return []+                | otherwise = unsafeInterleaveIO $ do+                    y <- withForeignPtr iter fcCharSetIterNext+                    xs <- go y+                    return (x':xs)+        ret <- go x+        return $ IntSet.fromList $ map (fromIntegral) ret+data CharSetIter'+type CharSetIter_ = Ptr CharSetIter'+foreign import ccall "my_FcCharSetIterCreate" fcCharSetIterCreate ::+    CharSet_ -> IO CharSetIter_+foreign import ccall "&my_FcCharSetIterDestroy" fcCharSetIterDestroy ::+    FunPtr (CharSetIter_ -> IO ())+foreign import ccall "my_FcCharSetIterStart" fcCharSetIterStart ::+    CharSetIter_ -> IO Word32+foreign import ccall "my_FcCharSetIterNext" fcCharSetIterNext ::+    CharSetIter_ -> IO Word32+foreign import ccall "my_FcCharSetIterDone" fcCharSetIterDone :: Word32 -> Bool  thawCharSet_ :: IO CharSet_ -> IO CharSet thawCharSet_ cb = bracket (throwNull <$> cb) fcCharSetDestroy thawCharSet
+ cbits/charsetiter.c view
@@ -0,0 +1,31 @@+#include <fontconfig/fontconfig.h>+#include <stdlib.h>++struct my_FcCharSetIter {+    FcCharSet *charset;+    FcChar32 map[FC_CHARSET_MAP_SIZE];+    FcChar32 next;+};++struct my_FcCharSetIter *my_FcCharSetIterCreate(FcCharSet *a) {+    struct my_FcCharSetIter *self = malloc(sizeof(struct my_FcCharSetIter));+    self->charset = FcCharSetCopy(a);+    return self;+}++void my_FcCharSetIterDestroy(struct my_FcCharSetIter *self) {+    FcCharSetDestroy(self->charset);+    free(self);+}++FcChar32 my_FcCharSetIterStart(struct my_FcCharSetIter *self) {+    return FcCharSetFirstPage(self->charset, self->map, &self->next);+}++FcChar32 my_FcCharSetIterNext(struct my_FcCharSetIter *self) {+    return FcCharSetNextPage(self->charset, self->map, &self->next);+}++FcBool my_FcCharSetIterDone(FcChar32 chr) {+    return chr == FC_CHARSET_DONE;+}
cbits/pattern.c view
@@ -1,17 +1,6 @@ #include <fontconfig/fontconfig.h> #include <stddef.h> -int my_FcCHARSET_MAP_SIZE() {-    return FC_CHARSET_MAP_SIZE;-}--FcChar32 my_FcCharSetFirstPage(const FcCharSet *a, FcChar32 *map, FcChar32 *next) {-    return FcCharSetFirstPage(a, map, next);-}-FcChar32 my_FcCharSetNextPage(const FcCharSet *a, FcChar32 *map, FcChar32 *next) {-    return FcCharSetNextPage(a, map, next);-}- FcBool my_FcPatternAdd(FcPattern *p, const char *object,         FcBool binding, FcBool append, FcValue *value) {     if (binding) {
fontconfig-pure.cabal view
@@ -10,7 +10,7 @@ -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             0.2.0.1+version:             0.3.0.0  -- A short (one-line) description of the package. synopsis:            Pure-functional language bindings to FontConfig@@ -62,7 +62,7 @@                 Graphics.Text.Font.Choose.Config, Graphics.Text.Font.Choose.Init,                 Graphics.Text.Font.Choose.Weight -  c-sources:    cbits/pattern.c+  c-sources:    cbits/pattern.c, cbits/charsetiter.c    -- LANGUAGE extensions used by modules in this package.   -- other-extensions: