Commit cd2ec1a9 authored by Patrick Lam's avatar Patrick Lam

Add functionality to allow fontconfig data structure serialization.

This patch allows the fundamental fontconfig data structures to be
    serialized. I've converted everything from FcPattern down to be able to
    use *Ptr objects, which can be either static or dynamic (using a union
    which either contains a pointer or an index) and replaced storage of
    pointers in the heap with the appropriate *Ptr object. I then changed
    all writes of pointers to the heap with a *CreateDynamic call, which
    creates a dynamic Ptr object pointing to the same object as before.
    This way, the fundamental fontconfig semantics should be unchanged; I
    did not have to change external signatures this way, although I did
    change some internal signatures. When given a *Ptr object, just run *U
    to get back to a normal pointer; it gives the right answer regardless
    of whether we're using static or dynamic storage.
I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize
    converts the dynamic FcFontSets contained in the config object to
    static FcFontSets and also converts its dependencies (e.g. everything
    you'd need to write to disk) to static objects. Note that you have to
    call Fc*PrepareSerialize first; this call will count the number of
    objects that actually needs to be allocated, so that we can avoid
    realloc. The Fc*Serialize calls then check the static pointers for
    nullness, and allocate the buffers if necessary. I've tested the
    execution of fc-list and fc-match after Fc*Serialize and they appear to
    work the same way.
parent f1a42f6b
......@@ -220,7 +220,7 @@ main (int argc, char **argv)
FILE *f;
int ncountry = 0;
int i = 0;
FcCharLeaf **leaves, **sleaves;
FcCharLeaf **leaves;
int total_leaves = 0;
int l, sl, tl;
int c;
......@@ -268,14 +268,13 @@ main (int argc, char **argv)
*/
for (i = 0; sets[i]; i++)
{
sleaves = sets[i]->leaves;
for (sl = 0; sl < sets[i]->num; sl++)
{
for (l = 0; l < tl; l++)
if (leaves[l] == sleaves[sl])
if (leaves[l] == FcCharSetGetLeaf(sets[i], sl))
break;
if (l == tl)
leaves[tl++] = sleaves[sl];
leaves[tl++] = FcCharSetGetLeaf(sets[i], sl);
}
}
......@@ -358,7 +357,7 @@ main (int argc, char **argv)
if (n % 8 == 0)
printf (" ");
for (l = 0; l < tl; l++)
if (leaves[l] == sets[i]->leaves[n])
if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
break;
if (l == tl)
fatal (names[i], 0, "can't find leaf");
......@@ -377,7 +376,7 @@ main (int argc, char **argv)
{
if (n % 8 == 0)
printf (" ");
printf (" 0x%04x,", sets[i]->numbers[n]);
printf (" 0x%04x,", FcCharSetGetNumbers(sets[i])[n]);
if (n % 8 == 7)
printf ("\n");
}
......@@ -399,9 +398,9 @@ main (int argc, char **argv)
if (j < 0)
j = i;
printf (" { (FcChar8 *) \"%s\",\n"
" { FC_REF_CONSTANT, %d, "
"(FcCharLeaf **) leaves_%s, "
"(FcChar16 *) numbers_%s } },\n",
" { FC_REF_CONSTANT, %d, FcStorageDynamic, "
"{ { (FcCharLeaf **) leaves_%s, "
"(FcChar16 *) numbers_%s } } } },\n",
langs[i],
sets[j]->num, names[j], names[j]);
}
......
......@@ -59,22 +59,22 @@
__v__.u.d = va_arg (va, double); \
break; \
case FcTypeString: \
__v__.u.s = va_arg (va, FcChar8 *); \
__v__.u.si = va_arg (va, FcObjectPtr); \
break; \
case FcTypeBool: \
__v__.u.b = va_arg (va, FcBool); \
break; \
case FcTypeMatrix: \
__v__.u.m = va_arg (va, FcMatrix *); \
__v__.u.mi = va_arg (va, FcMatrixPtr); \
break; \
case FcTypeCharSet: \
__v__.u.c = va_arg (va, FcCharSet *); \
__v__.u.ci = va_arg (va, FcCharSetPtr); \
break; \
case FcTypeFTFace: \
__v__.u.f = va_arg (va, FT_Face); \
break; \
case FcTypeLangSet: \
__v__.u.l = va_arg (va, FcLangSet *); \
__v__.u.li = va_arg (va, FcLangSetPtr); \
break; \
} \
if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
......
......@@ -196,22 +196,59 @@ typedef enum _FcResult {
FcResultOutOfMemory
} FcResult;
typedef enum _FcStorage {
FcStorageStatic, FcStorageDynamic
} FcStorage;
typedef struct _FcPattern FcPattern;
typedef struct _FcLangSet FcLangSet;
typedef struct _FcMatrixPtr {
FcStorage storage;
union {
int stat;
FcMatrix *dyn;
} u;
} FcMatrixPtr;
typedef struct _FcCharSetPtr {
FcStorage storage;
union {
int stat;
FcCharSet *dyn;
} u;
} FcCharSetPtr;
typedef struct _FcLangSetPtr {
FcStorage storage;
union {
int stat;
FcLangSet *dyn;
} u;
} FcLangSetPtr;
typedef struct _FcObjectPtr {
FcStorage storage;
union {
int stat;
const FcChar8 * dyn;
} u;
FcChar32 hash;
} FcObjectPtr;
typedef struct _FcValue {
FcType type;
union {
const FcChar8 *s;
FcObjectPtr si;
int i;
FcBool b;
double d;
const FcMatrix *m;
const FcCharSet *c;
FcMatrixPtr mi;
FcCharSetPtr ci;
void *f;
const FcPattern *p;
const FcLangSet *l;
FcLangSetPtr li;
} u;
} FcValue;
......@@ -224,7 +261,7 @@ typedef struct _FcFontSet {
typedef struct _FcObjectSet {
int nobject;
int sobject;
const char **objects;
FcObjectPtr *objects;
} FcObjectSet;
typedef enum _FcMatchKind {
......@@ -618,6 +655,9 @@ FcMatrixScale (FcMatrix *m, double sx, double sy);
void
FcMatrixShear (FcMatrix *m, double sh, double sv);
FcMatrix *
FcMatrixPtrU (FcMatrixPtr mi);
/* fcname.c */
FcBool
......
......@@ -1166,3 +1166,35 @@ bail1:
bail0:
return FcFalse;
}
void
FcCacheClearStatic()
{
FcFontSetClearStatic();
FcPatternClearStatic();
FcValueListClearStatic();
FcObjectClearStatic();
FcMatrixClearStatic();
FcCharSetClearStatic();
FcLangSetClearStatic();
}
FcBool
FcCachePrepareSerialize (FcConfig * config)
{
int i;
for (i = FcSetSystem; i <= FcSetApplication; i++)
if (config->fonts[i] && !FcFontSetPrepareSerialize(config->fonts[i]))
return FcFalse;
return FcTrue;
}
FcBool
FcCacheSerialize (FcConfig * config)
{
int i;
for (i = FcSetSystem; i <= FcSetApplication; i++)
if (config->fonts[i] && !FcFontSetSerialize(config->fonts[i]))
return FcFalse;
return FcTrue;
}
This diff is collapsed.
This diff is collapsed.
......@@ -40,20 +40,24 @@ FcValuePrint (const FcValue v)
printf (" %g(f)", v.u.d);
break;
case FcTypeString:
printf (" \"%s\"", v.u.s);
printf (" \"%s\"", FcObjectPtrU(v.u.si));
break;
case FcTypeBool:
printf (" %s", v.u.b ? "FcTrue" : "FcFalse");
break;
case FcTypeMatrix:
printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
{
FcMatrix *m = FcMatrixPtrU(v.u.mi);
printf (" (%f %f; %f %f)", m->xx, m->xy, m->yx, m->yy);
break;
}
case FcTypeCharSet: /* XXX */
printf (" set");
break;
case FcTypeLangSet:
printf (" ");
FcLangSetPrint (v.u.l);
FcLangSetPrint (FcLangSetPtrU(v.u.li));
break;
case FcTypeFTFace:
printf (" face");
......@@ -62,12 +66,12 @@ FcValuePrint (const FcValue v)
}
void
FcValueListPrint (const FcValueList *l)
FcValueListPrint (FcValueListPtr l)
{
for (; l; l = l->next)
for (; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
{
FcValuePrint (l->value);
switch (l->binding) {
FcValuePrint (FcValueListPtrU(l)->value);
switch (FcValueListPtrU(l)->binding) {
case FcValueBindingWeak:
printf ("(w)");
break;
......@@ -89,9 +93,9 @@ FcLangSetPrint (const FcLangSet *ls)
FcStrBufInit (&buf, init_buf, sizeof (init_buf));
if (FcNameUnparseLangSet (&buf, ls) && FcStrBufChar (&buf,'\0'))
printf ("%s", buf.buf);
printf ("%s", buf.buf);
else
printf ("langset (alloc error)");
printf ("langset (alloc error)");
FcStrBufDestroy (&buf);
}
......@@ -109,8 +113,8 @@ FcPatternPrint (const FcPattern *p)
printf ("Pattern %d of %d\n", p->num, p->size);
for (i = 0; i < p->num; i++)
{
e = &p->elts[i];
printf ("\t%s:", e->object);
e = FcPatternEltU(p->elts) + i;
printf ("\t%s:", FcObjectPtrU(e->object));
FcValueListPrint (e->values);
printf ("\n");
}
......
......@@ -80,3 +80,39 @@ FcFontSetAdd (FcFontSet *s, FcPattern *font)
s->fonts[s->nfont++] = font;
return FcTrue;
}
FcBool
FcFontSetPrepareSerialize (FcFontSet *s)
{
int i;
for (i = 0; i < s->nfont; i++)
if (!FcPatternPrepareSerialize(s->fonts[i]))
return FcFalse;
return FcTrue;
}
FcBool
FcFontSetSerialize (FcFontSet * s)
{
int i;
FcPattern * p;
for (i = 0; i < s->nfont; i++)
{
p = FcPatternSerialize (s->fonts[i]);
if (!p) return FcFalse;
FcPatternDestroy (s->fonts[i]);
s->fonts[i] = p;
}
return FcTrue;
}
void
FcFontSetClearStatic (void)
{
FcPatternClearStatic();
}
......@@ -41,6 +41,7 @@
#include <config.h>
#endif
/* unused */
typedef struct _FcSymbolic {
const char *name;
int value;
......@@ -108,22 +109,46 @@ typedef enum _FcValueBinding {
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
} FcValueBinding;
typedef struct _FcStrSetPtr {
FcStorage storage;
union {
int stat;
struct _FcStrSet *dyn;
} u;
} FcStrSetPtr;
typedef struct _FcValueListPtr {
FcStorage storage;
union {
int stat;
struct _FcValueList *dyn;
} u;
} FcValueListPtr;
typedef struct _FcValueList {
struct _FcValueList *next;
FcValueListPtr next;
FcValue value;
FcValueBinding binding;
} FcValueList;
typedef struct _FcPatternEltPtr {
FcStorage storage;
union {
int stat;
struct _FcPatternElt *dyn;
} u;
} FcPatternEltPtr;
typedef struct _FcPatternElt {
const char *object;
FcValueList *values;
FcObjectPtr object;
FcValueListPtr values;
} FcPatternElt;
struct _FcPattern {
int num;
int size;
FcPatternElt *elts;
FcPatternEltPtr elts;
int ref;
};
......@@ -197,15 +222,28 @@ typedef struct _FcCharLeaf {
struct _FcCharSet {
int ref; /* reference count */
int num; /* size of leaves and numbers arrays */
FcCharLeaf **leaves;
FcChar16 *numbers;
FcStorage storage;
union {
struct {
FcCharLeaf **leaves;
FcChar16 *numbers;
} dyn;
struct {
int leafidx_offset;
int numbers_offset;
} stat;
} u;
};
struct _FcStrSet {
int ref; /* reference count */
int num;
int size;
FcChar8 **strs;
FcStorage storage;
union {
FcChar8 **strs;
int stridx_offset;
} u;
};
struct _FcStrList {
......@@ -527,9 +565,30 @@ FcNameParseCharSet (FcChar8 *string);
FcCharLeaf *
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
void
FcCharSetPtrDestroy (FcCharSetPtr fcs);
void
FcCharSetClearStatic(void);
FcBool
FcCharSetPrepareSerialize(FcCharSet *c);
FcCharSetPtr
FcCharSetSerialize(FcCharSet *c);
FcCharSetPtr
FcCharSetPtrCreateDynamic(FcCharSet *c);
FcCharLeaf *
FcCharSetGetLeaf(const FcCharSet *c, int i);
FcChar16 *
FcCharSetGetNumbers(const FcCharSet *c);
/* fcdbg.c */
void
FcValueListPrint (const FcValueList *l);
FcValueListPrint (const FcValueListPtr l);
void
FcLangSetPrint (const FcLangSet *ls);
......@@ -552,6 +611,9 @@ FcSubstPrint (const FcSubst *subst);
int
FcDebug (void);
FcCharSet *
FcCharSetPtrU (FcCharSetPtr mi);
/* fcdir.c */
FcBool
......@@ -596,6 +658,16 @@ const FcCharMap *
FcFreeTypeGetPrivateMap (FT_Encoding encoding);
/* fcfs.c */
void
FcFontSetClearStatic (void);
FcBool
FcFontSetPrepareSerialize (FcFontSet * s);
FcBool
FcFontSetSerialize (FcFontSet * s);
/* fcgram.y */
int
FcConfigparse (void);
......@@ -676,6 +748,24 @@ FcNameParseLangSet (const FcChar8 *string);
FcBool
FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
void
FcLangSetClearStatic (void);
FcBool
FcLangSetPrepareSerialize (FcLangSet *l);
FcLangSetPtr
FcLangSetSerialize (FcLangSet *l);
FcLangSet *
FcLangSetPtrU (FcLangSetPtr li);
FcLangSetPtr
FcLangSetPtrCreateDynamic (FcLangSet *l);
void
FcLangSetPtrDestroy (FcLangSetPtr li);
/* fclist.c */
FcBool
......@@ -684,6 +774,18 @@ FcListPatternMatchAny (const FcPattern *p,
/* fcmatch.c */
/* fcmmap.c */
void
FcCacheClearStatic(void);
FcBool
FcCachePrepareSerialize(FcConfig * config);
FcBool
FcCacheSerialize (FcConfig * config);
/* fcname.c */
FcBool
......@@ -691,8 +793,8 @@ FcNameBool (const FcChar8 *v, FcBool *result);
/* fcpat.c */
void
FcValueListDestroy (FcValueList *l);
FcValueListDestroy (FcValueListPtr l);
FcPatternElt *
FcPatternFindElt (const FcPattern *p, const char *object);
......@@ -715,19 +817,100 @@ FcPatternThawAll (void);
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s);
const char *
void
FcObjectClearStatic(void);
FcObjectPtr
FcObjectStaticName (const char *name);
FcBool
FcObjectPrepareSerialize (FcObjectPtr si);
const char *
FcObjectPtrU (FcObjectPtr p);
int
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
FcObjectPtr
FcObjectPtrCreateDynamic (const char * s);
void
FcObjectPtrDestroy (FcObjectPtr p);
FcBool
FcPatternPrepareSerialize (FcPattern *p);
void
FcValueListClearStatic (void);
void
FcPatternClearStatic (void);
FcValueList *
FcValueListPtrU(FcValueListPtr p);
FcPatternElt *
FcPatternEltU (FcPatternEltPtr pei);
FcValueListPtr
FcValueListPtrCreateDynamic(FcValueList * p);
FcBool
FcValueListPrepareSerialize (FcValueList *p);
FcValueListPtr
FcValueListSerialize(FcValueList *pi);
FcPattern *
FcPatternSerialize (FcPattern * p);
/* fcrender.c */
/* fcmatrix.c */
extern const FcMatrix FcIdentityMatrix;
extern const FcMatrixPtr FcIdentityMatrix;
void
FcMatrixFree (FcMatrix *mat);
void
FcMatrixPtrDestroy (FcMatrixPtr mi);
FcBool
FcMatrixPrepareSerialize(FcMatrix *m);
FcMatrixPtr
FcMatrixSerialize(FcMatrix *m);
FcMatrix *
FcMatrixPtrU (FcMatrixPtr mi);
FcMatrixPtr
FcMatrixPtrCreateDynamic (FcMatrix *m);
void
FcMatrixClearStatic (void);
/* fcstr.c */
FcStrSet *
FcStrSetPtrU (const FcStrSetPtr set);
FcStrSetPtr
FcStrSetPtrCreateDynamic (const FcStrSet * set);
void
FcStrSetClearStatic (void);
FcBool
FcStrSetPrepareSerialize (const FcStrSet *set);
void
FcStrSetSort (FcStrSet * set);
FcChar8 *
FcStrSetGet (const FcStrSet *set, int i);
FcChar8 *
FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
......@@ -752,6 +935,9 @@ FcStrBufString (FcStrBuf *buf, const FcChar8 *s);
FcBool
FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
FcStrSetPtr
FcStrSetSerialize (FcStrSet *set);
int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
......
......@@ -22,6 +22,8 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <fcntl.h>
#include <sys/mman.h>
#include "fcint.h"
typedef struct {
......@@ -38,7 +40,7 @@ typedef struct {
struct _FcLangSet {
FcChar32 map[NUM_LANG_SET_MAP];
FcStrSet *extra;
FcStrSetPtr extra;
};
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
......@@ -48,7 +50,7 @@ FcLangSet *
FcFreeTypeLangSet (const FcCharSet *charset,
const FcChar8 *exclusiveLang)
{
int i;
int i, j;
FcChar32 missing;
const FcCharSet *exclusiveCharset = 0;
FcLangSet *ls;
......@@ -67,10 +69,15 @@ FcFreeTypeLangSet (const FcCharSet *charset,
* not support other Han languages
*/
if (exclusiveCharset &&
FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang) &&
fcLangCharSets[i].charset.leaves != exclusiveCharset->leaves)
FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang))
{
continue;
if (fcLangCharSets[i].charset.num != exclusiveCharset->num)
continue;
for (j = 0; j < fcLangCharSets[i].charset.num; j++)
if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) !=
FcCharSetGetLeaf(exclusiveCharset, j))
continue;
}
missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
if (FcDebug() & FC_DBG_SCANV)
......@@ -210,15 +217,22 @@ FcLangSetCreate (void)
return 0;
FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet));
memset (ls->map, '\0', sizeof (ls->map));
ls->extra = 0;
ls->extra = FcStrSetPtrCreateDynamic(0);
return ls;
}
void
FcLangSetPtrDestroy (FcLangSetPtr li)
{
if (li.storage == FcStorageDynamic)
FcLangSetDestroy(FcLangSetPtrU(li));
}
void
FcLangSetDestroy (FcLangSet *ls)
{
if (ls->extra)
FcStrSetDestroy (ls->extra);
if (FcStrSetPtrU(ls->extra))
FcStrSetDestroy (FcStrSetPtrU(ls->extra));
FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet));
free (ls);
}
......@@ -232,21 +246,21 @@ FcLangSetCopy (const FcLangSet *ls)
if (!new)
goto bail0;
memcpy (new->map, ls->map, sizeof (new->map));
if (ls->extra)
if (FcStrSetPtrU(ls->extra))
{
FcStrList *list;
FcChar8 *extra;
new->extra = FcStrSetCreate ();
if (!new->extra)
new->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
if (!FcStrSetPtrU(new->extra))
goto bail1;
list = FcStrListCreate (ls->extra);
list = FcStrListCreate (FcStrSetPtrU(ls->extra));
if (!list)
goto bail1;
while ((extra = FcStrListNext (list)))
if (!FcStrSetAdd (new->extra, extra))
if (!FcStrSetAdd (FcStrSetPtrU(new->extra), extra))
{
FcStrListDone (list);
goto bail1;
......@@ -327,13 +341,13 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
FcLangSetBitSet (ls, id);
return FcTrue;
}
if (!ls->extra)
if (!FcStrSetPtrU(ls->extra))
{
ls->extra = FcStrSetCreate ();
if (!ls->extra)
ls->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
if (!FcStrSetPtrU(ls->extra))
return FcFalse;
}
return FcStrSetAdd (ls->extra, lang);
return FcStrSetAdd (FcStrSetPtrU(ls->extra), lang);
}
FcLangResult
...