X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcmatch.c;h=0d84704b51abfff52eba73837ebf11aebbe8b3cd;hb=d9741a7f1a73f718ab20b0582fff8aebeba01077;hp=7e3353b3d42e610b1e5ba6a387eee20aeb08de76;hpb=7ce196733129b0e664c1bdc20f973f15167292f7;p=fontconfig.git diff --git a/src/fcmatch.c b/src/fcmatch.c index 7e3353b..0d84704 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -1,5 +1,5 @@ /* - * $RCSId: xc/lib/fontconfig/src/fcmatch.c,v 1.20 2002/08/31 22:17:32 keithp Exp $ + * fontconfig/src/fcmatch.c * * Copyright © 2000 Keith Packard * @@ -13,9 +13,9 @@ * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR @@ -72,7 +72,8 @@ FcCompareFamily (FcValue *v1, FcValue *v2) const FcChar8* v1_string = fc_value_string(v1); const FcChar8* v2_string = fc_value_string(v2); - if (FcToLower(*v1_string) != FcToLower(*v2_string)) + if (FcToLower(*v1_string) != FcToLower(*v2_string) && + *v1_string != ' ' && *v2_string != ' ') return 1.0; return (double) FcStrCmpIgnoreBlanksAndCase (v1_string, v2_string) != 0; @@ -183,68 +184,43 @@ typedef struct _FcMatcher { * each value, earlier values are more significant than * later values */ -static FcMatcher _FcMatchers [] = { +static const FcMatcher _FcMatchers [] = { { FC_FOUNDRY_OBJECT, FcCompareString, 0, 0 }, #define MATCH_FOUNDRY 0 -#define MATCH_FOUNDRY_INDEX 0 - { FC_CHARSET_OBJECT, FcCompareCharSet, 1, 1 }, #define MATCH_CHARSET 1 -#define MATCH_CHARSET_INDEX 1 - { FC_FAMILY_OBJECT, FcCompareFamily, 2, 4 }, #define MATCH_FAMILY 2 -#define MATCH_FAMILY_STRONG_INDEX 2 -#define MATCH_FAMILY_WEAK_INDEX 4 - { FC_LANG_OBJECT, FcCompareLang, 3, 3 }, #define MATCH_LANG 3 #define MATCH_LANG_INDEX 3 - { FC_SPACING_OBJECT, FcCompareNumber, 5, 5 }, #define MATCH_SPACING 4 -#define MATCH_SPACING_INDEX 5 - { FC_PIXEL_SIZE_OBJECT, FcCompareSize, 6, 6 }, #define MATCH_PIXEL_SIZE 5 -#define MATCH_PIXEL_SIZE_INDEX 6 - { FC_STYLE_OBJECT, FcCompareString, 7, 7 }, #define MATCH_STYLE 6 -#define MATCH_STYLE_INDEX 7 - { FC_SLANT_OBJECT, FcCompareNumber, 8, 8 }, #define MATCH_SLANT 7 -#define MATCH_SLANT_INDEX 8 - { FC_WEIGHT_OBJECT, FcCompareNumber, 9, 9 }, #define MATCH_WEIGHT 8 -#define MATCH_WEIGHT_INDEX 9 - { FC_WIDTH_OBJECT, FcCompareNumber, 10, 10 }, #define MATCH_WIDTH 9 -#define MATCH_WIDTH_INDEX 10 - - { FC_ANTIALIAS_OBJECT, FcCompareBool, 11, 11 }, -#define MATCH_ANTIALIAS 10 -#define MATCH_ANTIALIAS_INDEX 11 - - { FC_RASTERIZER_OBJECT, FcCompareString, 12, 12 }, -#define MATCH_RASTERIZER 11 -#define MATCH_RASTERIZER_INDEX 12 - - { FC_OUTLINE_OBJECT, FcCompareBool, 13, 13 }, -#define MATCH_OUTLINE 12 -#define MATCH_OUTLINE_INDEX 13 - - { FC_FONTVERSION_OBJECT, FcCompareNumber, 14, 14 }, -#define MATCH_FONTVERSION 13 -#define MATCH_FONTVERSION_INDEX 14 + { FC_DECORATIVE_OBJECT, FcCompareBool, 11, 11 }, +#define MATCH_DECORATIVE 10 + { FC_ANTIALIAS_OBJECT, FcCompareBool, 12, 12 }, +#define MATCH_ANTIALIAS 11 + { FC_RASTERIZER_OBJECT, FcCompareString, 13, 13 }, +#define MATCH_RASTERIZER 12 + { FC_OUTLINE_OBJECT, FcCompareBool, 14, 14 }, +#define MATCH_OUTLINE 13 + { FC_FONTVERSION_OBJECT, FcCompareNumber, 15, 15 }, +#define MATCH_FONTVERSION 14 }; -#define NUM_MATCH_VALUES 15 +#define NUM_MATCH_VALUES 16 -static FcMatcher* +static const FcMatcher* FcObjectToMatcher (FcObject object) { int i; @@ -279,6 +255,8 @@ FcObjectToMatcher (FcObject object) i = MATCH_RASTERIZER; break; case FC_OUTLINE_OBJECT: i = MATCH_OUTLINE; break; + case FC_DECORATIVE_OBJECT: + i = MATCH_DECORATIVE; break; } if (i < 0) @@ -298,7 +276,7 @@ FcCompareValueList (FcObject object, FcValueListPtr v1, v2; double v, best, bestStrong, bestWeak; int j; - FcMatcher *match = FcObjectToMatcher(object); + const FcMatcher *match = FcObjectToMatcher(object); if (!match) { @@ -310,10 +288,10 @@ FcCompareValueList (FcObject object, best = 1e99; bestStrong = 1e99; bestWeak = 1e99; - j = 0; + j = 1; for (v1 = v1orig; v1; v1 = FcValueListNext(v1)) { - for (v2 = v1orig; v2; v2 = FcValueListNext(v2)) + for (v2 = v2orig; v2; v2 = FcValueListNext(v2)) { v = (match->compare) (&v1->value, &v2->value); if (v < 0) @@ -321,7 +299,7 @@ FcCompareValueList (FcObject object, *result = FcResultTypeMismatch; return FcFalse; } - v = v * 100 + j; + v = v * 1000 + j; if (v < best) { if (bestValue) @@ -452,12 +430,12 @@ FcFontRenderPrepare (FcConfig *config, return new; } -FcPattern * -FcFontSetMatch (FcConfig *config, - FcFontSet **sets, - int nsets, - FcPattern *p, - FcResult *result) +static FcPattern * +FcFontSetMatchInternal (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcResult *result) { double score[NUM_MATCH_VALUES], bestscore[NUM_MATCH_VALUES]; int f; @@ -474,12 +452,6 @@ FcFontSetMatch (FcConfig *config, printf ("Match "); FcPatternPrint (p); } - if (!config) - { - config = FcConfigGetCurrent (); - if (!config) - return 0; - } for (set = 0; set < nsets; set++) { s = sets[set]; @@ -522,6 +494,7 @@ FcFontSetMatch (FcConfig *config, printf ("Best score"); for (i = 0; i < NUM_MATCH_VALUES; i++) printf (" %g", bestscore[i]); + printf ("\n"); FcPatternPrint (best); } if (!best) @@ -529,7 +502,29 @@ FcFontSetMatch (FcConfig *config, *result = FcResultNoMatch; return 0; } - return FcFontRenderPrepare (config, p, best); + return best; +} + +FcPattern * +FcFontSetMatch (FcConfig *config, + FcFontSet **sets, + int nsets, + FcPattern *p, + FcResult *result) +{ + FcPattern *best; + + if (!config) + { + config = FcConfigGetCurrent (); + if (!config) + return 0; + } + best = FcFontSetMatchInternal (config, sets, nsets, p, result); + if (best) + return FcFontRenderPrepare (config, p, best); + else + return NULL; } FcPattern * @@ -539,6 +534,7 @@ FcFontMatch (FcConfig *config, { FcFontSet *sets[2]; int nsets; + FcPattern *best; if (!config) { @@ -551,7 +547,12 @@ FcFontMatch (FcConfig *config, sets[nsets++] = config->fonts[FcSetSystem]; if (config->fonts[FcSetApplication]) sets[nsets++] = config->fonts[FcSetApplication]; - return FcFontSetMatch (config, sets, nsets, p, result); + + best = FcFontSetMatchInternal (config, sets, nsets, p, result); + if (best) + return FcFontRenderPrepare (config, p, best); + else + return NULL; } typedef struct _FcSortNode { @@ -576,52 +577,71 @@ FcSortCompare (const void *aa, const void *ab) } static FcBool -FcSortWalk (FcSortNode **n, int nnode, FcFontSet *fs, FcCharSet **cs, FcBool trim, FcBool build_cs) +FcSortWalk (FcSortNode **n, int nnode, FcFontSet *fs, FcCharSet **csp, FcBool trim) { - FcCharSet *ncs; - FcSortNode *node; + FcBool ret = FcFalse; + FcCharSet *cs; + + cs = 0; + if (trim || csp) + { + cs = FcCharSetCreate (); + if (cs == NULL) + goto bail; + } while (nnode--) { - node = *n++; - if (FcPatternGetCharSet (node->pattern, FC_CHARSET, 0, &ncs) == - FcResultMatch) + FcSortNode *node = *n++; + FcBool adds_chars = FcFalse; + + /* + * Only fetch node charset if we'd need it + */ + if (cs) { - /* - * If this font isn't a subset of the previous fonts, - * add it to the list - */ - if (!trim || !*cs || !FcCharSetIsSubset (ncs, *cs)) + FcCharSet *ncs; + + if (FcPatternGetCharSet (node->pattern, FC_CHARSET, 0, &ncs) != + FcResultMatch) + continue; + + if (!FcCharSetMerge (cs, ncs, &adds_chars)) + goto bail; + } + + /* + * If this font isn't a subset of the previous fonts, + * add it to the list + */ + if (!trim || adds_chars) + { + FcPatternReference (node->pattern); + if (FcDebug () & FC_DBG_MATCHV) { - if (trim || build_cs) - { - if (*cs) - { - ncs = FcCharSetUnion (ncs, *cs); - if (!ncs) - return FcFalse; - FcCharSetDestroy (*cs); - } - else - ncs = FcCharSetCopy (ncs); - *cs = ncs; - } - - FcPatternReference (node->pattern); - if (FcDebug () & FC_DBG_MATCH) - { - printf ("Add "); - FcPatternPrint (node->pattern); - } - if (!FcFontSetAdd (fs, node->pattern)) - { - FcPatternDestroy (node->pattern); - return FcFalse; - } + printf ("Add "); + FcPatternPrint (node->pattern); + } + if (!FcFontSetAdd (fs, node->pattern)) + { + FcPatternDestroy (node->pattern); + goto bail; } } } - return FcTrue; + if (csp) + { + *csp = cs; + cs = 0; + } + + ret = FcTrue; + +bail: + if (cs) + FcCharSetDestroy (cs); + + return ret; } void @@ -645,7 +665,6 @@ FcFontSetSort (FcConfig *config, FcSortNode **nodeps, **nodep; int nnodes; FcSortNode *new; - FcCharSet *cs; int set; int f; int i; @@ -730,7 +749,7 @@ FcFontSetSort (FcConfig *config, * If this node matches any language, go check * which ones and satisfy those entries */ - if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang) + if (nodeps[f]->score[MATCH_LANG_INDEX] < 200) { for (i = 0; i < nPatternLang; i++) { @@ -760,7 +779,7 @@ FcFontSetSort (FcConfig *config, } } if (!satisfies) - nodeps[f]->score[MATCH_LANG_INDEX] = 1000.0; + nodeps[f]->score[MATCH_LANG_INDEX] = 10000.0; } /* @@ -773,26 +792,19 @@ FcFontSetSort (FcConfig *config, if (!ret) goto bail1; - cs = 0; - - if (!FcSortWalk (nodeps, nnodes, ret, &cs, trim, (csp!=0))) + if (!FcSortWalk (nodeps, nnodes, ret, csp, trim)) goto bail2; - if (csp) - *csp = cs; - else - { - if (cs) - FcCharSetDestroy (cs); - } - free (nodes); + if (FcDebug() & FC_DBG_MATCH) + { + printf ("First font "); + FcPatternPrint (ret->fonts[0]); + } return ret; bail2: - if (cs) - FcCharSetDestroy (cs); FcFontSetDestroy (ret); bail1: free (nodes); @@ -823,3 +835,6 @@ FcFontSort (FcConfig *config, sets[nsets++] = config->fonts[FcSetApplication]; return FcFontSetSort (config, sets, nsets, p, trim, csp, result); } +#define __fcmatch__ +#include "fcaliastail.h" +#undef __fcmatch__