void FcObjectSetDestroy (FcObjectSet *os) { if (os->objects) { FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *)); free ((void *) os->objects); } FcMemFree (FC_MEM_OBJECTSET, sizeof (FcObjectSet)); free (os); }
void FcBlanksDestroy (FcBlanks *b) { if (b->blanks) { FcMemFree (FC_MEM_BLANKS, b->sblank * sizeof (FcChar32)); free (b->blanks); } FcMemFree (FC_MEM_BLANKS, sizeof (FcBlanks)); free (b); }
void FcFontSetDestroy (FcFontSet *s) { int i; for (i = 0; i < s->nfont; i++) FcPatternDestroy (s->fonts[i]); if (s->fonts) { FcMemFree (FC_MEM_FONTPTR, s->sfont * sizeof (FcPattern *)); free (s->fonts); } FcMemFree (FC_MEM_FONTSET, sizeof (FcFontSet)); free (s); }
void FcObjectSetDestroy (FcObjectSet *os) { int i; if (os->objects) { for (i = 0; i < os->nobject; i++) FcSharedStrFree ((FcChar8 *)os->objects[i]); FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *)); free ((void *) os->objects); } FcMemFree (FC_MEM_OBJECTSET, sizeof (FcObjectSet)); free (os); }
static FcValueList * FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) { FcValueList *l; if (!e) return 0; l = (FcValueList *) malloc (sizeof (FcValueList)); if (!l) return 0; FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList)); if (e->op == FcOpComma) { l->value = FcConfigEvaluate (p, e->u.tree.left); l->next = FcConfigValues (p, e->u.tree.right, binding); } else { l->value = FcConfigEvaluate (p, e); l->next = NULL; } l->binding = binding; if (l->value.type == FcTypeVoid) { FcValueList *next = FcValueListNext(l); FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); free (l); l = next; } return l; }
FcBool FcBlanksAdd (FcBlanks *b, FcChar32 ucs4) { FcChar32 *c; int sblank; for (sblank = 0; sblank < b->nblank; sblank++) if (b->blanks[sblank] == ucs4) return FcTrue; if (b->nblank == b->sblank) { sblank = b->sblank + 32; if (b->blanks) c = (FcChar32 *) realloc (b->blanks, sblank * sizeof (FcChar32)); else c = (FcChar32 *) malloc (sblank * sizeof (FcChar32)); if (!c) return FcFalse; if (b->sblank) FcMemFree (FC_MEM_BLANKS, b->sblank * sizeof (FcChar32)); FcMemAlloc (FC_MEM_BLANKS, sblank * sizeof (FcChar32)); b->sblank = sblank; b->blanks = c; } b->blanks[b->nblank++] = ucs4; return FcTrue; }
void FcLangSetDestroy (FcLangSet *ls) { if (ls->extra) FcStrSetDestroy (ls->extra); FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet)); free (ls); }
void FcMatrixFree (FcMatrix *mat) { if (mat != &FcIdentityMatrix) { FcMemFree (FC_MEM_MATRIX, sizeof (FcMatrix)); free (mat); } }
void FcConfigDestroy (FcConfig *config) { FcSetName set; FcExprPage *page; if (--config->ref > 0) return; if (config == _fcConfig) _fcConfig = 0; FcStrSetDestroy (config->configDirs); FcStrSetDestroy (config->fontDirs); FcStrSetDestroy (config->cacheDirs); FcStrSetDestroy (config->configFiles); FcStrSetDestroy (config->acceptGlobs); FcStrSetDestroy (config->rejectGlobs); FcFontSetDestroy (config->acceptPatterns); FcFontSetDestroy (config->rejectPatterns); if (config->blanks) FcBlanksDestroy (config->blanks); FcSubstDestroy (config->substPattern); FcSubstDestroy (config->substFont); FcSubstDestroy (config->substScan); for (set = FcSetSystem; set <= FcSetApplication; set++) if (config->fonts[set]) FcFontSetDestroy (config->fonts[set]); page = config->expr_pool; while (page) { FcExprPage *next = page->next_page; FcMemFree (FC_MEM_EXPR, sizeof (FcExprPage)); free (page); page = next; } free (config); FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig)); }
FcBool FcObjectSetAdd (FcObjectSet *os, const char *object) { int s; const char **objects; int high, low, mid, c; if (os->nobject == os->sobject) { s = os->sobject + 4; if (os->objects) objects = (const char **) realloc ((void *) os->objects, s * sizeof (const char *)); else objects = (const char **) malloc (s * sizeof (const char *)); if (!objects) return FcFalse; if (os->sobject) FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *)); FcMemAlloc (FC_MEM_OBJECTPTR, s * sizeof (const char *)); os->objects = objects; os->sobject = s; } high = os->nobject - 1; low = 0; mid = 0; c = 1; object = (char *)FcSharedStr ((FcChar8 *)object); while (low <= high) { mid = (low + high) >> 1; c = os->objects[mid] - object; if (c == 0) { FcSharedStrFree ((FcChar8 *)object); return FcTrue; } if (c < 0) low = mid + 1; else high = mid - 1; } if (c < 0) mid++; memmove (os->objects + mid + 1, os->objects + mid, (os->nobject - mid) * sizeof (const char *)); os->objects[mid] = object; os->nobject++; return FcTrue; }
static void FcSubstDestroy (FcSubst *s) { FcSubst *n; while (s) { n = s->next; if (s->test) FcTestDestroy (s->test); if (s->edit) FcEditDestroy (s->edit); free (s); FcMemFree (FC_MEM_SUBST, sizeof (FcSubst)); s = n; } }
static void FcListHashTableCleanup (FcListHashTable *table) { int i; FcListBucket *bucket, *next; for (i = 0; i < FC_LIST_HASH_SIZE; i++) { for (bucket = table->buckets[i]; bucket; bucket = next) { next = bucket->next; FcPatternDestroy (bucket->pattern); FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); } table->buckets[i] = 0; } table->entries = 0; }
FcBool FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) { const FcObjectTypeList *l, **prev; for (prev = &_FcObjectTypes; (l = *prev); prev = (const FcObjectTypeList **) &(l->next)) { if (l->types == types && l->ntypes == ntypes) { *prev = l->next; FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList)); free ((void *) l); return FcTrue; } } return FcFalse; }
FcBool FcNameUnregisterConstants (const FcConstant *consts, int nconsts) { const FcConstantList *l, **prev; for (prev = &_FcConstants; (l = *prev); prev = (const FcConstantList **) &(l->next)) { if (l->consts == consts && l->nconsts == nconsts) { *prev = l->next; FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList)); free ((void *) l); return FcTrue; } } return FcFalse; }
FcBool FcFontSetAdd (FcFontSet *s, FcPattern *font) { FcPattern **f; int sfont; if (s->nfont == s->sfont) { sfont = s->sfont + 32; if (s->fonts) f = (FcPattern **) realloc (s->fonts, sfont * sizeof (FcPattern *)); else f = (FcPattern **) malloc (sfont * sizeof (FcPattern *)); if (!f) return FcFalse; if (s->sfont) FcMemFree (FC_MEM_FONTPTR, s->sfont * sizeof (FcPattern *)); FcMemAlloc (FC_MEM_FONTPTR, sfont * sizeof (FcPattern *)); s->sfont = sfont; s->fonts = f; } s->fonts[s->nfont++] = font; return FcTrue; }
FcConfig * FcConfigCreate (void) { FcSetName set; FcConfig *config; config = malloc (sizeof (FcConfig)); if (!config) goto bail0; FcMemAlloc (FC_MEM_CONFIG, sizeof (FcConfig)); config->configDirs = FcStrSetCreate (); if (!config->configDirs) goto bail1; config->configFiles = FcStrSetCreate (); if (!config->configFiles) goto bail2; config->fontDirs = FcStrSetCreate (); if (!config->fontDirs) goto bail3; config->acceptGlobs = FcStrSetCreate (); if (!config->acceptGlobs) goto bail4; config->rejectGlobs = FcStrSetCreate (); if (!config->rejectGlobs) goto bail5; config->acceptPatterns = FcFontSetCreate (); if (!config->acceptPatterns) goto bail6; config->rejectPatterns = FcFontSetCreate (); if (!config->rejectPatterns) goto bail7; config->cacheDirs = FcStrSetCreate (); if (!config->cacheDirs) goto bail8; config->blanks = 0; config->substPattern = 0; config->substFont = 0; config->substScan = 0; config->maxObjects = 0; for (set = FcSetSystem; set <= FcSetApplication; set++) config->fonts[set] = 0; config->rescanTime = time(0); config->rescanInterval = 30; config->expr_pool = NULL; config->ref = 1; return config; bail8: FcFontSetDestroy (config->rejectPatterns); bail7: FcFontSetDestroy (config->acceptPatterns); bail6: FcStrSetDestroy (config->rejectGlobs); bail5: FcStrSetDestroy (config->acceptGlobs); bail4: FcStrSetDestroy (config->fontDirs); bail3: FcStrSetDestroy (config->configFiles); bail2: FcStrSetDestroy (config->configDirs); bail1: free (config); FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig)); bail0: return 0; }
void FcStrFree (FcChar8 *s) { FcMemFree (FC_MEM_STRING, strlen ((char *) s) + 1); free (s); }
FcFontSet * FcFontSetList (FcConfig *config, FcFontSet **sets, int nsets, FcPattern *p, FcObjectSet *os) { FcFontSet *ret; FcFontSet *s; int f; int set; FcListHashTable table; int i; FcListBucket *bucket; int destroy_os = 0; if (!config) { if (!FcInitBringUptoDate ()) goto bail0; config = FcConfigGetCurrent (); if (!config) goto bail0; } FcListHashTableInit (&table); if (!os) { os = FcObjectGetSet (); destroy_os = 1; } /* * Walk all available fonts adding those that * match to the hash table */ for (set = 0; set < nsets; set++) { s = sets[set]; if (!s) continue; for (f = 0; f < s->nfont; f++) if (FcListPatternMatchAny (p, /* pattern */ s->fonts[f])) /* font */ { FcChar8 *lang; if (FcPatternObjectGetString (p, FC_NAMELANG_OBJECT, 0, &lang) != FcResultMatch) { lang = FcGetDefaultLang (); } if (!FcListAppend (&table, s->fonts[f], os, lang)) goto bail1; } } #if 0 { int max = 0; int full = 0; int ents = 0; int len; for (i = 0; i < FC_LIST_HASH_SIZE; i++) { if ((bucket = table.buckets[i])) { len = 0; for (; bucket; bucket = bucket->next) { ents++; len++; } if (len > max) max = len; full++; } } printf ("used: %d max: %d avg: %g\n", full, max, (double) ents / FC_LIST_HASH_SIZE); } #endif /* * Walk the hash table and build * a font set */ ret = FcFontSetCreate (); if (!ret) goto bail0; for (i = 0; i < FC_LIST_HASH_SIZE; i++) while ((bucket = table.buckets[i])) { if (!FcFontSetAdd (ret, bucket->pattern)) goto bail2; table.buckets[i] = bucket->next; FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); } return ret; bail2: FcFontSetDestroy (ret); bail1: FcListHashTableCleanup (&table); bail0: if (destroy_os) FcObjectSetDestroy (os); return 0; }
static FcBool FcListAppend (FcListHashTable *table, FcPattern *font, FcObjectSet *os, const FcChar8 *lang) { int o; FcPatternElt *e; FcValueListPtr v; FcChar32 hash; FcListBucket **prev, *bucket; int familyidx = -1; int fullnameidx = -1; int styleidx = -1; int defidx = 0; int idx; hash = FcListPatternHash (font, os); for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE]; (bucket = *prev); prev = &(bucket->next)) { if (bucket->hash == hash && FcListPatternEqual (bucket->pattern, font, os)) return FcTrue; } bucket = (FcListBucket *) malloc (sizeof (FcListBucket)); if (!bucket) goto bail0; FcMemAlloc (FC_MEM_LISTBUCK, sizeof (FcListBucket)); bucket->next = 0; bucket->hash = hash; bucket->pattern = FcPatternCreate (); if (!bucket->pattern) goto bail1; for (o = 0; o < os->nobject; o++) { if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG)) { if (familyidx < 0) familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT, lang); defidx = familyidx; } else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG)) { if (fullnameidx < 0) fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT, lang); defidx = fullnameidx; } else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG)) { if (styleidx < 0) styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT, lang); defidx = styleidx; } else defidx = 0; e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o])); if (e) { for (v = FcPatternEltValues(e), idx = 0; v; v = FcValueListNext(v), ++idx) { if (!FcPatternAdd (bucket->pattern, os->objects[o], FcValueCanonicalize(&v->value), defidx != idx)) goto bail2; } } } *prev = bucket; ++table->entries; return FcTrue; bail2: FcPatternDestroy (bucket->pattern); bail1: FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); bail0: return FcFalse; }