/*
 * fontconfig/src/fclang.c
 *
 * Copyright © 2002 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * 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
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "fcint.h"
#include "fcftint.h"

/* Objects MT-safe for readonly access. */

typedef struct {
    const FcChar8    	lang[8];
    const FcCharSet	charset;
} FcLangCharSet;

typedef struct {
    int begin;
    int end;
} FcLangCharSetRange;

#include "../fc-lang/fclang.h"

struct _FcLangSet {
    FcStrSet	*extra;
    FcChar32    map_size;
    FcChar32	map[NUM_LANG_SET_MAP];
};

static int FcLangSetIndex (const FcChar8 *lang);


static void
FcLangSetBitSet (FcLangSet    *ls,
		 unsigned int  id)
{
  unsigned int bucket;

  id = fcLangCharSetIndices[id];
  bucket = id >> 5;
  if (bucket >= ls->map_size)
    return; /* shouldn't happen really */

  ls->map[bucket] |= ((FcChar32) 1 << (id & 0x1f));
}

static FcBool
FcLangSetBitGet (const FcLangSet *ls,
		 unsigned int     id)
{
  unsigned int bucket;

  id = fcLangCharSetIndices[id];
  bucket = id >> 5;
  if (bucket >= ls->map_size)
    return FcFalse;

  return ((ls->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse;
}

static void
FcLangSetBitReset (FcLangSet    *ls,
		   unsigned int  id)
{
  unsigned int bucket;

  id = fcLangCharSetIndices[id];
  bucket = id >> 5;
  if (bucket >= ls->map_size)
    return; /* shouldn't happen really */

  ls->map[bucket] &= ~((FcChar32) 1 << (id & 0x1f));
}

FcLangSet *
FcFreeTypeLangSet (const FcCharSet  *charset,
		   const FcChar8    *exclusiveLang)
{
    int		    i, j;
    FcChar32	    missing;
    const FcCharSet *exclusiveCharset = 0;
    FcLangSet	    *ls;

    if (exclusiveLang)
	exclusiveCharset = FcLangGetCharSet (exclusiveLang);
    ls = FcLangSetCreate ();
    if (!ls)
	return 0;
    if (FcDebug() & FC_DBG_LANGSET)
    {
	printf ("font charset");
	FcCharSetPrint (charset);
	printf ("\n");
    }
    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
    {
	if (FcDebug() & FC_DBG_LANGSET)
	{
	    printf ("%s charset", fcLangCharSets[i].lang);
	    FcCharSetPrint (&fcLangCharSets[i].charset);
	    printf ("\n");
	}
	
	/*
	 * Check for Han charsets to make fonts
	 * which advertise support for a single language
	 * not support other Han languages
	 */
	if (exclusiveCharset &&
	    FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang))
	{
	    if (fcLangCharSets[i].charset.num != exclusiveCharset->num)
		continue;

	    for (j = 0; j < fcLangCharSets[i].charset.num; j++)
		if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) !=
		    FcCharSetLeaf(exclusiveCharset, j))
		    continue;
	}
	missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
        if (FcDebug() & FC_DBG_SCANV)
	{
	    if (missing && missing < 10)
	    {
		FcCharSet   *missed = FcCharSetSubtract (&fcLangCharSets[i].charset,
							 charset);
		FcChar32    ucs4;
		FcChar32    map[FC_CHARSET_MAP_SIZE];
		FcChar32    next;

		printf ("\n%s(%u) ", fcLangCharSets[i].lang, missing);
		printf ("{");
		for (ucs4 = FcCharSetFirstPage (missed, map, &next);
		     ucs4 != FC_CHARSET_DONE;
		     ucs4 = FcCharSetNextPage (missed, map, &next))
		{
		    int	    i, j;
		    for (i = 0; i < FC_CHARSET_MAP_SIZE; i++)
			if (map[i])
			{
			    for (j = 0; j < 32; j++)
				if (map[i] & (1 << j))
				    printf (" %04x", ucs4 + i * 32 + j);
			}
		}
		printf (" }\n\t");
		FcCharSetDestroy (missed);
	    }
	    else
		printf ("%s(%u) ", fcLangCharSets[i].lang, missing);
	}
	if (!missing)
	    FcLangSetBitSet (ls, i);
    }

    if (FcDebug() & FC_DBG_SCANV)
	printf ("\n");


    return ls;
}

