PRUnichar *name;
EnumFontsXft(nsIAtom* aLangGroup, const char* aGeneric,             PRUint32* aCount, PRUnichar*** aResult){    FcPattern   *pat = NULL;    FcObjectSet *os  = NULL;    FcFontSet   *fs  = NULL;    nsresult     rv  = NS_ERROR_FAILURE;    PRUnichar **array = NULL;    PRUint32    narray = 0;    PRInt32     serif = 0, sansSerif = 0, monospace = 0, nGenerics;    *aCount = 0;    *aResult = nsnull;    pat = FcPatternCreate();    if (!pat)        goto end;    os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, 0);    if (!os)        goto end;    // take the pattern and add the lang group to it    if (aLangGroup)        NS_AddLangGroup(pat, aLangGroup);    // get the font list    fs = FcFontList(0, pat, os);    if (!fs)        goto end;    if (!fs->nfont) {        rv = NS_OK;        goto end;    }    // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and    // "monospace", slightly different from CSS's 5.    if (!aGeneric)        serif = sansSerif = monospace = 1;    else if (!strcmp(aGeneric, "serif"))        serif = 1;    else if (!strcmp(aGeneric, "sans-serif"))        sansSerif = 1;    else if (!strcmp(aGeneric, "monospace"))        monospace = 1;    else if (!strcmp(aGeneric, "cursive") || !strcmp(aGeneric, "fantasy"))        serif = sansSerif =  1;    else        NS_NOTREACHED("unexpected generic family");    nGenerics = serif + sansSerif + monospace;    array = NS_STATIC_CAST(PRUnichar **,               nsMemory::Alloc((fs->nfont + nGenerics) * sizeof(PRUnichar *)));    if (!array)        goto end;    if (serif) {        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("serif"));        if (!name)            goto end;        array[narray++] = name;    }    if (sansSerif) {        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("sans-serif"));        if (!name)            goto end;        array[narray++] = name;    }    if (monospace) {        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("monospace"));        if (!name)            goto end;        array[narray++] = name;    }    for (int i=0; i < fs->nfont; ++i) {        char *family;        PRUnichar *name;        // if there's no family, just move to the next iteration        if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,                                (FcChar8 **) &family) != FcResultMatch) {            continue;        }        name = NS_STATIC_CAST(PRUnichar *,                              nsMemory::Alloc ((strlen (family) + 1)                                               * sizeof (PRUnichar)));        if (!name)            goto end;        PRUnichar *r = name;        for (char *f = family; *f; ++f)            *r++ = *f;        *r = '\0';        array[narray++] = name;    }    NS_QuickSort(array + nGenerics, narray - nGenerics, sizeof (PRUnichar*),                 CompareFontNames, nsnull);    *aCount = narray;    if (narray)        *aResult = array;    else        nsMemory::Free(array);    rv = NS_OK; end:    if (NS_FAILED(rv) && array) {        while (narray)            nsMemory::Free (array[--narray]);        nsMemory::Free (array);    }    if (pat)        FcPatternDestroy(pat);    if (os)        FcObjectSetDestroy(os);    if (fs)        FcFontSetDestroy(fs);    return rv;}