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.
30 static FcPattern
** _fcPatterns
= 0;
31 static int fcpattern_bank_count
= 0, fcpattern_ptr
, fcpattern_count
;
32 FcPatternElt
** _fcPatternElts
= 0;
33 static int fcpatternelt_ptr
, fcpatternelt_count
;
34 FcValueList
** _fcValueLists
= 0;
35 static int fcvaluelist_bank_count
= 0, fcvaluelist_ptr
, fcvaluelist_count
;
37 static FcPatternEltPtr
38 FcPatternEltPtrCreateDynamic (FcPatternElt
* e
);
40 FcStrHashed (const FcChar8
*name
);
43 FcPatternCreate (void)
47 p
= (FcPattern
*) malloc (sizeof (FcPattern
));
50 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
));
53 p
->elts
= FcPatternEltPtrCreateDynamic(0);
54 p
->bank
= FC_BANK_DYNAMIC
;
60 FcValueDestroy (FcValue v
)
64 if (!FcStrHashed (v
.u
.s
))
65 FcStrFree ((FcChar8
*) v
.u
.s
);
68 FcMatrixFree ((FcMatrix
*) v
.u
.m
);
71 FcCharSetDestroy ((FcCharSet
*) v
.u
.c
);
74 FcLangSetDestroy ((FcLangSet
*) v
.u
.l
);
82 FcValueCanonicalize (const FcValue
*v
)
84 if (v
->type
& FC_STORAGE_STATIC
)
88 switch (v
->type
& ~FC_STORAGE_STATIC
)
91 new.u
.s
= fc_value_string(v
);
92 new.type
= FcTypeString
;
95 new.u
.c
= fc_value_charset(v
);
96 new.type
= FcTypeCharSet
;
99 new.u
.l
= fc_value_langset(v
);
100 new.type
= FcTypeLangSet
;
109 FcValueSave (FcValue v
)
113 v
.u
.s
= FcStrCopy (v
.u
.s
);
118 v
.u
.m
= FcMatrixCopy (v
.u
.m
);
123 v
.u
.c
= FcCharSetCopy ((FcCharSet
*) v
.u
.c
);
128 v
.u
.l
= FcLangSetCopy (v
.u
.l
);
139 FcValueListDestroy (FcValueListPtr l
)
142 for (; FcValueListPtrU(l
); l
= next
)
144 switch (FcValueListPtrU(l
)->value
.type
) {
146 if (!FcStrHashed ((FcChar8
*)FcValueListPtrU(l
)->value
.u
.s
))
147 FcStrFree ((FcChar8
*)FcValueListPtrU(l
)->value
.u
.s
);
150 FcMatrixFree ((FcMatrix
*)FcValueListPtrU(l
)->value
.u
.m
);
154 ((FcCharSet
*) (FcValueListPtrU(l
)->value
.u
.c
));
158 ((FcLangSet
*) (FcValueListPtrU(l
)->value
.u
.l
));
163 next
= FcValueListPtrU(l
)->next
;
164 FcMemFree (FC_MEM_VALLIST
, sizeof (FcValueList
));
165 if (l
.bank
== FC_BANK_DYNAMIC
)
171 FcValueEqual (FcValue va
, FcValue vb
)
173 if (va
.type
!= vb
.type
)
175 if (va
.type
== FcTypeInteger
)
177 va
.type
= FcTypeDouble
;
180 if (vb
.type
== FcTypeInteger
)
182 vb
.type
= FcTypeDouble
;
185 if (va
.type
!= vb
.type
)
192 return va
.u
.i
== vb
.u
.i
;
194 return va
.u
.d
== vb
.u
.d
;
196 return FcStrCmpIgnoreCase (va
.u
.s
, vb
.u
.s
) == 0;
198 return va
.u
.b
== vb
.u
.b
;
200 return FcMatrixEqual (va
.u
.m
, vb
.u
.m
);
202 return FcCharSetEqual (va
.u
.c
, vb
.u
.c
);
204 return va
.u
.f
== vb
.u
.f
;
206 return FcLangSetEqual (va
.u
.l
, vb
.u
.l
);
212 FcDoubleHash (double d
)
222 FcStringHash (const FcChar8
*s
)
229 h
= ((h
<< 1) | (h
>> 31)) ^ c
;
234 FcValueHash (const FcValue
*v
)
236 switch (fc_storage_type(v
)) {
240 return (FcChar32
) v
->u
.i
;
242 return FcDoubleHash (v
->u
.d
);
244 return FcStringHash (fc_value_string(v
));
246 return (FcChar32
) v
->u
.b
;
248 return (FcDoubleHash (v
->u
.m
->xx
) ^
249 FcDoubleHash (v
->u
.m
->xy
) ^
250 FcDoubleHash (v
->u
.m
->yx
) ^
251 FcDoubleHash (v
->u
.m
->yy
));
253 return (FcChar32
) fc_value_charset(v
)->num
;
255 return FcStringHash ((const FcChar8
*) ((FT_Face
) v
->u
.f
)->family_name
) ^
256 FcStringHash ((const FcChar8
*) ((FT_Face
) v
->u
.f
)->style_name
);
258 return FcLangSetHash (fc_value_langset(v
));
264 FcValueListEqual (FcValueListPtr la
, FcValueListPtr lb
)
266 if (FcValueListPtrU(la
) == FcValueListPtrU(lb
))
269 while (FcValueListPtrU(la
) && FcValueListPtrU(lb
))
271 if (!FcValueEqual (FcValueListPtrU(la
)->value
,
272 FcValueListPtrU(lb
)->value
))
274 la
= FcValueListPtrU(la
)->next
;
275 lb
= FcValueListPtrU(lb
)->next
;
277 if (FcValueListPtrU(la
) || FcValueListPtrU(lb
))
283 FcValueListHash (FcValueListPtr l
)
288 for (l_ptrU
= FcValueListPtrU(l
); l_ptrU
;
289 l_ptrU
= FcValueListPtrU(l_ptrU
->next
))
291 hash
= ((hash
<< 1) | (hash
>> 31)) ^ FcValueHash (&l_ptrU
->value
);
297 FcPatternDestroy (FcPattern
*p
)
301 if (p
->ref
== FC_REF_CONSTANT
|| --p
->ref
> 0)
304 for (i
= 0; i
< p
->num
; i
++)
305 FcValueListDestroy ((FcPatternEltU(p
->elts
)+i
)->values
);
308 if (FcPatternEltU(p
->elts
) && p
->elts
.bank
== FC_BANK_DYNAMIC
)
310 FcMemFree (FC_MEM_PATELT
, p
->size
* sizeof (FcPatternElt
));
311 free (FcPatternEltU(p
->elts
));
312 p
->elts
= FcPatternEltPtrCreateDynamic(0);
315 FcMemFree (FC_MEM_PATTERN
, sizeof (FcPattern
));
319 #define FC_VALUE_LIST_HASH_SIZE 257
320 #define FC_PATTERN_HASH_SIZE 67
322 typedef struct _FcValueListEnt FcValueListEnt
;
324 struct _FcValueListEnt
{
325 FcValueListEnt
*next
;
330 typedef union _FcValueListAlign
{
335 static int FcValueListFrozenCount
[FcTypeLangSet
+ 1];
336 static int FcValueListFrozenBytes
[FcTypeLangSet
+ 1];
337 static const char FcValueListFrozenName
[][8] = {
350 FcValueListReport (void);
353 FcValueListReport (void)
357 printf ("Fc Frozen Values:\n");
358 printf ("\t%8s %9s %9s\n", "Type", "Count", "Bytes");
359 for (t
= FcTypeVoid
; t
<= FcTypeLangSet
; t
++)
360 printf ("\t%8s %9d %9d\n", FcValueListFrozenName
[t
],
361 FcValueListFrozenCount
[t
], FcValueListFrozenBytes
[t
]);
364 static FcValueListEnt
*
365 FcValueListEntCreate (FcValueListPtr h
)
367 FcValueListAlign
*ea
;
375 for (l
= h
; FcValueListPtrU(l
); l
= FcValueListPtrU(l
)->next
)
377 size
= sizeof (FcValueListAlign
) + n
* sizeof (FcValueList
);
378 FcValueListFrozenCount
[FcValueListPtrU(h
)->value
.type
]++;
379 FcValueListFrozenBytes
[FcValueListPtrU(h
)->value
.type
] += size
;
380 /* this leaks for some reason */
381 ea
= malloc (sizeof (FcValueListAlign
));
384 new = malloc (n
* sizeof (FcValueList
));
390 memset(new, 0, n
* sizeof (FcValueList
));
391 FcMemAlloc (FC_MEM_VALLIST
, size
);
393 e
->list
= FcValueListPtrCreateDynamic(new);
394 for (l
= h
; FcValueListPtrU(l
);
395 l
= FcValueListPtrU(l
)->next
, new++)
397 if ((FcValueListPtrU(l
)->value
.type
& ~FC_STORAGE_STATIC
) == FcTypeString
)
399 new->value
.type
= FcTypeString
;
400 new->value
.u
.s
= FcStrStaticName
401 (fc_value_string(&FcValueListPtrU(l
)->value
));
405 new->value
= FcValueSave (FcValueCanonicalize
406 (&FcValueListPtrU(l
)->value
));
408 new->binding
= FcValueListPtrU(l
)->binding
;
409 if (FcValueListPtrU(FcValueListPtrU(l
)->next
))
411 new->next
= FcValueListPtrCreateDynamic(new + 1);
415 new->next
= FcValueListPtrCreateDynamic(0);
422 FcValueListEntDestroy (FcValueListEnt
*e
)
426 FcValueListFrozenCount
[FcValueListPtrU(e
->list
)->value
.type
]--;
428 /* XXX: We should perform these two operations with "size" as
429 computed in FcValueListEntCreate, but we don't have access to
430 that value here. Without this, the FcValueListFrozenBytes
431 values will be wrong as will the FcMemFree counts.
433 FcValueListFrozenBytes[e->list->value.type] -= size;
434 FcMemFree (FC_MEM_VALLIST, size);
437 for (l
= e
->list
; FcValueListPtrU(l
);
438 l
= FcValueListPtrU(l
)->next
)
440 if (FcValueListPtrU(l
)->value
.type
!= FcTypeString
)
441 FcValueDestroy (FcValueListPtrU(l
)->value
);
443 /* XXX: Are we being too chummy with the implementation here to
444 free(e) when it was actually the enclosing FcValueListAlign
445 that was allocated? */
449 static int FcValueListTotal
;
450 static int FcValueListUsed
;
452 static FcValueListEnt
*FcValueListHashTable
[FC_VALUE_LIST_HASH_SIZE
];
454 static FcValueListPtr
455 FcValueListFreeze (FcValueListPtr l
)
457 FcChar32 hash
= FcValueListHash (l
);
458 FcValueListEnt
**bucket
= &FcValueListHashTable
[hash
% FC_VALUE_LIST_HASH_SIZE
];
462 for (ent
= *bucket
; ent
; ent
= ent
->next
)
464 if (ent
->hash
== hash
&& FcValueListEqual (ent
->list
, l
))
468 ent
= FcValueListEntCreate (l
);
470 return FcValueListPtrCreateDynamic(0);
480 FcValueListThawAll (void)
483 FcValueListEnt
*ent
, *next
;
485 for (i
= 0; i
< FC_VALUE_LIST_HASH_SIZE
; i
++)
487 for (ent
= FcValueListHashTable
[i
]; ent
; ent
= next
)
490 FcValueListEntDestroy (ent
);
492 FcValueListHashTable
[i
] = 0;
495 FcValueListTotal
= 0;
500 FcPatternBaseHash (FcPattern
*b
)
502 FcChar32 hash
= b
->num
;
505 for (i
= 0; i
< b
->num
; i
++)
506 hash
= ((hash
<< 1) | (hash
>> 31)) ^
507 (long) (FcValueListPtrU((FcPatternEltU(b
->elts
)+i
)->values
));
511 typedef struct _FcPatternEnt FcPatternEnt
;
513 struct _FcPatternEnt
{
519 static int FcPatternTotal
;
520 static int FcPatternUsed
;
522 static FcPatternEnt
*FcPatternHashTable
[FC_VALUE_LIST_HASH_SIZE
];
525 FcPatternBaseFreeze (FcPattern
*b
)
529 FcChar32 hash
= FcPatternBaseHash (b
);
530 FcPatternEnt
**bucket
= &FcPatternHashTable
[hash
% FC_VALUE_LIST_HASH_SIZE
];
535 for (ent
= *bucket
; ent
; ent
= ent
->next
)
537 if (ent
->hash
== hash
&& b
->num
== ent
->pattern
->num
)
539 for (i
= 0; i
< b
->num
; i
++)
541 if (FcObjectPtrCompare((FcPatternEltU(b
->elts
)+i
)->object
,
542 (FcPatternEltU(ent
->pattern
->elts
)+i
)->object
) != 0)
544 if (FcValueListPtrU((FcPatternEltU(b
->elts
)+i
)->values
) !=
545 FcValueListPtrU((FcPatternEltU(ent
->pattern
->elts
)+i
)->values
))
554 * Compute size of pattern + elts
556 ent
= malloc (sizeof (FcPatternEnt
));
560 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPatternEnt
));
563 ep
= FcPatternCreate();
567 epp
= malloc(b
->num
* sizeof (FcPatternElt
));
570 FcPatternDestroy (ep
);
573 ep
->elts
= FcPatternEltPtrCreateDynamic(epp
);
575 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
)*(b
->num
));
579 ep
->ref
= FC_REF_CONSTANT
;
581 for (i
= 0; i
< b
->num
; i
++)
583 (FcPatternEltU(ep
->elts
)+i
)->values
=
584 (FcPatternEltU(b
->elts
)+i
)->values
;
585 (FcPatternEltU(ep
->elts
)+i
)->object
=
586 (FcPatternEltU(b
->elts
)+i
)->object
;
595 FcMemFree (FC_MEM_PATTERN
, sizeof (FcPatternEnt
));
601 FcPatternBaseThawAll (void)
604 FcPatternEnt
*ent
, *next
;
606 for (i
= 0; i
< FC_VALUE_LIST_HASH_SIZE
; i
++)
608 for (ent
= FcPatternHashTable
[i
]; ent
; ent
= next
)
613 FcPatternHashTable
[i
] = 0;
621 FcPatternFreeze (FcPattern
*p
)
623 FcPattern
*b
, *n
= 0, *freeme
= 0;
627 if (p
->ref
== FC_REF_CONSTANT
)
630 b
= FcPatternCreate();
638 e
= malloc(b
->num
* sizeof (FcPatternElt
));
641 FcPatternDestroy (b
);
644 b
->elts
= FcPatternEltPtrCreateDynamic(e
);
645 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
)*(b
->num
));
648 * Freeze object lists
650 for (i
= 0; i
< p
->num
; i
++)
652 (FcPatternEltU(b
->elts
)+i
)->object
=
653 (FcPatternEltU(p
->elts
)+i
)->object
;
654 (FcPatternEltU(b
->elts
)+i
)->values
=
655 FcValueListFreeze((FcPatternEltU(p
->elts
)+i
)->values
);
656 if (!FcValueListPtrU((FcPatternEltU(p
->elts
)+i
)->values
))
666 n
= FcPatternBaseFreeze (b
);
668 if (FcDebug() & FC_DBG_MEMORY
)
670 printf ("ValueLists: total %9d used %9d\n", FcValueListTotal
, FcValueListUsed
);
671 printf ("Patterns: total %9d used %9d\n", FcPatternTotal
, FcPatternUsed
);
675 free(FcPatternEltU(b
->elts
));
676 b
->elts
= FcPatternEltPtrCreateDynamic(0);
677 FcMemFree (FC_MEM_PATELT
, sizeof (FcPatternElt
)*(b
->num
));
680 FcPatternDestroy (freeme
);
682 assert (FcPatternEqual (n
, p
));
688 FcPatternPosition (const FcPattern
*p
, const char *object
)
690 int low
, high
, mid
, c
;
693 obj
= FcObjectToPtr(object
);
700 mid
= (low
+ high
) >> 1;
701 c
= FcObjectPtrCompare((FcPatternEltU(p
->elts
)+mid
)->object
, obj
);
715 FcPatternFindElt (const FcPattern
*p
, const char *object
)
717 int i
= FcPatternPosition (p
, object
);
720 return FcPatternEltU(p
->elts
)+i
;
724 FcPatternInsertElt (FcPattern
*p
, const char *object
)
729 i
= FcPatternPosition (p
, object
);
734 /* reallocate array */
735 if (p
->num
+ 1 >= p
->size
)
737 int s
= p
->size
+ 16;
738 if (FcPatternEltU(p
->elts
))
740 FcPatternElt
*e0
= FcPatternEltU(p
->elts
);
741 e
= (FcPatternElt
*) realloc (e0
, s
* sizeof (FcPatternElt
));
742 if (!e
) /* maybe it was mmapped */
744 e
= malloc(s
* sizeof (FcPatternElt
));
746 memcpy(e
, e0
, p
->num
* sizeof (FcPatternElt
));
750 e
= (FcPatternElt
*) malloc (s
* sizeof (FcPatternElt
));
753 p
->elts
= FcPatternEltPtrCreateDynamic(e
);
755 FcMemFree (FC_MEM_PATELT
, p
->size
* sizeof (FcPatternElt
));
756 FcMemAlloc (FC_MEM_PATELT
, s
* sizeof (FcPatternElt
));
759 (FcPatternEltU(p
->elts
)+p
->size
)->object
= 0;
760 (FcPatternEltU(p
->elts
)+p
->size
)->values
=
761 FcValueListPtrCreateDynamic(0);
767 memmove (FcPatternEltU(p
->elts
) + i
+ 1,
768 FcPatternEltU(p
->elts
) + i
,
769 sizeof (FcPatternElt
) *
775 (FcPatternEltU(p
->elts
)+i
)->object
= FcObjectToPtr (object
);
776 (FcPatternEltU(p
->elts
)+i
)->values
= FcValueListPtrCreateDynamic(0);
779 return FcPatternEltU(p
->elts
)+i
;
783 FcPatternEqual (const FcPattern
*pa
, const FcPattern
*pb
)
790 if (pa
->num
!= pb
->num
)
792 for (i
= 0; i
< pa
->num
; i
++)
794 if (FcObjectPtrCompare((FcPatternEltU(pa
->elts
)+i
)->object
,
795 (FcPatternEltU(pb
->elts
)+i
)->object
) != 0)
797 if (!FcValueListEqual ((FcPatternEltU(pa
->elts
)+i
)->values
,
798 (FcPatternEltU(pb
->elts
)+i
)->values
))
805 FcPatternHash (const FcPattern
*p
)
810 for (i
= 0; i
< p
->num
; i
++)
812 h
= (((h
<< 1) | (h
>> 31)) ^
813 FcStringHash ((FcChar8
*)FcObjectPtrU ((FcPatternEltU(p
->elts
)+i
)->object
)) ^
814 FcValueListHash ((FcPatternEltU(p
->elts
)+i
)->values
));
820 FcPatternEqualSubset (const FcPattern
*pai
, const FcPattern
*pbi
, const FcObjectSet
*os
)
822 FcPatternElt
*ea
, *eb
;
825 for (i
= 0; i
< os
->nobject
; i
++)
827 ea
= FcPatternFindElt (pai
, os
->objects
[i
]);
828 eb
= FcPatternFindElt (pbi
, os
->objects
[i
]);
833 if (!FcValueListEqual (ea
->values
, eb
->values
))
846 FcPatternAddWithBinding (FcPattern
*p
,
849 FcValueBinding binding
,
853 FcValueListPtr
new, *prev
;
855 FcObjectPtr objectPtr
;
857 if (p
->ref
== FC_REF_CONSTANT
)
860 newp
= malloc (sizeof (FcValueList
));
864 memset(newp
, 0, sizeof (FcValueList
));
865 new = FcValueListPtrCreateDynamic(newp
);
866 FcMemAlloc (FC_MEM_VALLIST
, sizeof (FcValueList
));
868 if (value
.type
== FcTypeString
)
870 value
.u
.s
= FcStrStaticName (value
.u
.s
);
872 value
.type
= FcTypeVoid
;
875 value
= FcValueSave (value
);
876 if (value
.type
== FcTypeVoid
)
879 /* quick and dirty hack to enable FcCompareFamily/FcCompareString
880 * speedup: only allow strings to be added under the FC_FAMILY,
881 * FC_FOUNDRY, FC_STYLE, FC_RASTERIZER keys.
882 * and charsets under FC_CHARSET key.
883 * This is slightly semantically different from the old behaviour,
884 * but fonts shouldn't be getting non-strings here anyway.
885 * a better hack would use FcBaseObjectTypes to check all objects. */
886 objectPtr
= FcObjectToPtr(object
);
887 if ((objectPtr
== FcObjectToPtr(FC_FAMILY
)
888 || objectPtr
== FcObjectToPtr(FC_FOUNDRY
)
889 || objectPtr
== FcObjectToPtr(FC_STYLE
)
890 || objectPtr
== FcObjectToPtr(FC_RASTERIZER
))
891 && value
.type
!= FcTypeString
)
893 if (objectPtr
== FcObjectToPtr(FC_CHARSET
)
894 && value
.type
!= FcTypeCharSet
)
897 FcValueListPtrU(new)->value
= value
;
898 FcValueListPtrU(new)->binding
= binding
;
899 FcValueListPtrU(new)->next
= FcValueListPtrCreateDynamic(0);
901 e
= FcPatternInsertElt (p
, object
);
907 for (prev
= &e
->values
; FcValueListPtrU(*prev
); prev
= &FcValueListPtrU(*prev
)->next
)
913 FcValueListPtrU(new)->next
= e
->values
;
920 switch (value
.type
) {
922 FcStrFree ((FcChar8
*) value
.u
.s
);
925 FcMatrixFree ((FcMatrix
*) value
.u
.m
);
928 FcCharSetDestroy ((FcCharSet
*) value
.u
.c
);
931 FcLangSetDestroy ((FcLangSet
*) value
.u
.l
);
937 FcMemFree (FC_MEM_VALLIST
, sizeof (FcValueList
));
938 free (FcValueListPtrU(new));
944 FcPatternAdd (FcPattern
*p
, const char *object
, FcValue value
, FcBool append
)
946 return FcPatternAddWithBinding (p
, object
, value
, FcValueBindingStrong
, append
);
950 FcPatternAddWeak (FcPattern
*p
, const char *object
, FcValue value
, FcBool append
)
952 return FcPatternAddWithBinding (p
, object
, value
, FcValueBindingWeak
, append
);
956 FcPatternDel (FcPattern
*p
, const char *object
)
960 e
= FcPatternFindElt (p
, object
);
965 FcValueListDestroy (e
->values
);
967 /* shuffle existing ones down */
969 (FcPatternEltU(p
->elts
) + p
->num
- (e
+ 1)) *
970 sizeof (FcPatternElt
));
972 (FcPatternEltU(p
->elts
)+p
->num
)->object
= 0;
973 (FcPatternEltU(p
->elts
)+p
->num
)->values
= FcValueListPtrCreateDynamic(0);
978 FcPatternRemove (FcPattern
*p
, const char *object
, int id
)
981 FcValueListPtr
*prev
, l
;
983 e
= FcPatternFindElt (p
, object
);
986 for (prev
= &e
->values
;
987 FcValueListPtrU(l
= *prev
);
988 prev
= &FcValueListPtrU(l
)->next
)
992 *prev
= FcValueListPtrU(l
)->next
;
993 FcValueListPtrU(l
)->next
= FcValueListPtrCreateDynamic(0);
994 FcValueListDestroy (l
);
995 if (!FcValueListPtrU(e
->values
))
996 FcPatternDel (p
, object
);
1005 FcPatternAddInteger (FcPattern
*p
, const char *object
, int i
)
1009 v
.type
= FcTypeInteger
;
1011 return FcPatternAdd (p
, object
, v
, FcTrue
);
1015 FcPatternAddDouble (FcPattern
*p
, const char *object
, double d
)
1019 v
.type
= FcTypeDouble
;
1021 return FcPatternAdd (p
, object
, v
, FcTrue
);
1026 FcPatternAddString (FcPattern
*p
, const char *object
, const FcChar8
*s
)
1032 v
.type
= FcTypeVoid
;
1034 return FcPatternAdd (p
, object
, v
, FcTrue
);
1037 v
.type
= FcTypeString
;
1038 v
.u
.s
= FcStrStaticName(s
);
1039 return FcPatternAdd (p
, object
, v
, FcTrue
);
1043 FcPatternAddMatrix (FcPattern
*p
, const char *object
, const FcMatrix
*s
)
1047 v
.type
= FcTypeMatrix
;
1049 return FcPatternAdd (p
, object
, v
, FcTrue
);
1054 FcPatternAddBool (FcPattern
*p
, const char *object
, FcBool b
)
1058 v
.type
= FcTypeBool
;
1060 return FcPatternAdd (p
, object
, v
, FcTrue
);
1064 FcPatternAddCharSet (FcPattern
*p
, const char *object
, const FcCharSet
*c
)
1068 v
.type
= FcTypeCharSet
;
1069 v
.u
.c
= (FcCharSet
*)c
;
1070 return FcPatternAdd (p
, object
, v
, FcTrue
);
1074 FcPatternAddFTFace (FcPattern
*p
, const char *object
, const FT_Face f
)
1078 v
.type
= FcTypeFTFace
;
1080 return FcPatternAdd (p
, object
, v
, FcTrue
);
1084 FcPatternAddLangSet (FcPattern
*p
, const char *object
, const FcLangSet
*ls
)
1088 v
.type
= FcTypeLangSet
;
1089 v
.u
.l
= (FcLangSet
*)ls
;
1090 return FcPatternAdd (p
, object
, v
, FcTrue
);
1094 FcPatternGet (const FcPattern
*p
, const char *object
, int id
, FcValue
*v
)
1099 e
= FcPatternFindElt (p
, object
);
1101 return FcResultNoMatch
;
1102 for (l
= e
->values
; FcValueListPtrU(l
); l
= FcValueListPtrU(l
)->next
)
1106 *v
= FcValueCanonicalize(&FcValueListPtrU(l
)->value
);
1107 return FcResultMatch
;
1111 return FcResultNoId
;
1115 FcPatternGetInteger (const FcPattern
*p
, const char *object
, int id
, int *i
)
1120 r
= FcPatternGet (p
, object
, id
, &v
);
1121 if (r
!= FcResultMatch
)
1131 return FcResultTypeMismatch
;
1133 return FcResultMatch
;
1137 FcPatternGetDouble (const FcPattern
*p
, const char *object
, int id
, double *d
)
1142 r
= FcPatternGet (p
, object
, id
, &v
);
1143 if (r
!= FcResultMatch
)
1150 *d
= (double) v
.u
.i
;
1153 return FcResultTypeMismatch
;
1155 return FcResultMatch
;
1159 FcPatternGetString (const FcPattern
*p
, const char *object
, int id
, FcChar8
** s
)
1164 r
= FcPatternGet (p
, object
, id
, &v
);
1165 if (r
!= FcResultMatch
)
1167 if (v
.type
!= FcTypeString
)
1168 return FcResultTypeMismatch
;
1170 *s
= (FcChar8
*) v
.u
.s
;
1171 return FcResultMatch
;
1175 FcPatternGetMatrix(const FcPattern
*p
, const char *object
, int id
, FcMatrix
**m
)
1180 r
= FcPatternGet (p
, object
, id
, &v
);
1181 if (r
!= FcResultMatch
)
1183 if (v
.type
!= FcTypeMatrix
)
1184 return FcResultTypeMismatch
;
1185 *m
= (FcMatrix
*)v
.u
.m
;
1186 return FcResultMatch
;
1191 FcPatternGetBool(const FcPattern
*p
, const char *object
, int id
, FcBool
*b
)
1196 r
= FcPatternGet (p
, object
, id
, &v
);
1197 if (r
!= FcResultMatch
)
1199 if (v
.type
!= FcTypeBool
)
1200 return FcResultTypeMismatch
;
1202 return FcResultMatch
;
1206 FcPatternGetCharSet(const FcPattern
*p
, const char *object
, int id
, FcCharSet
**c
)
1211 r
= FcPatternGet (p
, object
, id
, &v
);
1212 if (r
!= FcResultMatch
)
1214 if (v
.type
!= FcTypeCharSet
)
1215 return FcResultTypeMismatch
;
1216 *c
= (FcCharSet
*)v
.u
.c
;
1217 return FcResultMatch
;
1221 FcPatternGetFTFace(const FcPattern
*p
, const char *object
, int id
, FT_Face
*f
)
1226 r
= FcPatternGet (p
, object
, id
, &v
);
1227 if (r
!= FcResultMatch
)
1229 if (v
.type
!= FcTypeFTFace
)
1230 return FcResultTypeMismatch
;
1231 *f
= (FT_Face
) v
.u
.f
;
1232 return FcResultMatch
;
1236 FcPatternGetLangSet(const FcPattern
*p
, const char *object
, int id
, FcLangSet
**ls
)
1241 r
= FcPatternGet (p
, object
, id
, &v
);
1242 if (r
!= FcResultMatch
)
1244 if (v
.type
!= FcTypeLangSet
)
1245 return FcResultTypeMismatch
;
1246 *ls
= (FcLangSet
*)v
.u
.l
;
1247 return FcResultMatch
;
1251 FcPatternDuplicate (const FcPattern
*orig
)
1258 new = FcPatternCreate ();
1262 e
= FcPatternEltU(orig
->elts
);
1264 for (i
= 0; i
< orig
->num
; i
++)
1266 for (l
= (e
+ i
)->values
;
1268 l
= FcValueListPtrU(l
)->next
)
1269 if (!FcPatternAdd (new, FcObjectPtrU((e
+ i
)->object
),
1270 FcValueCanonicalize(&FcValueListPtrU(l
)->value
),
1278 FcPatternDestroy (new);
1284 FcPatternReference (FcPattern
*p
)
1286 if (p
->ref
!= FC_REF_CONSTANT
)
1291 FcPatternVaBuild (FcPattern
*orig
, va_list va
)
1295 FcPatternVapBuild (ret
, orig
, va
);
1300 FcPatternBuild (FcPattern
*orig
, ...)
1304 va_start (va
, orig
);
1305 FcPatternVapBuild (orig
, orig
, va
);
1311 * Add all of the elements in 's' to 'p'
1314 FcPatternAppend (FcPattern
*p
, FcPattern
*s
)
1320 for (i
= 0; i
< s
->num
; i
++)
1322 e
= FcPatternEltU(s
->elts
)+i
;
1323 for (v
= e
->values
; FcValueListPtrU(v
);
1324 v
= FcValueListPtrU(v
)->next
)
1326 if (!FcPatternAddWithBinding (p
, FcObjectPtrU(e
->object
),
1327 FcValueCanonicalize(&FcValueListPtrU(v
)->value
),
1328 FcValueListPtrU(v
)->binding
, FcTrue
))
1335 #define OBJECT_HASH_SIZE 31
1336 static struct objectBucket
{
1337 struct objectBucket
*next
;
1339 } *FcObjectBuckets
[OBJECT_HASH_SIZE
];
1342 FcStrHashed (const FcChar8
*name
)
1344 FcChar32 hash
= FcStringHash (name
);
1345 struct objectBucket
**p
;
1346 struct objectBucket
*b
;
1348 for (p
= &FcObjectBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1349 if (b
->hash
== hash
&& !strcmp ((char *)name
, (char *) (b
+ 1)))
1355 FcStrStaticName (const FcChar8
*name
)
1357 FcChar32 hash
= FcStringHash (name
);
1358 struct objectBucket
**p
;
1359 struct objectBucket
*b
;
1362 for (p
= &FcObjectBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1363 if (b
->hash
== hash
&& !strcmp ((char *)name
, (char *) (b
+ 1)))
1364 return (FcChar8
*) (b
+ 1);
1365 size
= sizeof (struct objectBucket
) + strlen ((char *)name
) + 1;
1366 b
= malloc (size
+ sizeof (int));
1367 /* workaround glibc bug which reads strlen in groups of 4 */
1368 FcMemAlloc (FC_MEM_STATICSTR
, size
+ sizeof (int));
1373 strcpy ((char *) (b
+ 1), (char *)name
);
1375 return (FcChar8
*) (b
+ 1);
1379 FcStrStaticNameFini (void)
1382 struct objectBucket
*b
, *next
;
1385 for (i
= 0; i
< OBJECT_HASH_SIZE
; i
++)
1387 for (b
= FcObjectBuckets
[i
]; b
; b
= next
)
1390 name
= (char *) (b
+ 1);
1391 size
= sizeof (struct objectBucket
) + strlen (name
) + 1;
1392 FcMemFree (FC_MEM_STATICSTR
, size
);
1395 FcObjectBuckets
[i
] = 0;
1400 FcPatternFini (void)
1402 FcPatternBaseThawAll ();
1403 FcValueListThawAll ();
1404 FcStrStaticNameFini ();
1405 FcObjectStaticNameFini ();
1408 static FcPatternEltPtr
1409 FcPatternEltPtrCreateDynamic (FcPatternElt
* e
)
1411 FcPatternEltPtr
new;
1412 new.bank
= FC_BANK_DYNAMIC
;
1417 static FcPatternEltPtr
1418 FcPatternEltPtrCreateStatic (int bank
, int i
)
1420 FcPatternEltPtr
new;
1427 FcStrNewBank (void);
1429 FcStrNeededBytes (const FcChar8
* s
);
1431 FcStrNeededBytesAlign (void);
1433 FcStrDistributeBytes (FcCache
* metadata
, void * block_ptr
);
1434 static const FcChar8
*
1435 FcStrSerialize (int bank
, const FcChar8
* s
);
1437 FcStrUnserialize (FcCache
* metadata
, void *block_ptr
);
1440 FcValueListNewBank (void);
1442 FcValueListNeededBytes (FcValueList
* vl
);
1444 FcValueListNeededBytesAlign (void);
1446 FcValueListDistributeBytes (FcCache
* metadata
, void *block_ptr
);
1447 static FcValueListPtr
1448 FcValueListSerialize(int bank
, FcValueList
*pi
);
1450 FcValueListUnserialize (FcCache
* metadata
, void *block_ptr
);
1454 FcPatternNewBank (void)
1456 fcpattern_count
= 0;
1457 fcpatternelt_count
= 0;
1460 FcValueListNewBank();
1464 FcPatternNeededBytes (FcPattern
* p
)
1469 fcpatternelt_count
+= p
->num
;
1471 for (i
= 0; i
< p
->num
; i
++)
1473 c
= FcValueListNeededBytes (FcValueListPtrU
1474 (((FcPatternEltU(p
->elts
)+i
)->values
)));
1480 return cum
+ sizeof (FcPattern
) + sizeof(FcPatternElt
)*p
->num
;
1484 FcPatternNeededBytesAlign (void)
1486 return fc_alignof (FcPattern
) + fc_alignof (FcPatternElt
) +
1487 FcValueListNeededBytesAlign ();
1491 FcPatternEnsureBank (int bi
)
1497 if (!_fcPatterns
|| fcpattern_bank_count
<= bi
)
1499 int new_count
= bi
+ 4;
1500 pp
= realloc (_fcPatterns
, sizeof (FcPattern
*) * new_count
);
1504 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
*) * new_count
);
1507 ep
= realloc (_fcPatternElts
, sizeof (FcPatternElt
*) * new_count
);
1511 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
*) * new_count
);
1512 _fcPatternElts
= ep
;
1514 for (i
= fcpattern_bank_count
; i
< new_count
; i
++)
1517 _fcPatternElts
[i
] = 0;
1520 fcpattern_bank_count
= new_count
;
1523 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
) * fcpattern_count
);
1528 FcPatternDistributeBytes (FcCache
* metadata
, void * block_ptr
)
1530 int bi
= FcCacheBankToIndex(metadata
->bank
);
1532 if (!FcPatternEnsureBank(bi
))
1536 block_ptr
= ALIGN(block_ptr
, FcPattern
);
1537 _fcPatterns
[bi
] = (FcPattern
*)block_ptr
;
1538 block_ptr
= (void *)((char *)block_ptr
+
1539 (sizeof (FcPattern
) * fcpattern_count
));
1541 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
) * fcpatternelt_count
);
1542 fcpatternelt_ptr
= 0;
1543 block_ptr
= ALIGN(block_ptr
, FcPatternElt
);
1544 _fcPatternElts
[bi
] = (FcPatternElt
*)block_ptr
;
1545 block_ptr
= (void *)((char *)block_ptr
+
1546 (sizeof (FcPatternElt
) * fcpatternelt_count
));
1548 metadata
->pattern_count
= fcpattern_count
;
1549 metadata
->patternelt_count
= fcpatternelt_count
;
1551 block_ptr
= FcStrDistributeBytes (metadata
, block_ptr
);
1552 block_ptr
= FcValueListDistributeBytes (metadata
, block_ptr
);
1557 FcPatternSerialize (int bank
, FcPattern
*old
)
1560 FcPatternElt
*e
, *nep
;
1562 FcValueListPtr v
, nv_head
, nvp
;
1563 int i
, elts
, bi
= FcCacheBankToIndex(bank
);
1565 p
= &_fcPatterns
[bi
][fcpattern_ptr
++];
1567 elts
= fcpatternelt_ptr
;
1568 nep
= &_fcPatternElts
[bi
][elts
];
1572 fcpatternelt_ptr
+= old
->num
;
1574 for (e
= FcPatternEltU(old
->elts
), i
=0; i
< old
->num
; i
++, e
++)
1577 nvp
= nv_head
= FcValueListSerialize(bank
, FcValueListPtrU(v
));
1578 if (!FcValueListPtrU(nv_head
))
1580 nv
= FcValueListPtrU(nvp
);
1584 v
= FcValueListPtrU(v
)->next
,
1585 nv
= FcValueListPtrU(nv
->next
))
1588 if (FcValueListPtrU(FcValueListPtrU(v
)->next
))
1590 nvp
= FcValueListSerialize
1591 (bank
, FcValueListPtrU(FcValueListPtrU(v
)->next
));
1596 nep
[i
].values
= nv_head
;
1597 nep
[i
].object
= e
->object
;
1600 p
->elts
= old
->elts
;
1601 p
->elts
= FcPatternEltPtrCreateStatic(bank
, elts
);
1604 p
->ref
= FC_REF_CONSTANT
;
1609 FcPatternUnserialize (FcCache
* metadata
, void *block_ptr
)
1611 int bi
= FcCacheBankToIndex(metadata
->bank
);
1612 if (!FcPatternEnsureBank(bi
))
1615 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
) * metadata
->pattern_count
);
1616 block_ptr
= ALIGN(block_ptr
, FcPattern
);
1617 _fcPatterns
[bi
] = (FcPattern
*)block_ptr
;
1618 block_ptr
= (void *)((char *)block_ptr
+
1619 (sizeof (FcPattern
) * metadata
->pattern_count
));
1621 FcMemAlloc (FC_MEM_PATELT
,
1622 sizeof (FcPatternElt
) * metadata
->patternelt_count
);
1623 block_ptr
= ALIGN(block_ptr
, FcPatternElt
);
1624 _fcPatternElts
[bi
] = (FcPatternElt
*)block_ptr
;
1625 block_ptr
= (void *)((char *)block_ptr
+
1626 (sizeof (FcPatternElt
) * metadata
->patternelt_count
));
1628 block_ptr
= FcStrUnserialize (metadata
, block_ptr
);
1629 block_ptr
= FcValueListUnserialize (metadata
, block_ptr
);
1635 FcValueListNewBank (void)
1637 fcvaluelist_count
= 0;
1644 FcValueListNeededBytes (FcValueList
*p
)
1651 vl
= FcValueListPtrU(vl
->next
))
1653 /* unserialize just in case */
1654 FcValue v
= FcValueCanonicalize(&vl
->value
);
1659 cum
+= FcCharSetNeededBytes(v
.u
.c
);
1662 cum
+= FcLangSetNeededBytes(v
.u
.l
);
1665 cum
+= FcStrNeededBytes(v
.u
.s
);
1669 fcvaluelist_count
++;
1670 cum
+= sizeof (FcValueList
);
1677 FcValueListNeededBytesAlign (void)
1679 return FcCharSetNeededBytesAlign() + FcLangSetNeededBytesAlign() +
1680 FcStrNeededBytesAlign() + fc_alignof (FcValueList
);
1684 FcValueListEnsureBank (int bi
)
1688 if (!_fcValueLists
|| fcvaluelist_bank_count
<= bi
)
1690 int new_count
= bi
+ 2, i
;
1692 pvl
= realloc (_fcValueLists
, sizeof (FcValueList
*) * new_count
);
1696 FcMemAlloc (FC_MEM_VALLIST
, sizeof (FcValueList
*) * new_count
);
1698 _fcValueLists
= pvl
;
1699 for (i
= fcvaluelist_bank_count
; i
< new_count
; i
++)
1700 _fcValueLists
[i
] = 0;
1702 fcvaluelist_bank_count
= new_count
;
1708 FcValueListDistributeBytes (FcCache
* metadata
, void *block_ptr
)
1710 int bi
= FcCacheBankToIndex(metadata
->bank
);
1712 if (!FcValueListEnsureBank(bi
))
1715 FcMemAlloc (FC_MEM_VALLIST
, sizeof (FcValueList
) * fcvaluelist_count
);
1716 fcvaluelist_ptr
= 0;
1717 block_ptr
= ALIGN(block_ptr
, FcValueList
);
1718 _fcValueLists
[bi
] = (FcValueList
*)block_ptr
;
1719 block_ptr
= (void *)((char *)block_ptr
+
1720 (sizeof (FcValueList
) * fcvaluelist_count
));
1721 metadata
->valuelist_count
= fcvaluelist_count
;
1723 block_ptr
= FcCharSetDistributeBytes(metadata
, block_ptr
);
1724 block_ptr
= FcLangSetDistributeBytes(metadata
, block_ptr
);
1729 static FcValueListPtr
1730 FcValueListSerialize(int bank
, FcValueList
*pi
)
1734 int bi
= FcCacheBankToIndex(bank
);
1738 new.bank
= FC_BANK_DYNAMIC
;
1743 _fcValueLists
[bi
][fcvaluelist_ptr
] = *pi
;
1745 new.u
.stat
= fcvaluelist_ptr
++;
1746 _fcValueLists
[bi
][new.u
.stat
].value
= FcValueCanonicalize (&pi
->value
);
1747 v
= &_fcValueLists
[bi
][new.u
.stat
].value
;
1753 const FcChar8
* s
= FcStrSerialize(bank
, v
->u
.s
);
1755 return FcValueListPtrCreateDynamic(pi
);
1756 v
->u
.s_off
= s
- (const FcChar8
*)v
;
1757 v
->type
|= FC_STORAGE_STATIC
;
1765 FcCharSet
* c
= FcCharSetSerialize(bank
, (FcCharSet
*)v
->u
.c
);
1767 return FcValueListPtrCreateDynamic(pi
);
1768 v
->u
.c_off
= (char *)c
- (char *)v
;
1769 v
->type
|= FC_STORAGE_STATIC
;
1775 FcLangSet
* l
= FcLangSetSerialize(bank
, (FcLangSet
*)v
->u
.l
);
1777 return FcValueListPtrCreateDynamic(pi
);
1778 v
->u
.l_off
= (char *)l
- (char *)v
;
1779 v
->type
|= FC_STORAGE_STATIC
;
1789 FcValueListUnserialize (FcCache
* metadata
, void *block_ptr
)
1791 int bi
= FcCacheBankToIndex(metadata
->bank
);
1793 if (!FcValueListEnsureBank(bi
))
1796 FcMemAlloc (FC_MEM_VALLIST
,
1797 sizeof (FcValueList
) * metadata
->valuelist_count
);
1798 block_ptr
= ALIGN(block_ptr
, FcValueList
);
1799 _fcValueLists
[bi
] = (FcValueList
*)block_ptr
;
1800 block_ptr
= (void *)((char *)block_ptr
+
1801 (sizeof (FcValueList
) * metadata
->valuelist_count
));
1803 block_ptr
= FcCharSetUnserialize(metadata
, block_ptr
);
1804 block_ptr
= FcLangSetUnserialize(metadata
, block_ptr
);
1810 FcValueListPtrCreateDynamic(FcValueList
* p
)
1814 r
.bank
= FC_BANK_DYNAMIC
;
1819 static FcChar8
** static_strs
;
1820 static int static_str_bank_count
= 0, fcstr_ptr
, fcstr_count
;
1822 static struct objectBucket
*FcStrBuckets
[OBJECT_HASH_SIZE
];
1828 struct objectBucket
*b
, *next
;
1831 for (i
= 0; i
< OBJECT_HASH_SIZE
; i
++)
1833 for (b
= FcStrBuckets
[i
]; b
; b
= next
)
1836 name
= (char *) (b
+ 1);
1837 size
= sizeof (struct objectBucket
) + strlen (name
) + 1;
1838 FcMemFree (FC_MEM_STATICSTR
, size
);
1841 FcStrBuckets
[i
] = 0;
1848 FcStrNeededBytes (const FcChar8
* s
)
1850 FcChar32 hash
= FcStringHash ((const FcChar8
*) s
);
1851 struct objectBucket
**p
;
1852 struct objectBucket
*b
;
1854 FcChar8
*const null
= 0;
1856 for (p
= &FcStrBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1857 if (b
->hash
== hash
&& !strcmp ((char *)s
, (char *) (b
+ 1)))
1859 size
= sizeof (struct objectBucket
) + strlen ((char *)s
) + 1 + sizeof(char *);
1861 FcMemAlloc (FC_MEM_STATICSTR
, size
);
1866 strcpy ((char *) (b
+ 1), (char *)s
);
1868 /* Yes, the following line is convoluted. However, it is
1869 * incorrect to replace the with a memset, because the C
1870 * specification doesn't guarantee that the null pointer is
1871 * the same as the zero bit pattern. */
1872 /* Misaligned pointers are not guaranteed to work, either! */
1873 memcpy (((char *) (b
+ 1) + strlen((char *)s
) + 1), &null
, sizeof (null
));
1876 fcstr_count
+= strlen((char *)s
) + 1;
1877 return strlen((char *)s
) + 1;
1881 FcStrNeededBytesAlign (void)
1883 return fc_alignof (char);
1887 FcStrEnsureBank (int bi
)
1891 if (!static_strs
|| static_str_bank_count
<= bi
)
1893 int new_count
= bi
+ 4, i
;
1894 ss
= realloc (static_strs
, sizeof (const char *) * new_count
);
1898 FcMemAlloc (FC_MEM_STRING
, sizeof (const char *) * (new_count
-static_str_bank_count
));
1901 for (i
= static_str_bank_count
; i
< new_count
; i
++)
1903 static_str_bank_count
= new_count
;
1909 FcStrDistributeBytes (FcCache
* metadata
, void * block_ptr
)
1911 int bi
= FcCacheBankToIndex(metadata
->bank
);
1912 if (!FcStrEnsureBank(bi
))
1915 FcMemAlloc (FC_MEM_STRING
, sizeof (char) * fcstr_count
);
1916 block_ptr
= ALIGN (block_ptr
, FcChar8
);
1917 static_strs
[bi
] = (FcChar8
*)block_ptr
;
1918 block_ptr
= (void *)((char *)block_ptr
+ (sizeof (char) * fcstr_count
));
1919 metadata
->str_count
= fcstr_count
;
1925 static const FcChar8
*
1926 FcStrSerialize (int bank
, const FcChar8
* s
)
1928 FcChar32 hash
= FcStringHash ((const FcChar8
*) s
);
1929 struct objectBucket
**p
;
1930 struct objectBucket
*b
;
1931 int bi
= FcCacheBankToIndex(bank
);
1933 for (p
= &FcStrBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1934 if (b
->hash
== hash
&& !strcmp ((char *)s
, (char *) (b
+ 1)))
1937 memcpy (&t
, ((FcChar8
*)(b
+ 1)) + strlen ((char *)s
) + 1, sizeof (FcChar8
*));
1940 strcpy((char *)(static_strs
[bi
] + fcstr_ptr
), (char *)s
);
1941 t
= static_strs
[bi
] + fcstr_ptr
;
1942 memcpy ((FcChar8
*) (b
+ 1) + strlen((char *)s
) + 1, &t
, sizeof (FcChar8
*));
1943 fcstr_ptr
+= strlen((char *)s
) + 1;
1944 memcpy (&t
, ((FcChar8
*)(b
+ 1)) + strlen ((char *)s
) + 1, sizeof (FcChar8
*));
1952 FcStrUnserialize (FcCache
* metadata
, void *block_ptr
)
1954 int bi
= FcCacheBankToIndex(metadata
->bank
);
1955 if (!FcStrEnsureBank(bi
))
1958 FcMemAlloc (FC_MEM_STRING
, sizeof (char) * metadata
->str_count
);
1959 block_ptr
= ALIGN (block_ptr
, FcChar8
);
1960 static_strs
[bi
] = (FcChar8
*)block_ptr
;
1961 block_ptr
= (void *)((char *)block_ptr
+
1962 (sizeof (char) * metadata
->str_count
));