FcChar8 *
FcLangNormalize (const FcChar8 *lang)
{
    FcChar8 *result = NULL, *s, *orig;
    char *territory, *encoding, *modifier;
    size_t llen, tlen = 0, mlen = 0;

    if (!lang || !*lang)
	return NULL;

    if (FcStrCmpIgnoreCase (lang, (const FcChar8 *)"C") == 0 ||
	FcStrCmpIgnoreCase (lang, (const FcChar8 *)"C.UTF-8") == 0 ||
	FcStrCmpIgnoreCase (lang, (const FcChar8 *)"C.utf8") == 0 ||
	FcStrCmpIgnoreCase (lang, (const FcChar8 *)"POSIX") == 0)
    {
	result = FcStrCopy ((const FcChar8 *)"en");
	goto bail;
    }

    s = FcStrCopy (lang);
    if (!s)
	goto bail;

    /* from the comments in glibc:
     *
     * LOCALE can consist of up to four recognized parts for the XPG syntax:
     *
     *            language[_territory[.codeset]][@modifier]
     *
     * Beside the first all of them are allowed to be missing.  If the
     * full specified locale is not found, the less specific one are
     * looked for.  The various part will be stripped off according to
     * the following order:
     *            (1) codeset
     *            (2) normalized codeset
     *            (3) territory
     *            (4) modifier
     *
     * So since we don't take care of the codeset part here, what patterns
     * we need to deal with is:
     *
     *   1. language_territory@modifier
     *   2. language@modifier
     *   3. language
     *
     * then. and maybe no need to try language_territory here.
     */
    modifier = strchr ((const char *) s, '@');
    if (modifier)
    {
	*modifier = 0;
	modifier++;
	mlen = strlen (modifier);
    }
    encoding = strchr ((const char *) s, '.');
    if (encoding)
    {
	*encoding = 0;
	encoding++;
	if (modifier)
	{
	    memmove (encoding, modifier, mlen + 1);
	    modifier = encoding;
	}
    }
    territory = strchr ((const char *) s, '_');
    if (!territory)
	territory = strchr ((const char *) s, '-');
    if (territory)
    {
	*territory = 0;
	territory++;
	tlen = strlen (territory);
    }
    llen = strlen ((const char *) s);
    if (llen < 2 || llen > 3)
    {
	fprintf (stderr, "Fontconfig warning: ignoring %s: not a valid language tag\n",
		 lang);
	goto bail0;
    }
    if (territory && (tlen < 2 || tlen > 3))
    {
	fprintf (stderr, "Fontconfig warning: ignoring %s: not a valid region tag\n",
		 lang);
	goto bail0;
    }
    if (territory)
	territory[-1] = '-';
    if (modifier)
	modifier[-1] = '@';
    orig = FcStrDowncase (s);
    if (!orig)
	goto bail0;
    if (territory)
    {
	if (FcDebug () & FC_DBG_LANGSET)
	    printf("Checking the existence of %s.orth\n", s);
	if (FcLangSetIndex (s) < 0)
	{
	    memmove (territory - 1, territory + tlen, (mlen > 0 ? mlen + 1 : 0) + 1);
	    if (modifier)
		modifier = territory;
	}
	else
	{
	    result = s;
	    /* we'll miss the opportunity to reduce the correct size
	     * of the allocated memory for the string after that.
	     */
	    s = NULL;
	    goto bail1;
	}
    }
    if (modifier)
    {
	if (FcDebug () & FC_DBG_LANGSET)
	    printf("Checking the existence of %s.orth\n", s);
	if (FcLangSetIndex (s) < 0)
	    modifier[-1] = 0;
	else
	{
	    result = s;
	    /* we'll miss the opportunity to reduce the correct size
	     * of the allocated memory for the string after that.
	     */
	    s = NULL;
	    goto bail1;
	}
    }
    if (FcDebug () & FC_DBG_LANGSET)
	printf("Checking the existence of %s.orth\n", s);
    if (FcLangSetIndex (s) < 0)
    {
	/* there seems no languages matched in orth.
	 * add the language as is for fallback.
	 */
	result = orig;
	orig = NULL;
    }
    else
    {
	result = s;
	/* we'll miss the opportunity to reduce the correct size
	 * of the allocated memory for the string after that.
	 */
	s = NULL;
    }
  bail1:
    if (orig)
	FcStrFree (orig);
  bail0:
    if (s)
	free (s);
  bail:
    if (FcDebug () & FC_DBG_LANGSET)
    {
	if (result)
	    printf ("normalized: %s -> %s\n", lang, result);
	else
	    printf ("Unable to normalize %s\n", lang);
    }

    return result;
}

