void FcDefaultSubstitute (FcPattern *pattern) { FcValue v; int i; if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch ) FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_MEDIUM); if (FcPatternObjectGet (pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch) FcPatternObjectAddInteger (pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN); if (FcPatternObjectGet (pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch) FcPatternObjectAddInteger (pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL); for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++) if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch) FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value); if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch) { double dpi, size, scale; if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch) { size = 12.0; (void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT); FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size); } if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch) { scale = 1.0; (void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT); FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale); } size *= scale; if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch) { dpi = 75.0; (void) FcPatternObjectDel (pattern, FC_DPI_OBJECT); FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi); } size *= dpi / 72.0; FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size); } if (FcPatternObjectGet (pattern, FC_LANG_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAddString (pattern, FC_LANG_OBJECT, FcGetDefaultLang ()); } if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT, 0x7fffffff); } if (FcPatternObjectGet (pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL); } }
void FcDefaultSubstitute(FcPattern *pattern) { FcValue v, namelang, v2; int i; if (FcPatternObjectGet(pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch) FcPatternObjectAddInteger(pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_NORMAL); if (FcPatternObjectGet(pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch) FcPatternObjectAddInteger(pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN); if (FcPatternObjectGet(pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch) FcPatternObjectAddInteger(pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL); for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++) if (FcPatternObjectGet(pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch) FcPatternObjectAddBool(pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value); if (FcPatternObjectGet(pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch) { double dpi, size, scale; if (FcPatternObjectGetDouble(pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch) { size = 12.0; (void)FcPatternObjectDel(pattern, FC_SIZE_OBJECT); FcPatternObjectAddDouble(pattern, FC_SIZE_OBJECT, size); } if (FcPatternObjectGetDouble(pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch) { scale = 1.0; (void)FcPatternObjectDel(pattern, FC_SCALE_OBJECT); FcPatternObjectAddDouble(pattern, FC_SCALE_OBJECT, scale); } size *= scale; if (FcPatternObjectGetDouble(pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch) { dpi = 75.0; (void)FcPatternObjectDel(pattern, FC_DPI_OBJECT); FcPatternObjectAddDouble(pattern, FC_DPI_OBJECT, dpi); } size *= dpi / 72.0; FcPatternObjectAddDouble(pattern, FC_PIXEL_SIZE_OBJECT, size); } if (FcPatternObjectGet(pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAddInteger(pattern, FC_FONTVERSION_OBJECT, 0x7fffffff); } if (FcPatternObjectGet(pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAddInteger(pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL); } if (FcPatternObjectGet(pattern, FC_NAMELANG_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAddString(pattern, FC_NAMELANG_OBJECT, FcGetDefaultLang()); } /* shouldn't be failed. */ FcPatternObjectGet(pattern, FC_NAMELANG_OBJECT, 0, &namelang); /* Add a fallback to ensure the english name when the requested language * isn't available. this would helps for the fonts that have non-English * name at the beginning. */ /* Set "en-us" instead of "en" to avoid giving higher score to "en". * This is a hack for the case that the orth is not like ll-cc, because, * if no namelang isn't explicitly set, it will has something like ll-cc * according to current locale. which may causes FcLangDifferentTerritory * at FcLangCompare(). thus, the English name is selected so that * exact matched "en" has higher score than ll-cc. */ v2.type = FcTypeString; v2.u.s = (FcChar8 *)"en-us"; if (FcPatternObjectGet(pattern, FC_FAMILYLANG_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAdd(pattern, FC_FAMILYLANG_OBJECT, namelang, FcTrue); FcPatternObjectAddWithBinding(pattern, FC_FAMILYLANG_OBJECT, v2, FcValueBindingWeak, FcTrue); } if (FcPatternObjectGet(pattern, FC_STYLELANG_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAdd(pattern, FC_STYLELANG_OBJECT, namelang, FcTrue); FcPatternObjectAddWithBinding(pattern, FC_STYLELANG_OBJECT, v2, FcValueBindingWeak, FcTrue); } if (FcPatternObjectGet(pattern, FC_FULLNAMELANG_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAdd(pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue); FcPatternObjectAddWithBinding(pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue); } if (FcPatternObjectGet(pattern, FC_PRGNAME_OBJECT, 0, &v) == FcResultNoMatch) { FcChar8 *prgname = FcGetPrgname(); if (prgname) FcPatternObjectAddString(pattern, FC_PRGNAME_OBJECT, prgname); } }
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; }