+FcCharSet *
+FcNameParseCharSet (FcChar8 *string)
+{
+ FcCharSet *c;
+ FcChar32 ucs4;
+ FcCharLeaf *leaf;
+ FcCharLeaf temp;
+ FcChar32 bits;
+ int i;
+
+ c = FcCharSetCreate ();
+ if (!c)
+ goto bail0;
+ while (*string)
+ {
+ string = FcCharSetParseValue (string, &ucs4);
+ if (!string)
+ goto bail1;
+ bits = 0;
+ for (i = 0; i < 256/32; i++)
+ {
+ string = FcCharSetParseValue (string, &temp.map[i]);
+ if (!string)
+ goto bail1;
+ bits |= temp.map[i];
+ }
+ if (bits)
+ {
+ leaf = malloc (sizeof (FcCharLeaf));
+ if (!leaf)
+ goto bail1;
+ *leaf = temp;
+ if (!FcCharSetInsertLeaf (c, ucs4, leaf))
+ goto bail1;
+ }
+ }
+ return c;
+bail1:
+ if (c->num)
+ {
+ FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
+ free (FcCharSetLeaves (c));
+ }
+ if (c->num)
+ {
+ FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
+ free (FcCharSetNumbers (c));
+ }
+ FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
+ free (c);
+bail0:
+ return NULL;
+}
+
+FcBool
+FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c)
+{
+ FcCharSetIter ci;
+ int i;
+#ifdef CHECK
+ int len = buf->len;
+#endif
+
+ for (FcCharSetIterStart (c, &ci);
+ ci.leaf;
+ FcCharSetIterNext (c, &ci))
+ {
+ if (!FcCharSetUnparseValue (buf, ci.ucs4))
+ return FcFalse;
+ for (i = 0; i < 256/32; i++)
+ if (!FcCharSetUnparseValue (buf, ci.leaf->map[i]))
+ return FcFalse;
+ }
+#ifdef CHECK
+ {
+ FcCharSet *check;
+ FcChar32 missing;
+ FcCharSetIter ci, checki;
+
+ /* null terminate for parser */
+ FcStrBufChar (buf, '\0');
+ /* step back over null for life after test */
+ buf->len--;
+ check = FcNameParseCharSet (buf->buf + len);
+ FcCharSetIterStart (c, &ci);
+ FcCharSetIterStart (check, &checki);
+ while (ci.leaf || checki.leaf)
+ {
+ if (ci.ucs4 < checki.ucs4)
+ {
+ printf ("Missing leaf node at 0x%x\n", ci.ucs4);
+ FcCharSetIterNext (c, &ci);
+ }
+ else if (checki.ucs4 < ci.ucs4)
+ {
+ printf ("Extra leaf node at 0x%x\n", checki.ucs4);
+ FcCharSetIterNext (check, &checki);
+ }
+ else
+ {
+ int i = 256/32;
+ FcChar32 *cm = ci.leaf->map;
+ FcChar32 *checkm = checki.leaf->map;
+
+ for (i = 0; i < 256; i += 32)
+ {
+ if (*cm != *checkm)
+ printf ("Mismatching sets at 0x%08x: 0x%08x != 0x%08x\n",
+ ci.ucs4 + i, *cm, *checkm);
+ cm++;
+ checkm++;
+ }
+ FcCharSetIterNext (c, &ci);
+ FcCharSetIterNext (check, &checki);
+ }
+ }
+ if ((missing = FcCharSetSubtractCount (c, check)))
+ printf ("%d missing in reparsed result\n", missing);
+ if ((missing = FcCharSetSubtractCount (check, c)))
+ printf ("%d extra in reparsed result\n", missing);
+ FcCharSetDestroy (check);
+ }
+#endif
+
+ return FcTrue;
+}
+