#define FcLangEnd(c)	((c) == '-' || (c) == '\0')

FcLangResult
FcLangCompare (const FcChar8 *s1, const FcChar8 *s2)
{
    FcChar8	    c1, c2;
    FcLangResult    result = FcLangDifferentLang;

    for (;;)
    {
	c1 = *s1++;
	c2 = *s2++;
	
	c1 = FcToLower (c1);
	c2 = FcToLower (c2);
	if (c1 != c2)
	{
	    if (FcLangEnd (c1) && FcLangEnd (c2))
		result = FcLangDifferentTerritory;
	    return result;
	}
	else if (!c1)
	    return FcLangEqual;
	else if (c1 == '-')
	    result = FcLangDifferentTerritory;
    }
}

/*
 * Return FcTrue when super contains sub.
 *
 * super contains sub if super and sub have the same
 * language and either the same country or one
 * is missing the country
 */

static FcBool
FcLangContains (const FcChar8 *super, const FcChar8 *sub)
{
    FcChar8	    c1, c2;

    for (;;)
    {
	c1 = *super++;
	c2 = *sub++;
	
	c1 = FcToLower (c1);
	c2 = FcToLower (c2);
	if (c1 != c2)
	{
	    /* see if super has a country while sub is mising one */
	    if (c1 == '-' && c2 == '\0')
		return FcTrue;
	    /* see if sub has a country while super is mising one */
	    if (c1 == '\0' && c2 == '-')
		return FcTrue;
	    return FcFalse;
	}
	else if (!c1)
	    return FcTrue;
    }
}

const FcCharSet *
FcLangGetCharSet (const FcChar8 *lang)
{
    int		i;
    int		country = -1;

    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
    {
	switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
	case FcLangEqual:
	    return &fcLangCharSets[i].charset;
	case FcLangDifferentTerritory:
	    if (country == -1)
		country = i;
	case FcLangDifferentLang:
	default:
	    break;
	}
    }
    if (country == -1)
	return 0;
    return &fcLangCharSets[country].charset;
}

FcStrSet *
FcGetLangs (void)
{
    FcStrSet *langs;
    int	i;

    langs = FcStrSetCreate();
    if (!langs)
	return 0;

    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
	FcStrSetAdd (langs, fcLangCharSets[i].lang);

    return langs;
}

FcLangSet *
FcLangSetCreate (void)
{
    FcLangSet	*ls;

    ls = malloc (sizeof (FcLangSet));
    if (!ls)
	return 0;
    memset (ls->map, '\0', sizeof (ls->map));
    ls->map_size = NUM_LANG_SET_MAP;
    ls->extra = 0;
    return ls;
}

void
FcLangSetDestroy (FcLangSet *ls)
{
    if (ls->extra)
	FcStrSetDestroy (ls->extra);
    free (ls);
}

