A cbits/transcode.c => cbits/transcode.c +42 -0
@@ 0,0 1,42 @@
+#include "cmp.h"
+#include <fontconfig/fontconfig.h>
+#include <assert.h>
+
+FcCharSet *decodeCharSet(cmp_ctx_t *bytes) {
+    uint32_t size;
+    if (!cmp_read_array(bytes, &size)) return NULL;
+
+    FcCharSet *ret = FcCharSetCreate();
+    if (ret == NULL) return NULL;
+
+    FcChar32 prev = 0;
+    for (uint32_t i = 0; i < size; i++) {
+        uint32_t x;
+        if (!cmp_read_uint(bytes, &x)) goto fail;
+        prev += x;
+        if (!FcCharSetAddChar(ret, prev)) goto fail;
+    }
+    return ret;
+fail:
+    FcCharSetDestroy(ret);
+    return NULL;
+}
+
+bool encodeCharSet(cmp_ctx_t *bytes, FcCharSet *data) {
+    FcChar32 size = FcCharSetCount(data);
+    FcChar32 count = 0; // For validation
+    if (!cmp_write_array(bytes, size)) return false;
+
+    FcChar32 map[FC_CHARSET_MAP_SIZE];
+    FcChar32 next;
+    FcChar32 c = FcCharSetFirstPage(data, map, &next);
+    FcChar32 prev = 0;
+    while (c != FC_CHARSET_DONE) {
+        if (!cmp_write_uinteger(bytes, c - prev)) return false;
+        prev = c;
+        count++;
+        c = FcCharSetNextPage(data, map, &next);
+    }
+    assert(size == count);
+    return true;
+}
 
M fontconfig-pure.cabal => fontconfig-pure.cabal +1 -1
@@ 68,7 68,7 @@ library
             Graphics.Text.Font.Choose.StrSet, Graphics.Text.Font.Choose.Value,
             Graphics.Text.Font.Choose.Pattern, Graphics.Text.Font.Choose.FontSet
 
-    c-sources: cbits/cmp.c
+    c-sources: cbits/cmp.c, cbits/transcode.c
 
     -- Modules included in this library but not exported.
     -- other-modules:
 
M lib/Graphics/Text/Font/Choose/CharSet.hs => lib/Graphics/Text/Font/Choose/CharSet.hs +1 -1
@@ 47,7 47,7 @@ diffCompress :: Int -> [Int] -> [Int]
 diffCompress prev (x:xs) = x - prev:diffCompress x xs
 diffCompress _ [] = []
 diffDecompress :: Int -> [Int] -> [Int]
-diffDecompress prev (x:xs) = prev + x:diffDecompress x xs
+diffDecompress prev (x:xs) = let y = prev + x in y:diffDecompress y xs
 diffDecompress _ [] = []
 
 newtype CharSet' = CharSet' { unCharSet :: CharSet }