summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2003-04-15 23:38:06 +0000
committerKeith Packard <keithp@keithp.com>2003-04-15 23:38:06 +0000
commit3f7653c2badeb426f938bafe1a82c2917b7ea125 (patch)
treebc820a13520bdc1c12ca9e92b78938a439aaa0e9
parent52253696cd2779bd9040457fbd157bbe75895ed6 (diff)
downloadfontconfig-3f7653c2badeb426f938bafe1a82c2917b7ea125.tar.gz
Fix unary operator parsing. Add floor, ceil, trunc and round unary
operators
-rw-r--r--fontconfig/fontconfig.h2
-rw-r--r--fonts.dtd6
-rw-r--r--src/Makefile.am2
-rw-r--r--src/fccfg.c71
-rw-r--r--src/fcdbg.c20
-rw-r--r--src/fcint.h3
-rw-r--r--src/fcxml.c107
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
diff --git a/fonts.dtd b/fonts.dtd
index f7c2bc9..b89ffe3 100644
--- a/fonts.dtd
+++ b/fonts.dtd
@@ -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;