FcLangSet *
FcLangSetCopy (const FcLangSet *ls)
{
    FcLangSet	*new;

    new = FcLangSetCreate ();
    if (!new)
	goto bail0;
    memset (new->map, '\0', sizeof (new->map));
    memcpy (new->map, ls->map, FC_MIN (sizeof (new->map), ls->map_size * sizeof (ls->map[0])));
    if (ls->extra)
    {
	FcStrList	*list;
	FcChar8		*extra;
	
	new->extra = FcStrSetCreate ();
	if (!new->extra)
	    goto bail1;

	list = FcStrListCreate (ls->extra);	
	if (!list)
	    goto bail1;
	
	while ((extra = FcStrListNext (list)))
	    if (!FcStrSetAdd (new->extra, extra))
	    {
		FcStrListDone (list);
		goto bail1;
	    }
	FcStrListDone (list);
    }
    return new;
bail1:
    FcLangSetDestroy (new);
bail0:
    return 0;
}

/* When the language isn't found, the return value r is such that:
 *  1) r < 0
 *  2) -r -1 is the index of the first language in fcLangCharSets that comes
 *     after the 'lang' argument in lexicographic order.
 *
 *  The -1 is necessary to avoid problems with language id 0 (otherwise, we
 *  wouldn't be able to distinguish between “language found, id is 0” and
 *  “language not found, sorts right before the language with id 0”).
 */
static int
FcLangSetIndex (const FcChar8 *lang)
{
    int	    low, high, mid = 0;
    int	    cmp = 0;
    FcChar8 firstChar = FcToLower(lang[0]);
    FcChar8 secondChar = firstChar ? FcToLower(lang[1]) : '\0';

    if (firstChar < 'a')
    {
	low = 0;
	high = fcLangCharSetRanges[0].begin;
    }
    else if(firstChar > 'z')
    {
	low = fcLangCharSetRanges[25].begin;
	high = NUM_LANG_CHAR_SET - 1;
    }
    else
    {
	low = fcLangCharSetRanges[firstChar - 'a'].begin;
	high = fcLangCharSetRanges[firstChar - 'a'].end;
	/* no matches */
	if (low > high)
	    return -(low+1); /* one past next entry after where it would be */
    }

    while (low <= high)
    {
	mid = (high + low) >> 1;
	if(fcLangCharSets[mid].lang[0] != firstChar)
	    cmp = FcStrCmpIgnoreCase(fcLangCharSets[mid].lang, lang);
	else
	{   /* fast path for resolving 2-letter languages (by far the most common) after
	     * finding the first char (probably already true because of the hash table) */
	    cmp = fcLangCharSets[mid].lang[1] - secondChar;
	    if (cmp == 0 &&
		(fcLangCharSets[mid].lang[2] != '\0' ||
		 lang[2] != '\0'))
	    {
		cmp = FcStrCmpIgnoreCase(fcLangCharSets[mid].lang+2,
					 lang+2);
	    }
	}
	if (cmp == 0)
	    return mid;
	if (cmp < 0)
	    low = mid + 1;
	else
	    high = mid - 1;
    }
    if (cmp < 0)
	mid++;
    return -(mid + 1);
}

FcBool
FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
{
    int	    id;

    id = FcLangSetIndex (lang);
    if (id >= 0)
    {
	FcLangSetBitSet (ls, id);
	return FcTrue;
    }
    if (!ls->extra)
    {
	ls->extra = FcStrSetCreate ();
	if (!ls->extra)
	    return FcFalse;
    }
    return FcStrSetAdd (ls->extra, lang);
}

FcBool
FcLangSetDel (FcLangSet *ls, const FcChar8 *lang)
{
    int	id;

    id = FcLangSetIndex (lang);
    if (id >= 0)
    {
	FcLangSetBitReset (ls, id);
    }
    else if (ls->extra)
    {
	FcStrSetDel (ls->extra, lang);
    }
    return FcTrue;
}

