]> git.wh0rd.org Git - fontconfig.git/commitdiff
Fix unary operator parsing. Add floor, ceil, trunc and round unary
authorKeith Packard <keithp@keithp.com>
Tue, 15 Apr 2003 23:38:06 +0000 (23:38 +0000)
committerKeith Packard <keithp@keithp.com>
Tue, 15 Apr 2003 23:38:06 +0000 (23:38 +0000)
    operators

fontconfig/fontconfig.h
fonts.dtd
src/Makefile.am
src/fccfg.c
src/fcdbg.c
src/fcint.h
src/fcxml.c

index ca40834362948b90465e8114bff9ce55af9d738e..2a26fa8185d1bd7a3a4c2c2c11a1f280cac59700 100644 (file)
@@ -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
index f7c2bc9712aacca4b76eb1d80cd9ef0f2318db40..b89ffe31a26ffb2c7cfb7a733891981e826c9ca1 100644 (file)
--- 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.
 <!ELEMENT divide (%expr;)*>
 <!ELEMENT not (%expr;)>
 <!ELEMENT if ((%expr;), (%expr;), (%expr;))>
+<!ELEMENT floor (%expr;)>
+<!ELEMENT ceil (%expr;)>
+<!ELEMENT round (%expr;)>
+<!ELEMENT trunc (%expr;)>
index 949c5a3cd68afb4c739e13949b46cfcbb8e52acf..bb522825d21dcfba7d1aae0b531dcf8b82302254 100644 (file)
@@ -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 \
index a8f10b90abc1ce924fd0480ef1451f64db13ef0a..68b548f53c99eff951e378ea28b5633ef3d13398 100644 (file)
@@ -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;
index 1b6ca41cced6911277a52998d6f53811e30e46a1..8d4439b944b7931c01f73606e4ca78fa0bfcfabf 100644 (file)
@@ -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;
     }
 }
index a008f069698e7db4da5919e10fceeb324eae757e..7ffc3a627f42d91191b12555158384b0fc5c1137 100644 (file)
@@ -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 {
index 95b0c85b3301168ab18d089cc673844907b5718a..657959c158c7c4733b3df510c1be4f3e41e51163 100644 (file)
@@ -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;