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; }
FcMatrix * FcMatrixCopy (const FcMatrix *mat) { FcMatrix *r; if(!mat) return 0; r = (FcMatrix *) malloc (sizeof (*r) ); if (!r) return 0; FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix)); *r = *mat; return r; }
FcLangSet * FcLangSetCreate (void) { FcLangSet *ls; ls = malloc (sizeof (FcLangSet)); if (!ls) return 0; FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet)); memset (ls->map, '\0', sizeof (ls->map)); ls->extra = 0; return ls; }
FcObjectSet * FcObjectSetCreate (void) { FcObjectSet *os; os = (FcObjectSet *) malloc (sizeof (FcObjectSet)); if (!os) return 0; FcMemAlloc (FC_MEM_OBJECTSET, sizeof (FcObjectSet)); os->nobject = 0; os->sobject = 0; os->objects = 0; return os; }
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; }
FcBlanks * FcBlanksCreate (void) { FcBlanks *b; b = malloc (sizeof (FcBlanks)); if (!b) return 0; FcMemAlloc (FC_MEM_BLANKS, sizeof (FcBlanks)); b->nblank = 0; b->sblank = 0; b->blanks = 0; return b; }
FcFontSet * FcFontSetCreate (void) { FcFontSet *s; s = (FcFontSet *) malloc (sizeof (FcFontSet)); if (!s) return 0; FcMemAlloc (FC_MEM_FONTSET, sizeof (FcFontSet)); s->nfont = 0; s->sfont = 0; s->fonts = 0; return s; }
FcBool FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes) { FcObjectTypeList *l; l = (FcObjectTypeList *) malloc (sizeof (FcObjectTypeList)); if (!l) return FcFalse; FcMemAlloc (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList)); l->types = types; l->ntypes = ntypes; l->next = _FcObjectTypes; _FcObjectTypes = l; return FcTrue; }
FcBool FcNameRegisterConstants (const FcConstant *consts, int nconsts) { FcConstantList *l; l = (FcConstantList *) malloc (sizeof (FcConstantList)); if (!l) return FcFalse; FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList)); l->consts = consts; l->nconsts = nconsts; l->next = _FcConstants; _FcConstants = l; return FcTrue; }
FcChar8 * FcStrPlus (const FcChar8 *s1, const FcChar8 *s2) { int s1l = strlen ((char *) s1); int s2l = strlen ((char *) s2); int l = s1l + s2l + 1; FcChar8 *s = malloc (l); if (!s) return 0; FcMemAlloc (FC_MEM_STRING, l); memcpy (s, s1, s1l); memcpy (s + s1l, s2, s2l + 1); return s; }
FcBool FcConfigAddEdit (FcConfig *config, FcTest *test, FcEdit *edit, FcMatchKind kind) { FcSubst *subst, **prev; FcTest *t; int num; switch (kind) { case FcMatchPattern: prev = &config->substPattern; break; case FcMatchFont: prev = &config->substFont; break; case FcMatchScan: prev = &config->substScan; break; default: return FcFalse; } subst = (FcSubst *) malloc (sizeof (FcSubst)); if (!subst) return FcFalse; FcMemAlloc (FC_MEM_SUBST, sizeof (FcSubst)); for (; *prev; prev = &(*prev)->next); *prev = subst; subst->next = 0; subst->test = test; subst->edit = edit; num = 0; for (t = test; t; t = t->next) { if (t->kind == FcMatchDefault) t->kind = kind; num++; } if (config->maxObjects < num) config->maxObjects = num; if (FcDebug () & FC_DBG_EDIT) { printf ("Add Subst "); FcSubstPrint (subst); } return FcTrue; }
FcChar8 * FcStrCopy (const FcChar8 *s) { int len; FcChar8 *r; if (!s) return 0; len = strlen ((char *) s) + 1; r = (FcChar8 *) malloc (len); if (!r) return 0; FcMemAlloc (FC_MEM_STRING, len); memcpy (r, s, len); return r; }
FcExpr * FcConfigAllocExpr (FcConfig *config) { if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end) { FcExprPage *new_page; new_page = malloc (sizeof (FcExprPage)); if (!new_page) return 0; FcMemAlloc (FC_MEM_EXPR, sizeof (FcExprPage)); new_page->next_page = config->expr_pool; new_page->next = new_page->exprs; config->expr_pool = new_page; } return config->expr_pool->next++; }
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; }
static FcValue FcConfigEvaluate (FcPattern *p, FcExpr *e) { FcValue v, vl, vr; FcResult r; FcMatrix *m; FcChar8 *str; switch (e->op) { case FcOpInteger: v.type = FcTypeInteger; v.u.i = e->u.ival; break; case FcOpDouble: v.type = FcTypeDouble; v.u.d = e->u.dval; break; case FcOpString: v.type = FcTypeString; v.u.s = e->u.sval; v = FcValueSave (v); break; case FcOpMatrix: v.type = FcTypeMatrix; v.u.m = e->u.mval; v = FcValueSave (v); break; case FcOpCharSet: v.type = FcTypeCharSet; v.u.c = e->u.cval; v = FcValueSave (v); break; case FcOpBool: v.type = FcTypeBool; v.u.b = e->u.bval; break; case FcOpField: r = FcPatternObjectGet (p, e->u.object, 0, &v); if (r != FcResultMatch) v.type = FcTypeVoid; v = FcValueSave (v); break; case FcOpConst: if (FcNameConstant (e->u.constant, &v.u.i)) v.type = FcTypeInteger; else v.type = FcTypeVoid; break; case FcOpQuest: vl = FcConfigEvaluate (p, e->u.tree.left); if (vl.type == FcTypeBool) { if (vl.u.b) v = FcConfigEvaluate (p, e->u.tree.right->u.tree.left); else v = FcConfigEvaluate (p, e->u.tree.right->u.tree.right); } else v.type = FcTypeVoid; FcValueDestroy (vl); break; case FcOpEqual: case FcOpNotEqual: case FcOpLess: case FcOpLessEqual: case FcOpMore: case FcOpMoreEqual: case FcOpContains: case FcOpNotContains: case FcOpListing: vl = FcConfigEvaluate (p, e->u.tree.left); vr = FcConfigEvaluate (p, e->u.tree.right); v.type = FcTypeBool; v.u.b = FcConfigCompareValue (&vl, e->op, &vr); FcValueDestroy (vl); FcValueDestroy (vr); break; case FcOpOr: case FcOpAnd: case FcOpPlus: case FcOpMinus: case FcOpTimes: case FcOpDivide: vl = FcConfigEvaluate (p, e->u.tree.left); vr = FcConfigEvaluate (p, e->u.tree.right); vl = FcConfigPromote (vl, vr); vr = FcConfigPromote (vr, vl); if (vl.type == vr.type) { switch (vl.type) { case FcTypeDouble: switch (e->op) { case FcOpPlus: v.type = FcTypeDouble; v.u.d = vl.u.d + vr.u.d; break; case FcOpMinus: v.type = FcTypeDouble; v.u.d = vl.u.d - vr.u.d; break; case FcOpTimes: v.type = FcTypeDouble; v.u.d = vl.u.d * vr.u.d; break; case FcOpDivide: v.type = FcTypeDouble; v.u.d = vl.u.d / vr.u.d; break; default: v.type = FcTypeVoid; break; } if (v.type == FcTypeDouble && v.u.d == (double) (int) v.u.d) { v.type = FcTypeInteger; v.u.i = (int) v.u.d; } break; case FcTypeBool: switch (e->op) { case FcOpOr: v.type = FcTypeBool; v.u.b = vl.u.b || vr.u.b; break; case FcOpAnd: v.type = FcTypeBool; v.u.b = vl.u.b && vr.u.b; break; default: v.type = FcTypeVoid; break; } break; case FcTypeString: switch (e->op) { case FcOpPlus: v.type = FcTypeString; str = FcStrPlus (vl.u.s, vr.u.s); v.u.s = FcStrStaticName (str); FcStrFree (str); if (!v.u.s) v.type = FcTypeVoid; break; default: v.type = FcTypeVoid; break; } break; case FcTypeMatrix: switch (e->op) { case FcOpTimes: v.type = FcTypeMatrix; m = malloc (sizeof (FcMatrix)); if (m) { FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix)); FcMatrixMultiply (m, vl.u.m, vr.u.m); v.u.m = m; } else { v.type = FcTypeVoid; } break; default: v.type = FcTypeVoid; break; } break; default: v.type = FcTypeVoid; break; } } else v.type = FcTypeVoid; FcValueDestroy (vl); FcValueDestroy (vr); break; case FcOpNot: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeBool: v.type = FcTypeBool; v.u.b = !vl.u.b; break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpFloor: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleFloor (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpCeil: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleCeil (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpRound: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleRound (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpTrunc: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleTrunc (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; default: v.type = FcTypeVoid; break; } return v; }
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; }
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; }