FcLangResult
FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang)
{
    int		    id;
    FcLangResult    best, r;
    int		    i;

    id = FcLangSetIndex (lang);
    if (id < 0)
	id = -id - 1;
    else if (FcLangSetBitGet (ls, id))
	return FcLangEqual;
    best = FcLangDifferentLang;
    for (i = id - 1; i >= 0; i--)
    {
	r = FcLangCompare (lang, fcLangCharSets[i].lang);
	if (r == FcLangDifferentLang)
	    break;
	if (FcLangSetBitGet (ls, i) && r < best)
	    best = r;
    }
    for (i = id; i < NUM_LANG_CHAR_SET; i++)
    {
	r = FcLangCompare (lang, fcLangCharSets[i].lang);
	if (r == FcLangDifferentLang)
	    break;
	if (FcLangSetBitGet (ls, i) && r < best)
	    best = r;
    }
    if (ls->extra)
    {
	FcStrList	*list = FcStrListCreate (ls->extra);
	FcChar8		*extra;
	
	if (list)
	{
	    while (best > FcLangEqual && (extra = FcStrListNext (list)))
	    {
		r = FcLangCompare (lang, extra);
		if (r < best)
		    best = r;
	    }
	    FcStrListDone (list);
	}
    }
    return best;
}

static FcLangResult
FcLangSetCompareStrSet (const FcLangSet *ls, FcStrSet *set)
{
    FcStrList	    *list = FcStrListCreate (set);
    FcLangResult    r, best = FcLangDifferentLang;
    FcChar8	    *extra;

    if (list)
    {
	while (best > FcLangEqual && (extra = FcStrListNext (list)))
	{
	    r = FcLangSetHasLang (ls, extra);
	    if (r < best)
		best = r;
	}
	FcStrListDone (list);
    }
    return best;
}

FcLangResult
FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb)
{
    int		    i, j, count;
    FcLangResult    best, r;
    FcChar32 aInCountrySet, bInCountrySet;

    count = FC_MIN (lsa->map_size, lsb->map_size);
    count = FC_MIN (NUM_LANG_SET_MAP, count);
    for (i = 0; i < count; i++)
	if (lsa->map[i] & lsb->map[i])
	    return FcLangEqual;
    best = FcLangDifferentLang;
    for (j = 0; j < NUM_COUNTRY_SET; j++)
    {
	aInCountrySet = 0;
	bInCountrySet = 0;

	for (i = 0; i < count; i++)
	{
	    aInCountrySet |= lsa->map[i] & fcLangCountrySets[j][i];
	    bInCountrySet |= lsb->map[i] & fcLangCountrySets[j][i];

	    if (aInCountrySet && bInCountrySet)
	    {
		best = FcLangDifferentTerritory;
		break;
	    }
	}
    }
    if (lsa->extra)
    {
	r = FcLangSetCompareStrSet (lsb, lsa->extra);
	if (r < best)
	    best = r;
    }
    if (best > FcLangEqual && lsb->extra)
    {
	r = FcLangSetCompareStrSet (lsa, lsb->extra);
	if (r < best)
	    best = r;
    }
    return best;
}

/*
 * Used in computing values -- mustn't allocate any storage
 */
FcLangSet *
FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *vbuf)
{
    int		id;
    typedef struct {
	FcLangSet  ls;
	FcStrSet   strs;
	FcChar8   *str;
    } FcLangSetPromotionBuffer;
    FcLangSetPromotionBuffer *buf = (FcLangSetPromotionBuffer *) vbuf;

    FC_ASSERT_STATIC (sizeof (FcLangSetPromotionBuffer) <= sizeof (FcValuePromotionBuffer));

    memset (buf->ls.map, '\0', sizeof (buf->ls.map));
    buf->ls.map_size = NUM_LANG_SET_MAP;
    buf->ls.extra = 0;
    if (lang)
    {
	id = FcLangSetIndex (lang);
	if (id >= 0)
	{
	    FcLangSetBitSet (&buf->ls, id);
	}
	else
	{
	    buf->ls.extra = &buf->strs;
	    buf->strs.num = 1;
	    buf->strs.size = 1;
	    buf->strs.strs = &buf->str;
	    FcRefInit (&buf->strs.ref, 1);
	    buf->str = (FcChar8 *) lang;
	}
    }
    return &buf->ls;
}

FcChar32
FcLangSetHash (const FcLangSet *ls)
{
    FcChar32	h = 0;
    int		i, count;

    count = FC_MIN (ls->map_size, NUM_LANG_SET_MAP);
    for (i = 0; i < count; i++)
	h ^= ls->map[i];
    if (ls->extra)
	h ^= ls->extra->num;
    return h;
}

