}
static double
+FcComparePostScript (FcValue *v1, FcValue *v2)
+{
+ const FcChar8 *v1_string = FcValueString (v1);
+ const FcChar8 *v2_string = FcValueString (v2);
+ int n;
+ size_t len;
+
+ if (FcToLower (*v1_string) != FcToLower (*v2_string) &&
+ *v1_string != ' ' && *v2_string != ' ')
+ return 1.0;
+
+ n = FcStrMatchIgnoreCaseAndDelims (v1_string, v2_string, (const FcChar8 *)" -");
+ len = strlen ((const char *)v1_string);
+
+ return (double)(len - n) / (double)len;
+}
+
+static double
FcCompareLang (FcValue *v1, FcValue *v2)
{
FcLangResult result;
static double
FcCompareFilename (FcValue *v1, FcValue *v2)
{
- const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2);
- if (FcStrCmp (s1, s2) == 0)
- return 0.0;
- else if (FcStrCmpIgnoreCase (s1, s2) == 0)
- return 1.0;
- else if (FcStrRegexCmp (s2, s1))
- return 2.0;
- else if (FcStrRegexCmpIgnoreCase (s2, s1))
- return 3.0;
- else
- return 4.0;
+ const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2);
+ if (FcStrCmp (s1, s2) == 0)
+ return 0.0;
+ else if (FcStrCmpIgnoreCase (s1, s2) == 0)
+ return 1.0;
+ else if (FcStrGlobMatch (s1, s2))
+ return 2.0;
+ else
+ return 3.0;
+}
+
+static double
+FcCompareHash (FcValue *v1, FcValue *v2)
+{
+ const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2);
+
+ /* Do not match an empty string */
+ if (!s1 || !s2 || !s1[0] || !s2[0])
+ return 1.0;
+ return FcCompareString (v1, v2);
}
#define PRI_NULL(n) \
#define PRI_FcCompareFilename(n) PRI1(n)
#define PRI_FcCompareCharSet(n) PRI1(n)
#define PRI_FcCompareLang(n) PRI1(n)
+#define PRI_FcComparePostScript(n) PRI1(n)
+#define PRI_FcCompareHash(n) PRI1(n)
#define FC_OBJECT(NAME, Type, Cmp) PRI_##Cmp(NAME)
#undef FC_OBJECT
#undef PRI1
-#define PRI1(n) \
- PRI_ ## n ## _STRONG, \
- PRI_ ## n ## _WEAK
+#define PRI1(n) \
+ PRI_ ## n, \
+ PRI_ ## n ## _STRONG = PRI_ ## n, \
+ PRI_ ## n ## _WEAK = PRI_ ## n
typedef enum _FcMatcherPriority {
PRI1(HASH),
PRI1(FILE),
+ PRI1(FONTFORMAT),
+ PRI1(SCALABLE),
PRI1(FOUNDRY),
PRI1(CHARSET),
PRI_FAMILY_STRONG,
- PRI_LANG_STRONG,
- PRI_LANG_WEAK,
+ PRI_POSTSCRIPT_NAME_STRONG,
+ PRI1(LANG),
PRI_FAMILY_WEAK,
+ PRI_POSTSCRIPT_NAME_WEAK,
PRI1(SPACING),
PRI1(PIXEL_SIZE),
PRI1(STYLE),
continue;
}
+ FcPatternObjectAdd (new, fe->object, v, FcFalse);
}
else
{
if (fel)
goto copy_lang;
- v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
+ FcPatternObjectListAdd (new, fe->object,
+ FcValueListDuplicate (FcPatternEltValues (fe)),
+ FcTrue);
}
- FcPatternObjectAdd (new, fe->object, v, FcFalse);
}
for (i = 0; i < pat->num; i++)
{
pe = &FcPatternElts(pat)[i];
fe = FcPatternObjectFindElt (font, pe->object);
- if (!fe)
+ if (!fe &&
+ pe->object != FC_FAMILYLANG_OBJECT &&
+ pe->object != FC_STYLELANG_OBJECT &&
+ pe->object != FC_FULLNAMELANG_OBJECT)
{
FcPatternObjectListAdd (new, pe->object,
FcValueListDuplicate (FcPatternEltValues(pe)),
{
FcBool ret = FcFalse;
FcCharSet *cs;
+ int i;
cs = 0;
if (trim || csp)
goto bail;
}
- while (nnode--)
+ for (i = 0; i < nnode; i++)
{
FcSortNode *node = *n++;
FcBool adds_chars = FcFalse;
* If this font isn't a subset of the previous fonts,
* add it to the list
*/
- if (!trim || adds_chars)
+ if (!i || !trim || adds_chars)
{
FcPatternReference (node->pattern);
if (FcDebug () & FC_DBG_MATCHV)
* If this node matches any language, go check
* which ones and satisfy those entries
*/
- if (nodeps[f]->score[PRI_LANG_STRONG] < 2000 ||
- nodeps[f]->score[PRI_LANG_WEAK] < 2000)
+ if (nodeps[f]->score[PRI_LANG] < 2000)
{
for (i = 0; i < nPatternLang; i++)
{
}
patternLangSat[i] = FcTrue;
satisfies = FcTrue;
- /* adjust score to ensure it's not more than 10000.0
- * which would means the lang didn't satisfy the requirements
- */
- if (nodeps[f]->score[PRI_LANG_STRONG] > 10000.0)
- nodeps[f]->score[PRI_LANG_STRONG] = 10000.0;
- if (nodeps[f]->score[PRI_LANG_WEAK] > 10000.0)
- nodeps[f]->score[PRI_LANG_WEAK] = 10000.0;
break;
}
}
}
if (!satisfies)
{
- nodeps[f]->score[PRI_LANG_STRONG] = 10000.0;
- nodeps[f]->score[PRI_LANG_WEAK] = 10000.0;
+ nodeps[f]->score[PRI_LANG] = 10000.0;
}
}