return FcTrue;
}
+FcPattern *
+FcFontRenderPrepare (FcConfig *config,
+ FcPattern *pat,
+ FcPattern *font)
+{
+ FcPattern *new;
+ int i;
+ FcPatternElt *fe, *pe;
+ FcValue v;
+ double score[NUM_MATCHER];
+ FcResult result;
+
+ new = FcPatternCreate ();
+ if (!new)
+ return 0;
+ for (i = 0; i < font->num; i++)
+ {
+ fe = &font->elts[i];
+ pe = FcPatternFind (pat, fe->object, FcFalse);
+ if (pe)
+ {
+ if (!FcCompareValueList (pe->object, pe->values,
+ fe->values, &v, score, &result))
+ {
+ FcPatternDestroy (new);
+ return 0;
+ }
+ }
+ else
+ v = fe->values->value;
+ FcPatternAdd (new, fe->object, v, FcTrue);
+ }
+ for (i = 0; i < pat->num; i++)
+ {
+ pe = &pat->elts[i];
+ fe = FcPatternFind (font, pe->object, FcFalse);
+ if (!fe)
+ FcPatternAdd (new, pe->object, pe->values->value, FcTrue);
+ }
+ FcConfigSubstitute (config, new, FcMatchFont);
+ return new;
+}
+
FcPattern *
FcFontSetMatch (FcConfig *config,
FcFontSet **sets,
int f;
FcFontSet *s;
FcPattern *best;
- FcPattern *new;
- FcPatternElt *fe, *pe;
- FcValue v;
int i;
- FcSetName set;
+ int set;
for (i = 0; i < NUM_MATCHER; i++)
bestscore[i] = 0;
*result = FcResultNoMatch;
return 0;
}
- new = FcPatternCreate ();
- if (!new)
- return 0;
- for (i = 0; i < best->num; i++)
- {
- fe = &best->elts[i];
- pe = FcPatternFind (p, fe->object, FcFalse);
- if (pe)
- {
- if (!FcCompareValueList (pe->object, pe->values,
- fe->values, &v, score, result))
- {
- FcPatternDestroy (new);
- return 0;
- }
- }
- else
- v = fe->values->value;
- FcPatternAdd (new, fe->object, v, FcTrue);
- }
- for (i = 0; i < p->num; i++)
- {
- pe = &p->elts[i];
- fe = FcPatternFind (best, pe->object, FcFalse);
- if (!fe)
- FcPatternAdd (new, pe->object, pe->values->value, FcTrue);
- }
- FcConfigSubstitute (config, new, FcMatchFont);
- return new;
+ return FcFontRenderPrepare (config, p, best);
}
FcPattern *
sets[nsets++] = config->fonts[FcSetApplication];
return FcFontSetMatch (config, sets, nsets, p, result);
}
+
+typedef struct _FcSortNode {
+ FcPattern *pattern;
+ double score[NUM_MATCHER];
+} FcSortNode;
+
+static int
+FcSortCompare (const void *aa, const void *ab)
+{
+ FcSortNode *a = *(FcSortNode **) aa;
+ FcSortNode *b = *(FcSortNode **) ab;
+ int i;
+
+ for (i = 0; i < NUM_MATCHER; i++)
+ {
+ if (a->score[i] > b->score[i])
+ return -1;
+ if (a->score[i] < b->score[i])
+ return 1;
+ }
+ return 0;
+}
+
+static FcBool
+FcSortWalk (FcSortNode **n, int nnode, FcFontSet *fs, FcCharSet **cs, FcBool trim)
+{
+ FcCharSet *ncs;
+ FcSortNode *node;
+
+ while (nnode--)
+ {
+ node = *n++;
+ if (FcPatternGetCharSet (node->pattern, FC_CHARSET, 0, &ncs) ==
+ FcResultMatch)
+ {
+ if (!trim || !*cs || FcCharSetSubtractCount (ncs, *cs) != 0)
+ {
+ if (*cs)
+ {
+ ncs = FcCharSetUnion (ncs, *cs);
+ if (!ncs)
+ return FcFalse;
+ FcCharSetDestroy (*cs);
+ }
+ else
+ ncs = FcCharSetCopy (ncs);
+ *cs = ncs;
+ if (!FcFontSetAdd (fs, node->pattern))
+ return FcFalse;
+ }
+ }
+ }
+ return FcTrue;
+}
+
+FcFontSet *
+FcFontSetSort (FcConfig *config,
+ FcFontSet **sets,
+ int nsets,
+ FcPattern *p,
+ FcBool trim,
+ FcCharSet **csp,
+ FcResult *result)
+{
+ FcFontSet *ret;
+ FcFontSet *s;
+ FcSortNode *nodes;
+ FcSortNode **nodeps, **nodep;
+ int nnodes;
+ FcSortNode *new;
+ FcCharSet *cs;
+ int set;
+ int f;
+ int i;
+
+ nnodes = 0;
+ for (set = 0; set < nsets; set++)
+ {
+ s = sets[set];
+ if (!s)
+ continue;
+ nnodes += s->nfont;
+ }
+ if (!nnodes)
+ goto bail0;
+ nodes = malloc (nnodes * sizeof (FcSortNode) + nnodes * sizeof (FcSortNode *));
+ if (!nodes)
+ goto bail0;
+ nodeps = (FcSortNode **) nodes + nnodes;
+
+ new = nodes;
+ nodep = nodeps;
+ for (set = 0; set < nsets; set++)
+ {
+ s = sets[set];
+ if (!s)
+ continue;
+ for (f = 0; f < s->nfont; f++)
+ {
+ if (FcDebug () & FC_DBG_MATCHV)
+ {
+ printf ("Font %d ", f);
+ FcPatternPrint (s->fonts[f]);
+ }
+ new->pattern = s->fonts[f];
+ if (!FcCompare (p, new->pattern, new->score, result))
+ goto bail1;
+ if (FcDebug () & FC_DBG_MATCHV)
+ {
+ printf ("Score");
+ for (i = 0; i < NUM_MATCHER; i++)
+ {
+ printf (" %g", new->score[i]);
+ }
+ printf ("\n");
+ }
+ *nodep = new;
+ new++;
+ nodep++;
+ }
+ }
+
+ nnodes = new - nodes;
+
+ qsort (nodeps, sizeof (FcSortNode *), nnodes,
+ FcSortCompare);
+
+ ret = FcFontSetCreate ();
+ if (!ret)
+ goto bail1;
+
+ cs = 0;
+
+ if (!FcSortWalk (nodeps, nnodes, ret, &cs, trim))
+ goto bail2;
+
+ *csp = cs;
+
+ return ret;
+
+bail2:
+ if (cs)
+ FcCharSetDestroy (cs);
+ FcFontSetDestroy (ret);
+bail1:
+ free (nodes);
+bail0:
+ return 0;
+}