FcLangSet *
FcNameParseLangSet (const FcChar8 *string)
{
    FcChar8	    lang[32], c = 0;
    int i;
    FcLangSet	    *ls;

    ls = FcLangSetCreate ();
    if (!ls)
	goto bail0;

    for(;;)
    {
	for(i = 0; i < 31;i++)
	{
	    c = *string++;
	    if(c == '\0' || c == '|')
		break; /* end of this code */
	    lang[i] = c;
	}
	lang[i] = '\0';
	if (!FcLangSetAdd (ls, lang))
	    goto bail1;
	if(c == '\0')
	    break;
    }
    return ls;
bail1:
    FcLangSetDestroy (ls);
bail0:
    return 0;
}

FcBool
FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls)
{
    int		i, bit, count;
    FcChar32	bits;
    FcBool	first = FcTrue;

    count = FC_MIN (ls->map_size, NUM_LANG_SET_MAP);
    for (i = 0; i < count; i++)
    {
	if ((bits = ls->map[i]))
	{
	    for (bit = 0; bit <= 31; bit++)
		if (bits & (1 << bit))
		{
		    int id = (i << 5) | bit;
		    if (!first)
			if (!FcStrBufChar (buf, '|'))
			    return FcFalse;
		    if (!FcStrBufString (buf, fcLangCharSets[fcLangCharSetIndicesInv[id]].lang))
			return FcFalse;
		    first = FcFalse;
		}
	}
    }
    if (ls->extra)
    {
	FcStrList   *list = FcStrListCreate (ls->extra);
	FcChar8	    *extra;

	if (!list)
	    return FcFalse;
	while ((extra = FcStrListNext (list)))
	{
	    if (!first)
		if (!FcStrBufChar (buf, '|'))
                {
                    FcStrListDone (list);
		    return FcFalse;
                }
	    if (!FcStrBufString (buf, extra))
                {
                    FcStrListDone (list);
                    return FcFalse;
                }
	    first = FcFalse;
	}
        FcStrListDone (list);
    }
    return FcTrue;
}

FcBool
FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb)
{
    int	    i, count;

    count = FC_MIN (lsa->map_size, lsb->map_size);
    count = FC_MIN (NUM_LANG_SET_MAP, count);
    for (i = 0; i < count; i++)
    {
	if (lsa->map[i] != lsb->map[i])
	    return FcFalse;
    }
    if (!lsa->extra && !lsb->extra)
	return FcTrue;
    if (lsa->extra && lsb->extra)
	return FcStrSetEqual (lsa->extra, lsb->extra);
    return FcFalse;
}

static FcBool
FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang)
{
    int		    id;
    int		    i;

    id = FcLangSetIndex (lang);
    if (id < 0)
	id = -id - 1;
    else if (FcLangSetBitGet (ls, id))
	return FcTrue;
    /*
     * search up and down among equal languages for a match
     */
    for (i = id - 1; i >= 0; i--)
    {
	if (FcLangCompare (fcLangCharSets[i].lang, lang) == FcLangDifferentLang)
	    break;
	if (FcLangSetBitGet (ls, i) &&
	    FcLangContains (fcLangCharSets[i].lang, lang))
	    return FcTrue;
    }
    for (i = id; i < NUM_LANG_CHAR_SET; i++)
    {
	if (FcLangCompare (fcLangCharSets[i].lang, lang) == FcLangDifferentLang)
	    break;
	if (FcLangSetBitGet (ls, i) &&
	    FcLangContains (fcLangCharSets[i].lang, lang))
	    return FcTrue;
    }
    if (ls->extra)
    {
	FcStrList	*list = FcStrListCreate (ls->extra);
	FcChar8		*extra;
	
	if (list)
	{
	    while ((extra = FcStrListNext (list)))
	    {
		if (FcLangContains (extra, lang))
		    break;
	    }
	    FcStrListDone (list);
    	    if (extra)
		return FcTrue;
	}
    }
    return FcFalse;
}

/*
 * return FcTrue if lsa contains every language in lsb
 */
