2 * $RCSId: xc/lib/fontconfig/src/fcpat.c,v 1.18 2002/09/18 17:11:46 tsi Exp $
4 * Copyright © 2000 Keith Packard
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
31 FcPatternCreate (void)
35 p
= (FcPattern
*) malloc (sizeof (FcPattern
));
38 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
));
47 FcValueDestroy (FcValue v
)
51 FcStrFree ((FcChar8
*) v
.u
.s
);
54 FcMatrixFree ((FcMatrix
*) v
.u
.m
);
57 FcCharSetDestroy ((FcCharSet
*) v
.u
.c
);
60 FcLangSetDestroy ((FcLangSet
*) v
.u
.l
);
68 FcValueSave (FcValue v
)
72 v
.u
.s
= FcStrCopy (v
.u
.s
);
77 v
.u
.m
= FcMatrixCopy (v
.u
.m
);
82 v
.u
.c
= FcCharSetCopy ((FcCharSet
*) v
.u
.c
);
87 v
.u
.l
= FcLangSetCopy (v
.u
.l
);
98 FcValueListDestroy (FcValueList
*l
)
103 switch (l
->value
.type
) {
105 FcStrFree ((FcChar8
*) l
->value
.u
.s
);
108 FcMatrixFree ((FcMatrix
*) l
->value
.u
.m
);
111 FcCharSetDestroy ((FcCharSet
*) l
->value
.u
.c
);
114 FcLangSetDestroy ((FcLangSet
*) l
->value
.u
.l
);
120 FcMemFree (FC_MEM_VALLIST
, sizeof (FcValueList
));
126 FcValueEqual (FcValue va
, FcValue vb
)
128 if (va
.type
!= vb
.type
)
130 if (va
.type
== FcTypeInteger
)
132 va
.type
= FcTypeDouble
;
135 if (vb
.type
== FcTypeInteger
)
137 vb
.type
= FcTypeDouble
;
140 if (va
.type
!= vb
.type
)
147 return va
.u
.i
== vb
.u
.i
;
149 return va
.u
.d
== vb
.u
.d
;
151 return FcStrCmpIgnoreCase (va
.u
.s
, vb
.u
.s
) == 0;
153 return va
.u
.b
== vb
.u
.b
;
155 return FcMatrixEqual (va
.u
.m
, vb
.u
.m
);
157 return FcCharSetEqual (va
.u
.c
, vb
.u
.c
);
159 return va
.u
.f
== vb
.u
.f
;
161 return FcLangSetEqual (va
.u
.l
, vb
.u
.l
);
167 FcDoubleHash (double d
)
177 FcStringHash (const FcChar8
*s
)
184 h
= ((h
<< 1) | (h
>> 31)) ^ c
;
189 FcValueHash (FcValue v
)
195 return (FcChar32
) v
.u
.i
;
197 return FcDoubleHash (v
.u
.d
);
199 return FcStringHash (v
.u
.s
);
201 return (FcChar32
) v
.u
.b
;
203 return (FcDoubleHash (v
.u
.m
->xx
) ^
204 FcDoubleHash (v
.u
.m
->xy
) ^
205 FcDoubleHash (v
.u
.m
->yx
) ^
206 FcDoubleHash (v
.u
.m
->yy
));
208 return (FcChar32
) v
.u
.c
->num
;
210 return FcStringHash ((const FcChar8
*) ((FT_Face
) v
.u
.f
)->family_name
) ^
211 FcStringHash ((const FcChar8
*) ((FT_Face
) v
.u
.f
)->style_name
);
213 return FcLangSetHash (v
.u
.l
);
219 FcValueListEqual (FcValueList
*la
, FcValueList
*lb
)
226 if (!FcValueEqual (la
->value
, lb
->value
))
237 FcValueListHash (FcValueList
*l
)
243 hash
= ((hash
<< 1) | (hash
>> 31)) ^ FcValueHash (l
->value
);
250 FcPatternDestroy (FcPattern
*p
)
254 if (p
->ref
== FC_REF_CONSTANT
|| --p
->ref
> 0)
257 for (i
= 0; i
< p
->num
; i
++)
258 FcValueListDestroy (p
->elts
[i
].values
);
263 FcMemFree (FC_MEM_PATELT
, p
->size
* sizeof (FcPatternElt
));
268 FcMemFree (FC_MEM_PATTERN
, sizeof (FcPattern
));
272 #define FC_VALUE_LIST_HASH_SIZE 257
273 #define FC_PATTERN_HASH_SIZE 67
275 typedef struct _FcValueListEnt FcValueListEnt
;
277 struct _FcValueListEnt
{
278 FcValueListEnt
*next
;
283 typedef union _FcValueListAlign
{
288 static int FcValueListFrozenCount
[FcTypeLangSet
+ 1];
289 static int FcValueListFrozenBytes
[FcTypeLangSet
+ 1];
290 static char *FcValueListFrozenName
[] = {
303 FcValueListReport (void);
306 FcValueListReport (void)
310 printf ("Fc Frozen Values:\n");
311 printf ("\t%8s %9s %9s\n", "Type", "Count", "Bytes");
312 for (t
= FcTypeVoid
; t
<= FcTypeLangSet
; t
++)
313 printf ("\t%8s %9d %9d\n", FcValueListFrozenName
[t
],
314 FcValueListFrozenCount
[t
], FcValueListFrozenBytes
[t
]);
317 static FcValueListEnt
*
318 FcValueListEntCreate (FcValueList
*h
)
320 FcValueListAlign
*ea
;
322 FcValueList
*l
, *new;
327 for (l
= h
; l
; l
= l
->next
)
329 size
= sizeof (FcValueListAlign
) + n
* sizeof (FcValueList
);
330 FcValueListFrozenCount
[h
->value
.type
]++;
331 FcValueListFrozenBytes
[h
->value
.type
] += size
;
335 FcMemAlloc (FC_MEM_VALLIST
, size
);
337 e
->list
= (FcValueList
*) (ea
+ 1);
339 for (l
= h
; l
; l
= l
->next
, new++)
341 if (l
->value
.type
== FcTypeString
)
343 new->value
.type
= FcTypeString
;
344 new->value
.u
.s
= (FcChar8
*) FcObjectStaticName ((char *) l
->value
.u
.s
);
348 new->value
= FcValueSave (l
->value
);
350 new->binding
= l
->binding
;
360 FcValueListEntDestroy (FcValueListEnt
*e
)
364 FcValueListFrozenCount
[e
->list
->value
.type
]--;
366 /* XXX: We should perform these two operations with "size" as
367 computed in FcValueListEntCreate, but we don't have access to
368 that value here. Without this, the FcValueListFrozenBytes
369 values will be wrong as will the FcMemFree counts.
371 FcValueListFrozenBytes[e->list->value.type] -= size;
372 FcMemFree (FC_MEM_VALLIST, size);
375 for (l
= e
->list
; l
; l
= l
->next
)
377 if (l
->value
.type
!= FcTypeString
)
378 FcValueDestroy (l
->value
);
380 /* XXX: Are we being too chummy with the implementation here to
381 free(e) when it was actually the enclosing FcValueListAlign
382 that was allocated? */
386 static int FcValueListTotal
;
387 static int FcValueListUsed
;
389 static FcValueListEnt
*FcValueListHashTable
[FC_VALUE_LIST_HASH_SIZE
];
392 FcValueListFreeze (FcValueList
*l
)
394 FcChar32 hash
= FcValueListHash (l
);
395 FcValueListEnt
**bucket
= &FcValueListHashTable
[hash
% FC_VALUE_LIST_HASH_SIZE
];
399 for (ent
= *bucket
; ent
; ent
= ent
->next
)
401 if (ent
->hash
== hash
&& FcValueListEqual (ent
->list
, l
))
405 ent
= FcValueListEntCreate (l
);
417 FcValueListThawAll (void)
420 FcValueListEnt
*ent
, *next
;
422 for (i
= 0; i
< FC_VALUE_LIST_HASH_SIZE
; i
++)
424 for (ent
= FcValueListHashTable
[i
]; ent
; ent
= next
)
427 FcValueListEntDestroy (ent
);
429 FcValueListHashTable
[i
] = 0;
432 FcValueListTotal
= 0;
437 FcPatternBaseHash (FcPattern
*b
)
439 FcChar32 hash
= b
->num
;
442 for (i
= 0; i
< b
->num
; i
++)
443 hash
= ((hash
<< 1) | (hash
>> 31)) ^ ((long) b
->elts
[i
].values
);
447 typedef struct _FcPatternEnt FcPatternEnt
;
449 struct _FcPatternEnt
{
455 static int FcPatternTotal
;
456 static int FcPatternUsed
;
458 static FcPatternEnt
*FcPatternHashTable
[FC_VALUE_LIST_HASH_SIZE
];
461 FcPatternBaseFreeze (FcPattern
*b
)
463 FcChar32 hash
= FcPatternBaseHash (b
);
464 FcPatternEnt
**bucket
= &FcPatternHashTable
[hash
% FC_VALUE_LIST_HASH_SIZE
];
470 for (ent
= *bucket
; ent
; ent
= ent
->next
)
472 if (ent
->hash
== hash
&& b
->num
== ent
->pattern
.num
)
474 for (i
= 0; i
< b
->num
; i
++)
476 if (b
->elts
[i
].object
!= ent
->pattern
.elts
[i
].object
)
478 if (b
->elts
[i
].values
!= ent
->pattern
.elts
[i
].values
)
482 return &ent
->pattern
;
487 * Compute size of pattern + elts
489 size
= sizeof (FcPatternEnt
) + b
->num
*sizeof (FcPatternElt
);
494 FcMemAlloc (FC_MEM_PATTERN
, size
);
497 ent
->pattern
.elts
= (FcPatternElt
*) (ent
+ 1);
498 ent
->pattern
.num
= b
->num
;
499 ent
->pattern
.size
= b
->num
;
500 ent
->pattern
.ref
= FC_REF_CONSTANT
;
502 for (i
= 0; i
< b
->num
; i
++)
504 ent
->pattern
.elts
[i
].values
= b
->elts
[i
].values
;
505 ent
->pattern
.elts
[i
].object
= b
->elts
[i
].object
;
511 return &ent
->pattern
;
515 FcPatternBaseThawAll (void)
518 FcPatternEnt
*ent
, *next
;
520 for (i
= 0; i
< FC_VALUE_LIST_HASH_SIZE
; i
++)
522 for (ent
= FcPatternHashTable
[i
]; ent
; ent
= next
)
527 FcPatternHashTable
[i
] = 0;
535 FcPatternFreeze (FcPattern
*p
)
537 FcPattern
*b
, *n
= 0;
541 if (p
->ref
== FC_REF_CONSTANT
)
544 size
= sizeof (FcPattern
) + p
->num
* sizeof (FcPatternElt
);
545 b
= (FcPattern
*) malloc (size
);
548 FcMemAlloc (FC_MEM_PATTERN
, size
);
552 b
->elts
= (FcPatternElt
*) (b
+ 1);
554 * Freeze object lists
556 for (i
= 0; i
< p
->num
; i
++)
558 b
->elts
[i
].object
= p
->elts
[i
].object
;
559 b
->elts
[i
].values
= FcValueListFreeze (p
->elts
[i
].values
);
560 if (!b
->elts
[i
].values
)
566 n
= FcPatternBaseFreeze (b
);
568 if (FcDebug() & FC_DBG_MEMORY
)
570 printf ("ValueLists: total %9d used %9d\n", FcValueListTotal
, FcValueListUsed
);
571 printf ("Patterns: total %9d used %9d\n", FcPatternTotal
, FcPatternUsed
);
577 assert (FcPatternEqual (n
, p
));
583 FcPatternPosition (const FcPattern
*p
, const char *object
)
585 int low
, high
, mid
, c
;
587 object
= FcObjectStaticName(object
);
594 mid
= (low
+ high
) >> 1;
595 c
= p
->elts
[mid
].object
- object
;
609 FcPatternFindElt (const FcPattern
*p
, const char *object
)
611 int i
= FcPatternPosition (p
, object
);
618 FcPatternInsertElt (FcPattern
*p
, const char *object
)
623 i
= FcPatternPosition (p
, object
);
629 if (p
->num
+ 1 >= p
->size
)
631 int s
= p
->size
+ 16;
633 e
= (FcPatternElt
*) realloc (p
->elts
, s
* sizeof (FcPatternElt
));
635 e
= (FcPatternElt
*) malloc (s
* sizeof (FcPatternElt
));
640 FcMemFree (FC_MEM_PATELT
, p
->size
* sizeof (FcPatternElt
));
641 FcMemAlloc (FC_MEM_PATELT
, s
* sizeof (FcPatternElt
));
644 p
->elts
[p
->size
].object
= 0;
645 p
->elts
[p
->size
].values
= 0;
651 memmove (p
->elts
+ i
+ 1,
653 sizeof (FcPatternElt
) *
659 p
->elts
[i
].object
= FcObjectStaticName (object
);
660 p
->elts
[i
].values
= 0;
667 FcPatternEqual (const FcPattern
*pa
, const FcPattern
*pb
)
674 if (pa
->num
!= pb
->num
)
676 for (i
= 0; i
< pa
->num
; i
++)
678 if (pa
->elts
[i
].object
!= pb
->elts
[i
].object
)
680 if (!FcValueListEqual (pa
->elts
[i
].values
, pb
->elts
[i
].values
))
687 FcPatternHash (const FcPattern
*p
)
692 for (i
= 0; i
< p
->num
; i
++)
694 h
= (((h
<< 1) | (h
>> 31)) ^
695 FcStringHash ((const FcChar8
*) p
->elts
[i
].object
) ^
696 FcValueListHash (p
->elts
[i
].values
));
702 FcPatternEqualSubset (const FcPattern
*pa
, const FcPattern
*pb
, const FcObjectSet
*os
)
704 FcPatternElt
*ea
, *eb
;
707 for (i
= 0; i
< os
->nobject
; i
++)
709 ea
= FcPatternFindElt (pa
, os
->objects
[i
]);
710 eb
= FcPatternFindElt (pb
, os
->objects
[i
]);
715 if (!FcValueListEqual (ea
->values
, eb
->values
))
728 FcPatternAddWithBinding (FcPattern
*p
,
731 FcValueBinding binding
,
735 FcValueList
*new, **prev
;
737 if (p
->ref
== FC_REF_CONSTANT
)
740 new = (FcValueList
*) malloc (sizeof (FcValueList
));
744 FcMemAlloc (FC_MEM_VALLIST
, sizeof (FcValueList
));
746 value
= FcValueSave (value
);
747 if (value
.type
== FcTypeVoid
)
751 new->binding
= binding
;
754 e
= FcPatternInsertElt (p
, object
);
760 for (prev
= &e
->values
; *prev
; prev
= &(*prev
)->next
);
765 new->next
= e
->values
;
772 switch (value
.type
) {
774 FcStrFree ((FcChar8
*) value
.u
.s
);
777 FcMatrixFree ((FcMatrix
*) value
.u
.m
);
780 FcCharSetDestroy ((FcCharSet
*) value
.u
.c
);
783 FcLangSetDestroy ((FcLangSet
*) value
.u
.l
);
789 FcMemFree (FC_MEM_VALLIST
, sizeof (FcValueList
));
796 FcPatternAdd (FcPattern
*p
, const char *object
, FcValue value
, FcBool append
)
798 return FcPatternAddWithBinding (p
, object
, value
, FcValueBindingStrong
, append
);
802 FcPatternAddWeak (FcPattern
*p
, const char *object
, FcValue value
, FcBool append
)
804 return FcPatternAddWithBinding (p
, object
, value
, FcValueBindingWeak
, append
);
808 FcPatternDel (FcPattern
*p
, const char *object
)
813 e
= FcPatternFindElt (p
, object
);
820 FcValueListDestroy (e
->values
);
822 /* shuffle existing ones down */
823 memmove (e
, e
+1, (p
->elts
+ p
->num
- (e
+ 1)) * sizeof (FcPatternElt
));
825 p
->elts
[p
->num
].object
= 0;
826 p
->elts
[p
->num
].values
= 0;
831 FcPatternRemove (FcPattern
*p
, const char *object
, int id
)
834 FcValueList
**prev
, *l
;
836 e
= FcPatternFindElt (p
, object
);
839 for (prev
= &e
->values
; (l
= *prev
); prev
= &l
->next
)
845 FcValueListDestroy (l
);
847 FcPatternDel (p
, object
);
856 FcPatternAddInteger (FcPattern
*p
, const char *object
, int i
)
860 v
.type
= FcTypeInteger
;
862 return FcPatternAdd (p
, object
, v
, FcTrue
);
866 FcPatternAddDouble (FcPattern
*p
, const char *object
, double d
)
870 v
.type
= FcTypeDouble
;
872 return FcPatternAdd (p
, object
, v
, FcTrue
);
877 FcPatternAddString (FcPattern
*p
, const char *object
, const FcChar8
*s
)
881 v
.type
= FcTypeString
;
883 return FcPatternAdd (p
, object
, v
, FcTrue
);
887 FcPatternAddMatrix (FcPattern
*p
, const char *object
, const FcMatrix
*s
)
891 v
.type
= FcTypeMatrix
;
892 v
.u
.m
= (FcMatrix
*) s
;
893 return FcPatternAdd (p
, object
, v
, FcTrue
);
898 FcPatternAddBool (FcPattern
*p
, const char *object
, FcBool b
)
904 return FcPatternAdd (p
, object
, v
, FcTrue
);
908 FcPatternAddCharSet (FcPattern
*p
, const char *object
, const FcCharSet
*c
)
912 v
.type
= FcTypeCharSet
;
913 v
.u
.c
= (FcCharSet
*) c
;
914 return FcPatternAdd (p
, object
, v
, FcTrue
);
918 FcPatternAddFTFace (FcPattern
*p
, const char *object
, const FT_Face f
)
922 v
.type
= FcTypeFTFace
;
924 return FcPatternAdd (p
, object
, v
, FcTrue
);
928 FcPatternAddLangSet (FcPattern
*p
, const char *object
, const FcLangSet
*ls
)
932 v
.type
= FcTypeLangSet
;
933 v
.u
.l
= (FcLangSet
*) ls
;
934 return FcPatternAdd (p
, object
, v
, FcTrue
);
938 FcPatternGet (const FcPattern
*p
, const char *object
, int id
, FcValue
*v
)
943 e
= FcPatternFindElt (p
, object
);
945 return FcResultNoMatch
;
946 for (l
= e
->values
; l
; l
= l
->next
)
951 return FcResultMatch
;
959 FcPatternGetInteger (const FcPattern
*p
, const char *object
, int id
, int *i
)
964 r
= FcPatternGet (p
, object
, id
, &v
);
965 if (r
!= FcResultMatch
)
975 return FcResultTypeMismatch
;
977 return FcResultMatch
;
981 FcPatternGetDouble (const FcPattern
*p
, const char *object
, int id
, double *d
)
986 r
= FcPatternGet (p
, object
, id
, &v
);
987 if (r
!= FcResultMatch
)
997 return FcResultTypeMismatch
;
999 return FcResultMatch
;
1003 FcPatternGetString (const FcPattern
*p
, const char *object
, int id
, FcChar8
** s
)
1008 r
= FcPatternGet (p
, object
, id
, &v
);
1009 if (r
!= FcResultMatch
)
1011 if (v
.type
!= FcTypeString
)
1012 return FcResultTypeMismatch
;
1013 *s
= (FcChar8
*) v
.u
.s
;
1014 return FcResultMatch
;
1018 FcPatternGetMatrix(const FcPattern
*p
, const char *object
, int id
, FcMatrix
**m
)
1023 r
= FcPatternGet (p
, object
, id
, &v
);
1024 if (r
!= FcResultMatch
)
1026 if (v
.type
!= FcTypeMatrix
)
1027 return FcResultTypeMismatch
;
1028 *m
= (FcMatrix
*) v
.u
.m
;
1029 return FcResultMatch
;
1034 FcPatternGetBool(const FcPattern
*p
, const char *object
, int id
, FcBool
*b
)
1039 r
= FcPatternGet (p
, object
, id
, &v
);
1040 if (r
!= FcResultMatch
)
1042 if (v
.type
!= FcTypeBool
)
1043 return FcResultTypeMismatch
;
1045 return FcResultMatch
;
1049 FcPatternGetCharSet(const FcPattern
*p
, const char *object
, int id
, FcCharSet
**c
)
1054 r
= FcPatternGet (p
, object
, id
, &v
);
1055 if (r
!= FcResultMatch
)
1057 if (v
.type
!= FcTypeCharSet
)
1058 return FcResultTypeMismatch
;
1059 *c
= (FcCharSet
*) v
.u
.c
;
1060 return FcResultMatch
;
1064 FcPatternGetFTFace(const FcPattern
*p
, const char *object
, int id
, FT_Face
*f
)
1069 r
= FcPatternGet (p
, object
, id
, &v
);
1070 if (r
!= FcResultMatch
)
1072 if (v
.type
!= FcTypeFTFace
)
1073 return FcResultTypeMismatch
;
1074 *f
= (FT_Face
) v
.u
.f
;
1075 return FcResultMatch
;
1079 FcPatternGetLangSet(const FcPattern
*p
, const char *object
, int id
, FcLangSet
**ls
)
1084 r
= FcPatternGet (p
, object
, id
, &v
);
1085 if (r
!= FcResultMatch
)
1087 if (v
.type
!= FcTypeLangSet
)
1088 return FcResultTypeMismatch
;
1089 *ls
= (FcLangSet
*) v
.u
.l
;
1090 return FcResultMatch
;
1094 FcPatternDuplicate (const FcPattern
*orig
)
1100 new = FcPatternCreate ();
1104 for (i
= 0; i
< orig
->num
; i
++)
1106 for (l
= orig
->elts
[i
].values
; l
; l
= l
->next
)
1107 if (!FcPatternAdd (new, orig
->elts
[i
].object
, l
->value
, FcTrue
))
1114 FcPatternDestroy (new);
1120 FcPatternReference (FcPattern
*p
)
1122 if (p
->ref
!= FC_REF_CONSTANT
)
1127 FcPatternVaBuild (FcPattern
*orig
, va_list va
)
1131 FcPatternVapBuild (ret
, orig
, va
);
1136 FcPatternBuild (FcPattern
*orig
, ...)
1140 va_start (va
, orig
);
1141 FcPatternVapBuild (orig
, orig
, va
);
1147 * Add all of the elements in 's' to 'p'
1150 FcPatternAppend (FcPattern
*p
, FcPattern
*s
)
1156 for (i
= 0; i
< s
->num
; i
++)
1159 for (v
= e
->values
; v
; v
= v
->next
)
1161 if (!FcPatternAddWithBinding (p
, e
->object
,
1162 v
->value
, v
->binding
, FcTrue
))
1169 #define OBJECT_HASH_SIZE 31
1170 static struct objectBucket
{
1171 struct objectBucket
*next
;
1173 } *FcObjectBuckets
[OBJECT_HASH_SIZE
];
1176 FcObjectStaticName (const char *name
)
1178 FcChar32 hash
= FcStringHash ((const FcChar8
*) name
);
1179 struct objectBucket
**p
;
1180 struct objectBucket
*b
;
1183 for (p
= &FcObjectBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1184 if (b
->hash
== hash
&& !strcmp (name
, (char *) (b
+ 1)))
1185 return (char *) (b
+ 1);
1186 size
= sizeof (struct objectBucket
) + strlen (name
) + 1;
1188 FcMemAlloc (FC_MEM_STATICSTR
, size
);
1193 strcpy ((char *) (b
+ 1), name
);
1195 return (char *) (b
+ 1);
1199 FcObjectStaticNameFini (void)
1202 struct objectBucket
*b
, *next
;
1205 for (i
= 0; i
< OBJECT_HASH_SIZE
; i
++)
1207 for (b
= FcObjectBuckets
[i
]; b
; b
= next
)
1210 name
= (char *) (b
+ 1);
1211 size
= sizeof (struct objectBucket
) + strlen (name
) + 1;
1212 FcMemFree (FC_MEM_STATICSTR
, size
);
1215 FcObjectBuckets
[i
] = 0;
1220 FcPatternFini (void)
1222 FcPatternBaseThawAll ();
1223 FcValueListThawAll ();
1224 FcObjectStaticNameFini ();