+ nnodes = 0;
+ for (set = 0; set < nsets; set++)
+ {
+ s = sets[set];
+ if (!s)
+ continue;
+ nnodes += s->nfont;
+ }
+ if (!nnodes)
+ goto bail0;
+
+ for (nPatternLang = 0;
+ FcPatternGet (p, FC_LANG, nPatternLang, &patternLang) == FcResultMatch;
+ nPatternLang++)
+ ;
+
+ /* freed below */
+ nodes = malloc (nnodes * sizeof (FcSortNode) +
+ nnodes * sizeof (FcSortNode *) +
+ nPatternLang * sizeof (FcBool));
+ if (!nodes)
+ goto bail0;
+ nodeps = (FcSortNode **) (nodes + nnodes);
+ patternLangSat = (FcBool *) (nodeps + 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_MATCH_VALUES; i++)
+ {
+ printf (" %g", new->score[i]);
+ }
+ printf ("\n");
+ }
+ *nodep = new;
+ new++;
+ nodep++;
+ }
+ }
+
+ nnodes = new - nodes;
+
+ qsort (nodeps, nnodes, sizeof (FcSortNode *),
+ FcSortCompare);
+
+ for (i = 0; i < nPatternLang; i++)
+ patternLangSat[i] = FcFalse;
+
+ for (f = 0; f < nnodes; f++)
+ {
+ FcBool satisfies = FcFalse;
+ /*
+ * If this node matches any language, go check
+ * which ones and satisfy those entries
+ */
+ if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang)
+ {
+ for (i = 0; i < nPatternLang; i++)
+ {
+ FcValue nodeLang;
+
+ if (!patternLangSat[i] &&
+ FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch &&
+ FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch)
+ {
+ double compare = FcCompareLang (&patternLang, &nodeLang);
+ if (compare >= 0 && compare < 2)
+ {
+ if (FcDebug () & FC_DBG_MATCHV)
+ {
+ FcChar8 *family;
+ FcChar8 *style;
+
+ if (FcPatternGetString (nodeps[f]->pattern, FC_FAMILY, 0, &family) == FcResultMatch &&
+ FcPatternGetString (nodeps[f]->pattern, FC_STYLE, 0, &style) == FcResultMatch)
+ printf ("Font %s:%s matches language %d\n", family, style, i);
+ }
+ patternLangSat[i] = FcTrue;
+ satisfies = FcTrue;
+ break;
+ }
+ }
+ }
+ }
+ if (!satisfies)
+ nodeps[f]->score[MATCH_LANG_INDEX] = 1000.0;
+ }
+
+ /*
+ * Re-sort once the language issues have been settled
+ */
+ qsort (nodeps, nnodes, sizeof (FcSortNode *),
+ FcSortCompare);
+
+ ret = FcFontSetCreate ();
+ if (!ret)
+ goto bail1;
+
+ cs = 0;
+
+ if (!FcSortWalk (nodeps, nnodes, ret, &cs, trim, (csp!=0)))
+ goto bail2;
+
+ if (csp)
+ *csp = cs;
+ else
+ {
+ if (cs)
+ FcCharSetDestroy (cs);
+ }
+
+ free (nodes);
+
+ return ret;
+
+bail2:
+ if (cs)
+ FcCharSetDestroy (cs);
+ FcFontSetDestroy (ret);
+bail1:
+ free (nodes);
+bail0:
+ return 0;