FcBool
FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
{
    int		    i, j, count;
    FcChar32	    missing;

    if (FcDebug() & FC_DBG_MATCHV)
    {
	printf ("FcLangSet "); FcLangSetPrint (lsa);
	printf (" contains "); FcLangSetPrint (lsb);
	printf ("\n");
    }
    /*
     * check bitmaps for missing language support
     */
    count = FC_MIN (lsa->map_size, lsb->map_size);
    count = FC_MIN (NUM_LANG_SET_MAP, count);
    for (i = 0; i < count; i++)
    {
	missing = lsb->map[i] & ~lsa->map[i];
	if (missing)
	{
	    for (j = 0; j < 32; j++)
		if (missing & (1 << j))
		{
		    if (!FcLangSetContainsLang (lsa,
						fcLangCharSets[fcLangCharSetIndicesInv[i*32 + j]].lang))
		    {
			if (FcDebug() & FC_DBG_MATCHV)
			    printf ("\tMissing bitmap %s\n", fcLangCharSets[fcLangCharSetIndicesInv[i*32+j]].lang);
			return FcFalse;
		    }
		}
	}
    }
    if (lsb->extra)
    {
	FcStrList   *list = FcStrListCreate (lsb->extra);
	FcChar8	    *extra;

	if (list)
	{
	    while ((extra = FcStrListNext (list)))
	    {
		if (!FcLangSetContainsLang (lsa, extra))
		{
		    if (FcDebug() & FC_DBG_MATCHV)
			printf ("\tMissing string %s\n", extra);
		    break;
		}
	    }
	    FcStrListDone (list);
	    if (extra)
		return FcFalse;
	}
    }
    return FcTrue;
}

FcBool
FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l)
{
    if (!FcSerializeAlloc (serialize, l, sizeof (FcLangSet)))
	return FcFalse;
    return FcTrue;
}

FcLangSet *
FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l)
{
    FcLangSet	*l_serialize = FcSerializePtr (serialize, l);

    if (!l_serialize)
	return NULL;
    memset (l_serialize->map, '\0', sizeof (l_serialize->map));
    memcpy (l_serialize->map, l->map, FC_MIN (sizeof (l_serialize->map), l->map_size * sizeof (l->map[0])));
    l_serialize->map_size = NUM_LANG_SET_MAP;
    l_serialize->extra = NULL; /* We don't serialize ls->extra */
    return l_serialize;
}

FcStrSet *
FcLangSetGetLangs (const FcLangSet *ls)
{
    FcStrSet *langs;
    int	      i;

    langs = FcStrSetCreate();
    if (!langs)
	return 0;

    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
	if (FcLangSetBitGet (ls, i))
	    FcStrSetAdd (langs, fcLangCharSets[i].lang);

    if (ls->extra)
    {
	FcStrList	*list = FcStrListCreate (ls->extra);
	FcChar8		*extra;

	if (list)
	{
	    while ((extra = FcStrListNext (list)))
		FcStrSetAdd (langs, extra);

	    FcStrListDone (list);
	}
    }

    return langs;
}

static FcLangSet *
FcLangSetOperate(const FcLangSet	*a,
		 const FcLangSet	*b,
		 FcBool			(*func) (FcLangSet 	*ls,
						 const FcChar8	*s))
{
    FcLangSet	*langset = FcLangSetCopy (a);
    FcStrSet	*set = FcLangSetGetLangs (b);
    FcStrList	*sl = FcStrListCreate (set);
    FcChar8	*str;

    FcStrSetDestroy (set);
    while ((str = FcStrListNext (sl)))
    {
	func (langset, str);
    }
    FcStrListDone (sl);

    return langset;
}

FcLangSet *
FcLangSetUnion (const FcLangSet *a, const FcLangSet *b)
{
    return FcLangSetOperate(a, b, FcLangSetAdd);
}

FcLangSet *
FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b)
{
    return FcLangSetOperate(a, b, FcLangSetDel);
}

#define __fclang__
#include "fcaliastail.h"
#include "fcftaliastail.h"
#undef __fclang__
