From 04e3e462ef4e7ce094848c0ea1424f1624f8bf9a Mon Sep 17 00:00:00 2001 From: Adrian Cochrane Date: Thu, 4 Apr 2024 16:43:43 +1300 Subject: [PATCH] Draft C-side wrappers for various FontConfig APIs. --- cbits/freetype-wrap.c | 651 ++++++++++++++++++++++++++++++++++++++++++ cbits/transcode.c | 24 +- cbits/transcode.h | 29 ++ fontconfig-pure.cabal | 2 + 4 files changed, 695 insertions(+), 11 deletions(-) create mode 100644 cbits/freetype-wrap.c create mode 100644 cbits/transcode.h diff --git a/cbits/freetype-wrap.c b/cbits/freetype-wrap.c new file mode 100644 index 0000000..41e9038 --- /dev/null +++ b/cbits/freetype-wrap.c @@ -0,0 +1,651 @@ +#include "transcode.h" +#include +#include +#include + +uint8_t *fcNameParse(char *name, size_t *length) { + FcPattern *pat = FcNameParse(name); + if (pat == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) {FcPatternDestroy(pat); return NULL;} + if (!encodePattern(&out, pat)) { + FcPatternDestroy(pat); cmp_bytes_free(&out); return NULL; + } + FcPatternDestroy(pat); + return cmp_bytes_take(&out, length); +} + +char *fcNameUnparse(uint8_t *data, size_t length) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, length)) return NULL; + FcPattern *pat = decodePattern(&in); + cmp_bytes_take(&in, NULL); // Caller frees `data`! + if (pat == NULL) return NULL; + + char *ret = FcNameUnparse(pat); + FcPatternDestroy(pat); + return ret; +} + +char *fcNameFormat(uint8_t *data, size_t length, char *format) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, length)) return NULL; + FcPattern *pat = decodePattern(&in); + cmp_bytes_take(&in, NULL); // Caller frees `data`! + if (pat == NULL) return NULL; + + char *ret = FcPatternFormat(pat, format); + FcPatternDestroy(pat); + return ret; +} + +uint8_t *fcFontSetList(FcConfig *config, uint8_t *sets, size_t sets_length, + uint8_t *pat, size_t pat_length, uint8_t *objects, size_t objs_length, size_t *length) { + cmp_ctx_t in; + uint8_t *ret = NULL; + + if (!cmp_bytes_init(&in, sets, sets_length)) return NULL; + size_t nsets; + FcFontSet **fontsets = decodeFontSets(&in, &nsets); + cmp_bytes_take(&in, NULL); + if (fontsets == NULL) return NULL; + + if (!cmp_bytes_init(&in, pat, pat_length)) goto fail_pat; + FcPattern *pattern = decodePattern(&in); + cmp_bytes_take(&in, NULL); + if (pattern == NULL) goto fail_pat; + + if (!cmp_bytes_init(&in, objects, objs_length)) goto fail_objs; + FcObjectSet *objs = decodeObjectSet(&in); + cmp_bytes_take(&in, NULL); + if (objs == NULL) goto fail_objs; + + FcFontSet *res = FcFontSetList(config, fontsets, nsets, pattern, objs); + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) goto fail; + bool ok = encodeFontSet(&out, res); + ret = cmp_bytes_take(&out, length); + if (!ok && ret != NULL) { free(ret); ret = NULL;} + +fail: + FcFontSetDestroy(res); + FcObjectSetDestroy(objs); +fail_objs: + FcPatternDestroy(pattern); +fail_pat: + for (size_t i = 0; i < nsets; i++) FcFontSetDestroy(fontsets[i]); + free(fontsets); + return ret; +} + + +// FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId, FcResultOutOfMemory + +uint8_t *fcFontSetMatch(FcConfig *config, uint8_t *sets, size_t sets_length, + uint8_t *pat, size_t pat_length, size_t *length) { + cmp_ctx_t in; + uint8_t *ret = NULL; + + if (!cmp_bytes_init(&in, sets, sets_length)) return NULL; + size_t nsets; + FcFontSet **fontsets = decodeFontSets(&in, &nsets); + cmp_bytes_take(&in, NULL); + if (fontsets == NULL) return NULL; + + if (!cmp_bytes_init(&in, pat, pat_length)) goto fail; + FcPattern *pattern = decodePattern(&in); + cmp_bytes_take(&in, NULL); + if (pattern == NULL) goto fail; + + // Necessary preprocessing! + FcPattern *res = NULL; + if (!FcConfigSubstitute(config, pattern, FcMatchPattern)) goto fail2; + FcDefaultSubstitute(pattern); + + FcResult err; + res = FcFontSetMatch(config, fontsets, nsets, pattern, &err); + + cmp_ctx_t out; + bool ok; + if (err == FcResultMatch) { + if (!cmp_bytes_alloc(&out, 1024)) goto fail2; + ok = encodePattern(&out, res); + ret = cmp_bytes_take(&out, length); + if (!ok && ret != NULL) { free(ret); ret = NULL; } + } else { + if (!cmp_bytes_alloc(&out, 32)) goto fail2; + ok = encodeResult(&out, err); + ret = cmp_bytes_take(&out, length); + if (!ok && ret != NULL) { free(ret); ret = NULL; } + } + +fail2: + if (res != NULL) FcPatternDestroy(res); + FcPatternDestroy(pattern); +fail: + for (size_t i = 0; i < nsets; i++) FcFontSetDestroy(fontsets[i]); + free(fontsets); + return ret; +} + +uint8_t *fcFontSetSort(FcConfig *config, uint8_t *sets, size_t sets_length, + uint8_t *pat, size_t pat_length, bool trim, size_t *length) { + cmp_ctx_t in; + uint8_t *ret = NULL; + + if (!cmp_bytes_init(&in, sets, sets_length)) return NULL; + size_t nsets; + FcFontSet **fontsets = decodeFontSets(&in, &nsets); + cmp_bytes_take(&in, NULL); + if (fontsets == NULL) return NULL; + + if (!cmp_bytes_init(&in, pat, pat_length)) goto fail; + FcPattern *pattern = decodePattern(&in); + cmp_bytes_take(&in, NULL); + if (pattern == NULL) goto fail; + + // Necessary preprocessing! + if (!FcConfigSubstitute(config, pattern, FcMatchPattern)) goto fail2; + FcDefaultSubstitute(pattern); + + FcResult err; + FcCharSet *charset = NULL; + FcFontSet *res = FcFontSetSort(config, fontsets, nsets, pattern, trim, &charset, &err); + + cmp_ctx_t out; + bool ok = true; + switch (err) { + case FcResultMatch: + if (!cmp_bytes_alloc(&out, 1024*res->nfont)) goto fail3; + ok = ok || cmp_write_array(&out, 2); + if (res == NULL) cmp_write_nil(&out); + else { + // FIXME: Postprocess each font! Rather than call encodeFontSet! + ok = ok || encodeFontSet(&out, res); + } + if (charset == NULL) cmp_write_nil(&out); + else ok = ok || encodeCharSet(&out, charset); + break; + case FcResultNoMatch: + if (!cmp_bytes_alloc(&out, 1024)) goto fail3; + ok = ok || cmp_write_array(&out, 2); + ok = ok || cmp_write_array(&out, 0); + if (charset == NULL) cmp_write_nil(&out); + else ok = ok || encodeCharSet(&out, charset); + break; + default: + if (!cmp_bytes_alloc(&out, 32)) goto fail3; + ok = ok || encodeResult(&out, err); + } + ret = cmp_bytes_take(&out, length); + if (!ok && ret != NULL) { free(ret); ret = NULL; } + +fail3: + FcFontSetDestroy(res); + if (charset != NULL) FcCharSetDestroy(charset); +fail2: + FcPatternDestroy(pattern); +fail: + for (size_t i = 0; i < nsets; i++) FcFontSetDestroy(fontsets[i]); + free(fontsets); + return ret; +} + +unsigned int fcFreeTypeCharIndex(FT_Face *face, uint32_t ucs4) { + return FcFreeTypeCharIndex(*face, ucs4); +} + +uint8_t *fcFreeTypeCharSet(FT_Face *face, size_t *length) { + FcCharSet *res = FcFreeTypeCharSet(*face, NULL); + + if (res == NULL) return NULL; + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcCharSetDestroy(res); + return NULL; + } + if (!encodeCharSet(&out, res)) { + FcCharSetDestroy(res); + cmp_bytes_free(&out); + return NULL; + } + FcCharSetDestroy(res); + return cmp_bytes_take(&out, length);; +} + +uint8_t *fcFreeTypeCharSetAndSpacing(FT_Face *face, size_t *length) { + int spacing; + FcCharSet *res = FcFreeTypeCharSetAndSpacing(*face, NULL, &spacing); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcCharSetDestroy(res); + return NULL; + } + if (!cmp_write_array(&out, 2)) goto fail; + switch (spacing) { // This branches ensures a consistant ABI for Haskell to bind against. + case FC_MONO: + if (!cmp_write_integer(&out, 0)) goto fail; + break; + case FC_DUAL: + if (!cmp_write_integer(&out, 1)) goto fail; + break; + case FC_PROPORTIONAL: + if (!cmp_write_integer(&out, 2)) goto fail; + break; + default: + if (!cmp_write_integer(&out, 3)) goto fail; + break; + } + if (!encodeCharSet(&out, res)) goto fail; + FcCharSetDestroy(res); + return cmp_bytes_take(&out, length);; + +fail: + FcCharSetDestroy(res); + cmp_bytes_free(&out); + return NULL; +} + +uint8_t *fcFreeTypeQuery(char *file, int id, size_t *length) { + int count; + FcPattern *res = FcFreeTypeQuery(file, id, NULL, &count); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcPatternDestroy(res); + return NULL; + } + if (!cmp_write_array(&out, 2)) goto fail; + if (!cmp_write_integer(&out, count)) goto fail; + if (!encodePattern(&out, res)) goto fail; + FcPatternDestroy(res); + return cmp_bytes_take(&out, length);; + +fail: + FcPatternDestroy(res); + cmp_bytes_free(&out); + return NULL; +} + +uint8_t *fcFreeTypeQueryAll(char *file, size_t *length) { + int count; + FcFontSet *fontset = FcFontSetCreate(); + if (fontset == NULL) return NULL; + unsigned int npatterns = FcFreeTypeQueryAll(file, -1, NULL, &count, fontset); + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcFontSetDestroy(fontset); + return NULL; + } + if (!cmp_write_array(&out, 3)) goto fail; + if (!cmp_write_integer(&out, npatterns)) goto fail; + if (!cmp_write_integer(&out, count)) goto fail; + if (!encodeFontSet(&out, fontset)) goto fail; + uint8_t *ret = cmp_bytes_take(&out, length); + FcFontSetDestroy(fontset); + return ret; + +fail: + FcFontSetDestroy(fontset); + cmp_bytes_free(&out); + return NULL; +} + +uint8_t *fcFreeTypeQueryFace(FT_Face *face, char *file, int id, size_t *length) { + FcPattern *res = FcFreeTypeQueryFace(*face, file, id, NULL); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcPatternDestroy(res); + return NULL; + } + if (!encodePattern(&out, res)) { + FcPatternDestroy(res); + cmp_bytes_free(&out); + } + uint8_t *ret = cmp_bytes_take(&out, length); + FcPatternDestroy(res); + return ret; +} + +int fcLangSetHasLang(uint8_t *langset, size_t length, const char *lang) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, langset, length)) return -1; + FcLangSet *ls = decodeLangSet(&in); + cmp_bytes_take(&in, NULL); // Caller frees `langset` + if (ls == NULL) return -1; + + FcLangResult ret = FcLangSetHasLang(ls, lang); + FcLangSetDestroy(ls); + switch (ret) { + case FcLangDifferentLang: + return 0; + case FcLangEqual: + return 1; + case FcLangDifferentTerritory: + return 2; + default: + return -2; + } +} + +uint8_t *fcGetDefaultLangs(size_t *length) { + FcStrSet *res = FcGetDefaultLangs(); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcStrSetDestroy(res); + return NULL; + } + if (!encodeStrSet(&out, res)) { + cmp_bytes_free(&out); + FcStrSetDestroy(res); + return NULL; + } + FcStrSetDestroy(res); + return cmp_bytes_take(&out, length); +} + +uint8_t *fcGetLangs(size_t *length) { + FcStrSet *res = FcGetLangs(); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcStrSetDestroy(res); + return NULL; + } + if (!encodeStrSet(&out, res)) { + cmp_bytes_free(&out); + FcStrSetDestroy(res); + return NULL; + } + FcStrSetDestroy(res); + return cmp_bytes_take(&out, length); +} + +char *fcLangNormalize(char *lang) {return FcLangNormalize(lang);} + +uint8_t *fcLangGetCharSet(const char *lang, size_t *length) { + const FcCharSet *res = FcLangGetCharSet(lang); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) return NULL; + if (!encodeCharSet(&out, res)) { + cmp_bytes_free(&out); + return NULL; + } + return cmp_bytes_take(&out, length); +} + +uint8_t *fcConfigGetConfigDirs(FcConfig *conf, size_t *length) { + FcStrList *res = FcConfigGetConfigDirs(conf); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcStrListDone(res); + return NULL; + } + if (!encodeStrList(&out, res)) { + cmp_bytes_free(&out); + FcStrListDone(res); + return NULL; + } + FcStrListDone(res); + return cmp_bytes_take(&out, length); +} + +uint8_t *fcConfigGetFontDirs(FcConfig *conf, size_t *length) { + FcStrList *res = FcConfigGetFontDirs(conf); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcStrListDone(res); + return NULL; + } + if (!encodeStrList(&out, res)) { + cmp_bytes_free(&out); + FcStrListDone(res); + return NULL; + } + FcStrListDone(res); + return cmp_bytes_take(&out, length); +} + +uint8_t *fcConfigGetConfigFiles(FcConfig *conf, size_t *length) { + FcStrList *res = FcConfigGetConfigFiles(conf); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcStrListDone(res); + return NULL; + } + if (!encodeStrList(&out, res)) { + cmp_bytes_free(&out); + FcStrListDone(res); + return NULL; + } + FcStrListDone(res); + return cmp_bytes_take(&out, length); +} + +uint8_t *fcConfigGetCacheDirs(FcConfig *conf, size_t *length) { + FcStrList *res = FcConfigGetCacheDirs(conf); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcStrListDone(res); + return NULL; + } + if (!encodeStrList(&out, res)) { + cmp_bytes_free(&out); + FcStrListDone(res); + return NULL; + } + FcStrListDone(res); + return cmp_bytes_take(&out, length); +} + +uint8_t *fcConfigGetFonts(FcConfig *conf, bool system, size_t *length) { + FcFontSet *res = FcConfigGetFonts(conf, system ? FcSetSystem : FcSetApplication); + if (res == NULL) return NULL; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) { + FcFontSetDestroy(res); + return NULL; + } + if (!encodeFontSet(&out, res)) { + cmp_bytes_free(&out); + FcFontSetDestroy(res); + return NULL; + } + FcFontSetDestroy(res); + return cmp_bytes_take(&out, length); +} + +uint8_t *fcConfigSubstituteWithPat(FcConfig *conf, uint8_t *data, size_t in_length, bool isFont, size_t *length) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, in_length)) return NULL; + + uint32_t size = 0; + if (!cmp_read_array(&in, &size) || size < 1 || size > 2) return NULL; + FcPattern *p = decodePattern(&in); + if (p == NULL) {cmp_bytes_take(&in, NULL); return NULL;} + FcPattern *p_pat = NULL; + if (size == 2) { + p_pat = decodePattern(&in); + if (p_pat == NULL) {cmp_bytes_take(&in, NULL); goto fail;} + } + cmp_bytes_take(&in, NULL); + + if (!FcConfigSubstituteWithPat(conf, p, p_pat, isFont ? FcMatchFont : FcMatchPattern)) goto fail; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) goto fail; + if (!encodePattern(&out, p)) goto fail; + FcPatternDestroy(p); + if (p_pat != NULL) FcPatternDestroy(p_pat); + return cmp_bytes_take(&out, length); + +fail: + FcPatternDestroy(p); + if (p_pat != NULL) FcPatternDestroy(p_pat); + return NULL; +} + +uint8_t *fcFontMatch(FcConfig *conf, uint8_t *data, size_t in_length, size_t *length) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, in_length)) return NULL; + FcPattern *p = decodePattern(&in); + cmp_bytes_take(&in, NULL); + if (p == NULL) return NULL; + + if (!FcConfigSubstitute(conf, p, FcMatchPattern)) goto fail; + FcDefaultSubstitute(p); + + FcResult err; + FcPattern *res = FcFontMatch(conf, p, &err); + if (res == NULL) goto fail; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) goto fail; + if (err != FcResultMatch) { + if (!encodeResult(&out, err)) goto fail2; + } else { + if (!encodePattern(&out, res)) goto fail2; + } + FcPatternDestroy(p); + return cmp_bytes_take(&out, length);; + +fail2: + cmp_bytes_free(&out); +fail: + FcPatternDestroy(p); + return NULL; +} + +uint8_t *fcFontSort(FcConfig *conf, uint8_t *data, size_t in_length, bool trim, size_t *length) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, in_length)) return NULL; + FcPattern *p = decodePattern(&in); + cmp_bytes_take(&in, NULL); + if (p == NULL) return NULL; + + if (!FcConfigSubstitute(conf, p, FcMatchPattern)) goto fail; + FcDefaultSubstitute(p); + + FcResult err; + FcCharSet *csp; + FcFontSet *res = FcFontSort(conf, p, trim, &csp, &err); + if (res == NULL) goto fail2; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) goto fail2; + if (err != FcResultMatch) { + if (!encodeResult(&out, err)) goto fail3; + } else if (csp != NULL) { + if (!cmp_write_array(&out, 2)) goto fail3; + if (!encodeFontSet(&out, res)) goto fail3; + if (!encodeCharSet(&out, csp)) goto fail3; + } else { + if (!cmp_write_array(&out, 1)) goto fail3; + if (!encodeFontSet(&out, res)) goto fail3; + } + FcPatternDestroy(p); + if (csp != NULL) FcCharSetDestroy(csp); + return cmp_bytes_take(&out, length); + +fail3: + cmp_bytes_free(&out); +fail2: + if (csp != NULL) FcCharSetDestroy(csp); +fail: + FcPatternDestroy(p); + return NULL; +} + +uint8_t *fcFontRenderPrepare(FcConfig *conf, uint8_t *data, size_t in_length, size_t *length) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, in_length)) return NULL; + uint32_t size = 0; + if (!cmp_read_array(&in, &size) || size != 2) return NULL; + FcPattern *pat = decodePattern(&in); + if (pat == NULL) {cmp_bytes_take(&in, NULL); return NULL;} + FcPattern *font = decodePattern(&in); + cmp_bytes_take(&in, NULL); + if (font == NULL) {FcPatternDestroy(pat); return NULL; } + + FcPattern *res = FcFontRenderPrepare(conf, pat, font); + if (res == NULL) goto fail0; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) goto fail; + if (!encodePattern(&out, res)) {cmp_bytes_free(&out); goto fail;} + FcPatternDestroy(pat); + FcPatternDestroy(font); + FcPatternDestroy(res); + return cmp_bytes_take(&out, length); + +fail: + FcPatternDestroy(res); +fail0: + FcPatternDestroy(pat); + FcPatternDestroy(font); + return NULL; +} + +uint8_t *fcFontList(FcConfig *conf, uint8_t *data, size_t in_length, size_t *length) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, in_length)) return NULL; + uint32_t size = 0; + if (!cmp_read_array(&in, &size) || size != 2) { + cmp_bytes_take(&in, NULL); + return NULL; + } + FcPattern *pat = decodePattern(&in); + if (pat == NULL) {cmp_bytes_take(&in, NULL); return NULL;} + FcObjectSet *os = decodeObjectSet(&in); + cmp_bytes_take(&in, NULL); + if (os == NULL) {FcPatternDestroy(pat); return NULL;} + + FcFontSet *res = FcFontList(conf, pat, os); + if (res == NULL) goto fail0; + + cmp_ctx_t out; + if (!cmp_bytes_alloc(&out, 1024)) goto fail; + if (!encodeFontSet(&out, res)) { cmp_bytes_free(&out); goto fail;} + FcFontSetDestroy(res); + return cmp_bytes_take(&out, length); + +fail: + FcFontSetDestroy(res); +fail0: + FcPatternDestroy(pat); + FcObjectSetDestroy(os); + return NULL; +} + +/*int fcConfigAcceptFont(FcConfig *conf, uint8_t *data, size_t length) { + cmp_ctx_t in; + if (!cmp_bytes_init(&in, data, length)) return -1; + FcPattern *pat = decodePattern(&in); + if (pat == NULL) return -1; + + FcBool ret = FcConfigAcceptFont(conf, pat); + FcPatternDestroy(pat); + return ret ? 1 : 0; +}*/ diff --git a/cbits/transcode.c b/cbits/transcode.c index 1a71cc8..1106aac 100644 --- a/cbits/transcode.c +++ b/cbits/transcode.c @@ -46,26 +46,28 @@ fail: return NULL; } -bool encodeStrSet(cmp_ctx_t *bytes, FcStrSet *data) { - if (bytes == NULL || data == NULL) return false; - bool ret = false; - - FcStrList *iter = FcStrListCreate(data); - if (iter == NULL) return false; - +bool encodeStrList(cmp_ctx_t *bytes, FcStrList *iter) { uint32_t size = 0; FcStrListFirst(iter); while (FcStrListNext(iter) != NULL) size++; - if (!cmp_write_array(bytes, size)) goto exit; + if (!cmp_write_array(bytes, size)) return false; FcStrListFirst(iter); char *text = FcStrListNext(iter); while (text != NULL) { - if (!cmp_write_str(bytes, text, strlen(text))) goto exit; + if (!cmp_write_str(bytes, text, strlen(text))) return false; text = FcStrListNext(iter); } - ret = true; -exit: + return true; +} + +bool encodeStrSet(cmp_ctx_t *bytes, FcStrSet *data) { + if (bytes == NULL || data == NULL) return false; + + FcStrList *iter = FcStrListCreate(data); + if (iter == NULL) return false; + + bool ret = encodeStrList(bytes, iter); FcStrListDone(iter); return ret; } diff --git a/cbits/transcode.h b/cbits/transcode.h new file mode 100644 index 0000000..ea23a74 --- /dev/null +++ b/cbits/transcode.h @@ -0,0 +1,29 @@ +#include "cmp.h" +#include + +FcStrSet *decodeStrSet(cmp_ctx_t *bytes); +FcStrSet *decodeFileSet(cmp_ctx_t *bytes); +bool encodeStrSet(cmp_ctx_t *bytes, FcStrSet *data); +FcCharSet *decodeCharSet(cmp_ctx_t *bytes); +bool encodeStrList(cmp_ctx_t *bytes, const FcStrList *data); +bool encodeCharSet(cmp_ctx_t *bytes, const FcCharSet *data); +FcLangSet *decodeLangSet(cmp_ctx_t *bytes); +bool encodeLangSet(cmp_ctx_t *bytes, const FcLangSet *data); +FcObjectSet *decodeObjectSet(cmp_ctx_t *bytes); +FcRange *decodeRange(cmp_ctx_t *bytes); +bool encodeRange(cmp_ctx_t *bytes, const FcRange *data); +FcMatrix *decodeMatrix(cmp_ctx_t *bytes); +bool encodeMatrix(cmp_ctx_t *bytes, const FcMatrix *data); +bool decodeValue(cmp_ctx_t *bytes, FcValue *out); +bool encodeValue(cmp_ctx_t *bytes, FcValue *data); +FcPattern *decodePattern(cmp_ctx_t *bytes); +bool encodePattern(cmp_ctx_t *bytes, FcPattern *data); +FcFontSet *decodeFontSet(cmp_ctx_t *bytes); +FcFontSet **decodeFontSets(cmp_ctx_t *bytes, size_t *nsets); +bool encodeFontSet(cmp_ctx_t *bytes, FcFontSet *data); +bool encodeResult(cmp_ctx_t *bytes, FcResult res); + +bool cmp_bytes_init(cmp_ctx_t *ctx, uint8_t *buf, size_t length); +bool cmp_bytes_alloc(cmp_ctx_t *ctx, size_t length); +void cmp_bytes_free(cmp_ctx_t *ctx); +uint8_t *cmp_bytes_take(cmp_ctx_t *ctx, size_t *length); diff --git a/fontconfig-pure.cabal b/fontconfig-pure.cabal index cde47f5..888a5b9 100644 --- a/fontconfig-pure.cabal +++ b/fontconfig-pure.cabal @@ -70,6 +70,8 @@ library c-sources: cbits/cmp.c, cbits/transcode.c, cbits/freetype-wrap.c + pkgconfig-depends: fontconfig + -- Modules included in this library but not exported. -- other-modules: -- 2.30.2