diff options
-rw-r--r-- | fontconfig/fontconfig.h | 2 | ||||
-rw-r--r-- | fonts.dtd | 6 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/fccfg.c | 71 | ||||
-rw-r--r-- | src/fcdbg.c | 20 | ||||
-rw-r--r-- | src/fcint.h | 3 | ||||
-rw-r--r-- | src/fcxml.c | 107 |
7 files changed, 187 insertions, 24 deletions
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index ca40834..2a26fa8 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -108,7 +108,9 @@ typedef int FcBool; #define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD #define FC_WEIGHT_BOLD 200 #define FC_WEIGHT_EXTRABOLD 205 +#define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD #define FC_WEIGHT_BLACK 210 +#define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK #define FC_SLANT_ROMAN 0 #define FC_SLANT_ITALIC 100 @@ -91,7 +91,7 @@ <!ENTITY % expr 'int|double|string|matrix|bool|charset |name|const |or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains - |plus|minus|times|divide|not|if'> + |plus|minus|times|divide|not|if|floor|ceil|round|trunc'> <!-- Match and edit patterns. @@ -180,3 +180,7 @@ <!ELEMENT divide (%expr;)*> <!ELEMENT not (%expr;)> <!ELEMENT if ((%expr;), (%expr;), (%expr;))> +<!ELEMENT floor (%expr;)> +<!ELEMENT ceil (%expr;)> +<!ELEMENT round (%expr;)> +<!ELEMENT trunc (%expr;)> diff --git a/src/Makefile.am b/src/Makefile.am index 949c5a3..bb52282 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,7 +49,7 @@ INCLUDES = \ EXTRA_DIST = fontconfig.def.in -noinst_HEADERS=fcint.h +noinst_HEADERS=fcint.h data.h libfontconfig_la_SOURCES = \ fcatomic.c \ diff --git a/src/fccfg.c b/src/fccfg.c index a8f10b9..68b548f 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -648,6 +648,13 @@ FcConfigCompareValue (const FcValue m_o, } +#define _FcDoubleFloor(d) ((int) (d)) +#define _FcDoubleCeil(d) ((double) (int) (d) == (d) ? (int) (d) : (int) ((d) + 1)) +#define FcDoubleFloor(d) ((d) >= 0 ? _FcDoubleFloor(d) : -_FcDoubleCeil(-(d))) +#define FcDoubleCeil(d) ((d) >= 0 ? _FcDoubleCeil(d) : -_FcDoubleFloor(-(d))) +#define FcDoubleRound(d) FcDoubleFloor ((d) + 0.5) +#define FcDoubleTrunc(d) ((d) >= 0 ? _FcDoubleFloor (d) : -_FcDoubleFloor (-(d))) + static FcValue FcConfigEvaluate (FcPattern *p, FcExpr *e) { @@ -836,6 +843,70 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) } 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; diff --git a/src/fcdbg.c b/src/fcdbg.c index 1b6ca41..8d4439b 100644 --- a/src/fcdbg.c +++ b/src/fcdbg.c @@ -153,6 +153,10 @@ FcOpPrint (FcOp op) case FcOpNot: printf ("Not"); break; case FcOpNil: printf ("Nil"); break; case FcOpComma: printf ("Comma"); break; + case FcOpFloor: printf ("Floor"); break; + case FcOpCeil: printf ("Ceil"); break; + case FcOpRound: printf ("Round"); break; + case FcOpTrunc: printf ("Trunc"); break; case FcOpInvalid: printf ("Invalid"); break; } } @@ -236,6 +240,22 @@ FcExprPrint (const FcExpr *expr) printf ("Not "); FcExprPrint (expr->u.tree.left); break; + case FcOpFloor: + printf ("Floor "); + FcExprPrint (expr->u.tree.left); + break; + case FcOpCeil: + printf ("Ceil "); + FcExprPrint (expr->u.tree.left); + break; + case FcOpRound: + printf ("Round "); + FcExprPrint (expr->u.tree.left); + break; + case FcOpTrunc: + printf ("Trunc "); + FcExprPrint (expr->u.tree.left); + break; case FcOpInvalid: printf ("Invalid"); break; } } diff --git a/src/fcint.h b/src/fcint.h index a008f06..7ffc3a6 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -135,7 +135,8 @@ typedef enum _FcOp { FcOpOr, FcOpAnd, FcOpEqual, FcOpNotEqual, FcOpContains, FcOpNotContains, FcOpLess, FcOpLessEqual, FcOpMore, FcOpMoreEqual, FcOpPlus, FcOpMinus, FcOpTimes, FcOpDivide, - FcOpNot, FcOpComma, FcOpInvalid + FcOpNot, FcOpComma, FcOpFloor, FcOpCeil, FcOpRound, FcOpTrunc, + FcOpInvalid } FcOp; typedef struct _FcExpr { diff --git a/src/fcxml.c b/src/fcxml.c index 95b0c85..657959c 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -203,6 +203,8 @@ FcExprCreateOp (FcExpr *left, FcOp op, FcExpr *right) void FcExprDestroy (FcExpr *e) { + if (!e) + return; switch (e->op) { case FcOpInteger: break; @@ -251,6 +253,10 @@ FcExprDestroy (FcExpr *e) FcExprDestroy (e->u.tree.right); /* fall through */ case FcOpNot: + case FcOpFloor: + case FcOpCeil: + case FcOpRound: + case FcOpTrunc: FcExprDestroy (e->u.tree.left); break; case FcOpNil: @@ -337,6 +343,10 @@ typedef enum _FcElement { FcElementDivide, FcElementNot, FcElementIf, + FcElementFloor, + FcElementCeil, + FcElementRound, + FcElementTrunc, FcElementUnknown } FcElement; @@ -389,6 +399,10 @@ FcElementMap (const XML_Char *name) { "divide", FcElementDivide }, { "not", FcElementNot }, { "if", FcElementIf }, + { "floor", FcElementFloor }, + { "ceil", FcElementCeil }, + { "round", FcElementRound }, + { "trunc", FcElementTrunc }, { 0, 0 } }; @@ -1292,8 +1306,17 @@ FcPopExpr (FcConfigParse *parse) return expr; } +/* + * This builds a tree of binary operations. Note + * that every operator is defined so that if only + * a single operand is contained, the value of the + * whole expression is the value of the operand. + * + * This code reduces in that case to returning that + * operand. + */ static FcExpr * -FcPopExprs (FcConfigParse *parse, FcOp op) +FcPopBinary (FcConfigParse *parse, FcOp op) { FcExpr *left, *expr = 0, *new; @@ -1318,9 +1341,39 @@ FcPopExprs (FcConfigParse *parse, FcOp op) } static void -FcParseExpr (FcConfigParse *parse, FcOp op) +FcParseBinary (FcConfigParse *parse, FcOp op) +{ + FcExpr *expr = FcPopBinary (parse, op); + if (expr) + FcVStackPushExpr (parse, FcVStackExpr, expr); +} + +/* + * This builds a a unary operator, it consumes only + * a single operand + */ + +static FcExpr * +FcPopUnary (FcConfigParse *parse, FcOp op) +{ + FcExpr *operand, *new = 0; + + if ((operand = FcPopExpr (parse))) + { + new = FcExprCreateOp (operand, op, 0); + if (!new) + { + FcExprDestroy (operand); + FcConfigMessage (parse, FcSevereError, "out of memory"); + } + } + return new; +} + +static void +FcParseUnary (FcConfigParse *parse, FcOp op) { - FcExpr *expr = FcPopExprs (parse, op); + FcExpr *expr = FcPopUnary (parse, op); if (expr) FcVStackPushExpr (parse, FcVStackExpr, expr); } @@ -1449,7 +1502,7 @@ FcParseTest (FcConfigParse *parse) return; } } - expr = FcPopExprs (parse, FcOpComma); + expr = FcPopBinary (parse, FcOpComma); if (!expr) { FcConfigMessage (parse, FcSevereWarning, "missing test expression"); @@ -1527,7 +1580,7 @@ FcParseEdit (FcConfigParse *parse) return; } } - expr = FcPopExprs (parse, FcOpComma); + expr = FcPopBinary (parse, FcOpComma); edit = FcEditCreate ((char *) FcStrCopy (name), mode, expr, binding); if (!edit) { @@ -1716,52 +1769,64 @@ FcEndElement(void *userData, const XML_Char *name) FcParseString (parse, FcVStackConstant); break; case FcElementOr: - FcParseExpr (parse, FcOpOr); + FcParseBinary (parse, FcOpOr); break; case FcElementAnd: - FcParseExpr (parse, FcOpAnd); + FcParseBinary (parse, FcOpAnd); break; case FcElementEq: - FcParseExpr (parse, FcOpEqual); + FcParseBinary (parse, FcOpEqual); break; case FcElementNotEq: - FcParseExpr (parse, FcOpNotEqual); + FcParseBinary (parse, FcOpNotEqual); break; case FcElementLess: - FcParseExpr (parse, FcOpLess); + FcParseBinary (parse, FcOpLess); break; case FcElementLessEq: - FcParseExpr (parse, FcOpLessEqual); + FcParseBinary (parse, FcOpLessEqual); break; case FcElementMore: - FcParseExpr (parse, FcOpMore); + FcParseBinary (parse, FcOpMore); break; case FcElementMoreEq: - FcParseExpr (parse, FcOpMoreEqual); + FcParseBinary (parse, FcOpMoreEqual); break; case FcElementContains: - FcParseExpr (parse, FcOpContains); + FcParseBinary (parse, FcOpContains); break; case FcElementNotContains: - FcParseExpr (parse, FcOpNotContains); + FcParseBinary (parse, FcOpNotContains); break; case FcElementPlus: - FcParseExpr (parse, FcOpPlus); + FcParseBinary (parse, FcOpPlus); break; case FcElementMinus: - FcParseExpr (parse, FcOpMinus); + FcParseBinary (parse, FcOpMinus); break; case FcElementTimes: - FcParseExpr (parse, FcOpTimes); + FcParseBinary (parse, FcOpTimes); break; case FcElementDivide: - FcParseExpr (parse, FcOpDivide); + FcParseBinary (parse, FcOpDivide); break; case FcElementNot: - FcParseExpr (parse, FcOpNot); + FcParseUnary (parse, FcOpNot); break; case FcElementIf: - FcParseExpr (parse, FcOpQuest); + FcParseBinary (parse, FcOpQuest); + break; + case FcElementFloor: + FcParseUnary (parse, FcOpFloor); + break; + case FcElementCeil: + FcParseUnary (parse, FcOpCeil); + break; + case FcElementRound: + FcParseUnary (parse, FcOpRound); + break; + case FcElementTrunc: + FcParseUnary (parse, FcOpTrunc); break; case FcElementUnknown: break; |