Commit 938bc633 authored by Keith Packard's avatar Keith Packard

Fix weird first/not-first lameness in font matches, replacing with target

    qualifiers on test elements. Update library manual page.
parent 80a7d664
/*
* $XFree86: xc/lib/fontconfig/fontconfig/fcprivate.h,v 1.2 2002/02/15 06:01:27 keithp Exp $
* $XFree86: xc/lib/fontconfig/fontconfig/fcprivate.h,v 1.3 2002/05/31 23:21:24 keithp Exp $
*
* Copyright 2001 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -72,6 +72,9 @@
break; \
case FcTypeFTFace: \
__v__.u.f = va_arg (va, FT_Face); \
break; \
case FcTypePattern: \
__v__.u.p = va_arg (va, FcPattern *); \
} \
if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
goto _FcPatternVapBuild_bail1; \
......
......@@ -71,6 +71,7 @@ typedef int FcBool;
#define FC_SOURCE "source" /* String (X11, freetype) */
#define FC_CHARSET "charset" /* CharSet */
#define FC_LANG "lang" /* String OS/2 CodePageRange */
#define FC_PATTERN "pattern" /* FcPattern */
#define FC_DIR_CACHE_FILE "fonts.cache"
#define FC_USER_CACHE_FILE ".fonts.cache"
......@@ -109,7 +110,8 @@ typedef enum _FcType {
FcTypeBool,
FcTypeMatrix,
FcTypeCharSet,
FcTypeFTFace
FcTypeFTFace,
FcTypePattern
} FcType;
typedef struct _FcMatrix {
......@@ -141,6 +143,8 @@ typedef enum _FcResult {
FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId
} FcResult;
typedef struct _FcPattern FcPattern;
typedef struct _FcValue {
FcType type;
union {
......@@ -151,11 +155,10 @@ typedef struct _FcValue {
const FcMatrix *m;
const FcCharSet *c;
void *f;
const FcPattern *p;
} u;
} FcValue;
typedef struct _FcPattern FcPattern;
typedef struct _FcFontSet {
int nfont;
int sfont;
......@@ -169,7 +172,7 @@ typedef struct _FcObjectSet {
} FcObjectSet;
typedef enum _FcMatchKind {
FcMatchPattern, FcMatchFont
FcMatchPattern, FcMatchFont
} FcMatchKind;
typedef enum _FcSetName {
......@@ -336,13 +339,13 @@ FcCharSetNextPage (const FcCharSet *a,
/* fcdbg.c */
void
FcValuePrint (FcValue v);
FcValuePrint (const FcValue v);
void
FcPatternPrint (FcPattern *p);
FcPatternPrint (const FcPattern *p);
void
FcFontSetPrint (FcFontSet *s);
FcFontSetPrint (const FcFontSet *s);
/* fcdefault.c */
void
......@@ -602,6 +605,9 @@ FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c);
FcBool
FcPatternAddBool (FcPattern *p, const char *object, FcBool b);
FcBool
FcPatternAddPattern (FcPattern *p, const char *object, const FcPattern *pp);
FcResult
FcPatternGetInteger (FcPattern *p, const char *object, int n, int *i);
......@@ -620,6 +626,9 @@ FcPatternGetCharSet (FcPattern *p, const char *object, int n, FcCharSet **c);
FcResult
FcPatternGetBool (FcPattern *p, const char *object, int n, FcBool *b);
FcResult
FcPatternGetPattern (FcPattern *p, const char *object, int n, FcPattern **pp);
FcPattern *
FcPatternVaBuild (FcPattern *orig, va_list va);
......
......@@ -127,6 +127,11 @@
-->
<include ignore_missing="yes">~/.fonts.conf</include>
<!--
Load local system customization file
-->
<include ignore_missing="yes">local.conf</include>
<!--
Alias well known font names to available TrueType fonts
-->
......@@ -197,11 +202,11 @@
<match target="font">
<!-- check to see if the font is roman -->
<test qual="first" name="slant">
<test name="slant">
<const>roman</const>
</test>
<!-- check to see if the pattern requested non-roman -->
<test qual="not_first" name="slant" compare="not_eq">
<test target="pattern" name="slant" compare="not_eq">
<const>roman</const>
</test>
<!-- multiply the matrix to slant the font -->
......
......@@ -112,11 +112,15 @@
if 'qual' is 'first', then the match succeeds only if the first value matches.
if 'qual' is 'not_first', then the match succeeds only if any value other than
the first matches.
For match elements with target=font, if test 'target' is 'pattern',
then the test is applied to the pattern used in matching rather than
to the resulting font.
-->
<!ELEMENT test (%expr;)*>
<!ATTLIST test
qual (any|all|first|not_first) "any"
name CDATA #REQUIRED
target (pattern|font|default) "default"
compare (eq|not_eq|less|less_eq|more|more_eq) "eq">
<!--
......
/*
* $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.15 2002/06/21 06:14:45 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.18 2002/07/31 01:36:37 keithp Exp $
*
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -438,16 +438,20 @@ FcConfigAddEdit (FcConfig *config,
subst->next = 0;
subst->test = test;
subst->edit = edit;
if (FcDebug () & FC_DBG_EDIT)
{
printf ("Add Subst ");
FcSubstPrint (subst);
}
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;
}
......@@ -483,7 +487,6 @@ FcConfigCompareValue (FcValue m,
v = FcConfigPromote (v, m);
if (m.type == v.type)
{
ret = FcFalse;
switch (m.type) {
case FcTypeInteger:
break; /* FcConfigPromote prevents this from happening */
......@@ -588,6 +591,19 @@ FcConfigCompareValue (FcValue m,
default:
break;
}
break;
case FcTypePattern:
switch (op) {
case FcOpEqual:
ret = FcPatternEqual (m.u.p, v.u.p);
break;
case FcOpNotEqual:
ret = !FcPatternEqual (m.u.p, v.u.p);
break;
default:
break;
}
break;
}
}
else
......@@ -658,15 +674,22 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
v.type = FcTypeVoid;
FcValueDestroy (vl);
break;
case FcOpOr:
case FcOpAnd:
case FcOpEqual:
case FcOpContains:
case FcOpNotEqual:
case FcOpLess:
case FcOpLessEqual:
case FcOpMore:
case FcOpMoreEqual:
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 FcOpEqual:
case FcOpPlus:
case FcOpMinus:
case FcOpTimes:
......@@ -696,31 +719,6 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
v.type = FcTypeDouble;
v.u.d = vl.u.d / vr.u.d;
break;
case FcOpEqual:
case FcOpContains:
v.type = FcTypeBool;
v.u.b = vl.u.d == vr.u.d;
break;
case FcOpNotEqual:
v.type = FcTypeBool;
v.u.b = vl.u.d != vr.u.d;
break;
case FcOpLess:
v.type = FcTypeBool;
v.u.b = vl.u.d < vr.u.d;
break;
case FcOpLessEqual:
v.type = FcTypeBool;
v.u.b = vl.u.d <= vr.u.d;
break;
case FcOpMore:
v.type = FcTypeBool;
v.u.b = vl.u.d > vr.u.d;
break;
case FcOpMoreEqual:
v.type = FcTypeBool;
v.u.b = vl.u.d >= vr.u.d;
break;
default:
v.type = FcTypeVoid;
break;
......@@ -742,15 +740,6 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
v.type = FcTypeBool;
v.u.b = vl.u.b && vr.u.b;
break;
case FcOpEqual:
case FcOpContains:
v.type = FcTypeBool;
v.u.b = vl.u.b == vr.u.b;
break;
case FcOpNotEqual:
v.type = FcTypeBool;
v.u.b = vl.u.b != vr.u.b;
break;
default:
v.type = FcTypeVoid;
break;
......@@ -758,15 +747,6 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break;
case FcTypeString:
switch (e->op) {
case FcOpEqual:
case FcOpContains:
v.type = FcTypeBool;
v.u.b = FcStrCmpIgnoreCase (vl.u.s, vr.u.s) == 0;
break;
case FcOpNotEqual:
v.type = FcTypeBool;
v.u.b = FcStrCmpIgnoreCase (vl.u.s, vr.u.s) != 0;
break;
case FcOpPlus:
v.type = FcTypeString;
v.u.s = FcStrPlus (vl.u.s, vr.u.s);
......@@ -780,15 +760,6 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break;
case FcTypeMatrix:
switch (e->op) {
case FcOpEqual:
case FcOpContains:
v.type = FcTypeBool;
v.u.b = FcMatrixEqual (vl.u.m, vr.u.m);
break;
case FcOpNotEqual:
v.type = FcTypeBool;
v.u.b = FcMatrixEqual (vl.u.m, vr.u.m);
break;
case FcOpTimes:
v.type = FcTypeMatrix;
m = malloc (sizeof (FcMatrix));
......@@ -808,26 +779,6 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break;
}
break;
case FcTypeCharSet:
switch (e->op) {
case FcOpContains:
/* vl contains vr if vr is a subset of vl */
v.type = FcTypeBool;
v.u.b = FcCharSetIsSubset (vr.u.c, vl.u.c);
break;
case FcOpEqual:
v.type = FcTypeBool;
v.u.b = FcCharSetEqual (vl.u.c, vr.u.c);
break;
case FcOpNotEqual:
v.type = FcTypeBool;
v.u.b = !FcCharSetEqual (vl.u.c, vr.u.c);
break;
default:
v.type = FcTypeVoid;
break;
}
break;
default:
v.type = FcTypeVoid;
break;
......@@ -1068,6 +1019,8 @@ FcConfigSubstitute (FcConfig *config,
FcTest *t;
FcEdit *e;
FcValueList *l;
FcPattern *p_pat = 0;
FcPattern *m;
if (!config)
{
......@@ -1089,7 +1042,10 @@ FcConfigSubstitute (FcConfig *config,
if (kind == FcMatchPattern)
s = config->substPattern;
else
{
s = config->substFont;
(void) FcPatternGetPattern (p, FC_PATTERN, 0, &p_pat);
}
for (; s; s = s->next)
{
/*
......@@ -1103,7 +1059,15 @@ FcConfigSubstitute (FcConfig *config,
printf ("FcConfigSubstitute test ");
FcTestPrint (t);
}
st[i].elt = FcPatternFindElt (p, t->field);
st[i].elt = 0;
if (kind == FcMatchFont && t->kind == FcMatchPattern)
m = p_pat;
else
m = p;
if (m)
st[i].elt = FcPatternFindElt (m, t->field);
else
st[i].elt = 0;
/*
* If there's no such field in the font,
* then FcQualAll matches while FcQualAny does not
......@@ -1122,7 +1086,7 @@ FcConfigSubstitute (FcConfig *config,
* Check to see if there is a match, mark the location
* to apply match-relative edits
*/
st[i].value = FcConfigMatchValueList (p, t, st[i].elt->values);
st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values);
if (!st[i].value)
break;
if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
......@@ -1148,11 +1112,17 @@ FcConfigSubstitute (FcConfig *config,
*/
l = FcConfigValues (p, e->expr, e->binding);
/*
* Locate any test associated with this field
* Locate any test associated with this field, skipping
* tests associated with the pattern when substituting in
* the font
*/
for (t = s->test, i = 0; t; t = t->next, i++)
if (!FcStrCmpIgnoreCase ((FcChar8 *) t->field, (FcChar8 *) e->field))
{
if ((t->kind == FcMatchFont || kind == FcMatchPattern) &&
!FcStrCmpIgnoreCase ((FcChar8 *) t->field,
(FcChar8 *) e->field))
break;
}
switch (e->op) {
case FcOpAssign:
/*
......
......@@ -27,7 +27,7 @@
#include "fcint.h"
void
FcValuePrint (FcValue v)
FcValuePrint (const FcValue v)
{
switch (v.type) {
case FcTypeVoid:
......@@ -54,18 +54,23 @@ FcValuePrint (FcValue v)
case FcTypeFTFace:
printf (" face");
break;
case FcTypePattern:
printf (" pattern {");
FcPatternPrint (v.u.p);
printf (" } ");
break;
}
}
void
FcValueListPrint (FcValueList *l)
FcValueListPrint (const FcValueList *l)
{
for (; l; l = l->next)
FcValuePrint (l->value);
}
void
FcPatternPrint (FcPattern *p)
FcPatternPrint (const FcPattern *p)
{
int i;
FcPatternElt *e;
......@@ -126,7 +131,7 @@ FcOpPrint (FcOp op)
}
void
FcExprPrint (FcExpr *expr)
FcExprPrint (const FcExpr *expr)
{
switch (expr->op) {
case FcOpInteger: printf ("%d", expr->u.ival); break;
......@@ -206,8 +211,16 @@ FcExprPrint (FcExpr *expr)
}
void
FcTestPrint (FcTest *test)
FcTestPrint (const FcTest *test)
{
switch (test->kind) {
case FcMatchPattern:
printf ("pattern ");
break;
case FcMatchFont:
printf ("font ");
break;
}
switch (test->qual) {
case FcQualAny:
printf ("any ");
......@@ -230,7 +243,7 @@ FcTestPrint (FcTest *test)
}
void
FcEditPrint (FcEdit *edit)
FcEditPrint (const FcEdit *edit)
{
printf ("Edit %s ", edit->field);
FcOpPrint (edit->op);
......@@ -239,7 +252,7 @@ FcEditPrint (FcEdit *edit)
}
void
FcSubstPrint (FcSubst *subst)
FcSubstPrint (const FcSubst *subst)
{
FcEdit *e;
FcTest *t;
......@@ -261,7 +274,7 @@ FcSubstPrint (FcSubst *subst)
}
void
FcFontSetPrint (FcFontSet *s)
FcFontSetPrint (const FcFontSet *s)
{
int i;
......
......@@ -138,8 +138,11 @@ typedef enum _FcQual {
FcQualAny, FcQualAll, FcQualFirst, FcQualNotFirst
} FcQual;
#define FcMatchDefault ((FcMatchKind) -1)
typedef struct _FcTest {
struct _FcTest *next;
FcMatchKind kind;
FcQual qual;
const char *field;
FcOp op;
......@@ -429,22 +432,22 @@ FcFreeTypeGetPrivateMap (FT_Encoding encoding);
/* fcdbg.c */
void
FcValueListPrint (FcValueList *l);
FcValueListPrint (const FcValueList *l);
void
FcOpPrint (FcOp op);
void
FcTestPrint (FcTest *test);
FcTestPrint (const FcTest *test);
void
FcExprPrint (FcExpr *expr);
FcExprPrint (const FcExpr *expr);
void
FcEditPrint (FcEdit *edit);
FcEditPrint (const FcEdit *edit);
void
FcSubstPrint (FcSubst *subst);
FcSubstPrint (const FcSubst *subst);
int
FcDebug (void);
......@@ -477,7 +480,11 @@ char *
FcConfigSaveField (const char *field);
FcTest *
FcTestCreate (FcQual qual, const FcChar8 *field, FcOp compare, FcExpr *expr);
FcTestCreate (FcMatchKind kind,
FcQual qual,
const FcChar8 *field,
FcOp compare,
FcExpr *expr);
void
FcTestDestroy (FcTest *test);
......
/*
* $XFree86: xc/lib/fontconfig/src/fclist.c,v 1.5 2002/06/03 08:31:15 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fclist.c,v 1.7 2002/06/19 20:08:22 keithp Exp $
*
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -247,6 +247,8 @@ FcListValueHash (FcValue v)
return FcCharSetCount (v.u.c);
case FcTypeFTFace:
return (FcChar32) v.u.f;
case FcTypePattern:
return (FcChar32) v.u.p->num;
}
return 0;
}
......
/*
* $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.15 2002/06/29 20:31:02 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.16 2002/07/06 23:47:44 keithp Exp $
*
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -384,26 +384,12 @@ FcFontRenderPrepare (FcConfig *config,
pe = FcPatternFindElt (pat, fe->object);
if (pe)
{
int j;
double score[NUM_MATCH_VALUES];
for (j = 0; j < NUM_MATCH_VALUES; j++)
score[j] = 0;
if (!FcCompareValueList (pe->object, pe->values,
fe->values, &v, score, &result))
fe->values, &v, 0, &result))
{
FcPatternDestroy (new);
return 0;
}
for (j = 0; j < NUM_MATCH_VALUES; j++)
if (score[j] >= 100.0)
{
FcValueList *pv;
for (pv = pe->values; pv; pv = pv->next)
FcPatternAdd (new, fe->object, pv->value, FcTrue);
break;
}
}
else
v = fe->values->value;
......@@ -416,6 +402,7 @@ FcFontRenderPrepare (FcConfig *config,
if (!fe)
FcPatternAdd (new, pe->object, pe->values->value, FcTrue);
}
FcPatternAddPattern (new, FC_PATTERN, pat);
FcConfigSubstitute (config, new, FcMatchFont);
return new;
}
......
/*
* $XFree86: xc/lib/fontconfig/src/fcname.c,v 1.9 2002/06/26 22:14:08 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fcname.c,v 1.10 2002/06/29 20:31:02 keithp Exp $
*
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -472,6 +472,8 @@ FcNameUnparseValue (FcStrBuf *buf,
return FcNameUnparseCharSet (buf, v.u.c);
case FcTypeFTFace:
return FcTrue;
case FcTypePattern:
return FcTrue;
}
return FcFalse;
}
......
/*
* $XFree86: xc/lib/fontconfig/src/fcpat.c,v 1.11 2002/07/06 23:47:44 keithp Exp $
* $XFree86: xc/lib/fontconfig/src/fcpat.c,v 1.12 2002/08/07 01:45:59 keithp Exp $
*
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
*
......@@ -55,6 +55,9 @@ FcValueDestroy (FcValue v)
case FcTypeCharSet:
FcCharSetDestroy ((FcCharSet *) v.u.c);
break;
case FcTypePattern:
FcPatternDestroy ((FcPattern *) v.u.p);
break;
default:
break;
}
......@@ -79,6 +82,9 @@ FcValueSave (FcValue v)
if (!v.u.c)
v.type = FcTypeVoid;
break;
case FcTypePattern:
FcPatternReference ((FcPattern *) v.u.p);
break;
default:
break;
}
......@@ -101,6 +107,9 @@ FcValueListDestroy (FcValueList *l)
case FcTypeCharSet:
FcCharSetDestroy ((FcCharSet *) l->value.u.c);
break;
case FcTypePattern:
FcPatternDestroy ((FcPattern *) l->value.u.p);
break;
default:
break;
}
......@@ -145,6 +154,8 @@ FcValueEqual (FcValue va, FcValue vb)
return FcCharSetEqual (va.u.c, vb.u.c);
case FcTypeFTFace:
return va.u.f == vb.u.f;
case FcTypePattern:
return FcPatternEqual (va.u.p, vb.u.p);
}
return FcFalse;
}
......@@ -195,6 +206,8 @@ FcValueHash (FcValue v)
case FcTypeFTFace:
return FcStringHash ((const FcChar8 *) ((FT_Face) v.u.f)->family_name) ^
FcStringHash ((const FcChar8 *) ((FT_Face) v.u.f)->style_name);
case FcTypePattern:
return (FcChar32) v.u.p->num;
}
return FcFalse;
}
......@@ -446,6 +459,9 @@ bail2:
case FcTypeCharSet:
FcCharSetDestroy ((FcCharSet *) value.u.c);
break;
case FcTypePattern:
FcPatternDestroy ((FcPattern *) value.u.p);
break;