[charset] Grow internal FcCharset arrays exponentially
This commit is contained in:
parent
cce69b07ef
commit
900723f3d2
|
@ -68,11 +68,9 @@ FcCharSetDestroy (FcCharSet *fcs)
|
||||||
}
|
}
|
||||||
if (fcs->num)
|
if (fcs->num)
|
||||||
{
|
{
|
||||||
|
/* the numbers here are estimates */
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
|
||||||
free (FcCharSetLeaves (fcs));
|
free (FcCharSetLeaves (fcs));
|
||||||
}
|
|
||||||
if (fcs->num)
|
|
||||||
{
|
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
||||||
free (FcCharSetNumbers (fcs));
|
free (FcCharSetNumbers (fcs));
|
||||||
}
|
}
|
||||||
|
@ -134,6 +132,8 @@ FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FC_IS_ZERO_OR_POWER_OF_TWO(x) (!((x) & ((x)-1)))
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
FcCharSetPutLeaf (FcCharSet *fcs,
|
FcCharSetPutLeaf (FcCharSet *fcs,
|
||||||
FcChar32 ucs4,
|
FcChar32 ucs4,
|
||||||
|
@ -143,45 +143,52 @@ FcCharSetPutLeaf (FcCharSet *fcs,
|
||||||
intptr_t *leaves = FcCharSetLeaves (fcs);
|
intptr_t *leaves = FcCharSetLeaves (fcs);
|
||||||
FcChar16 *numbers = FcCharSetNumbers (fcs);
|
FcChar16 *numbers = FcCharSetNumbers (fcs);
|
||||||
|
|
||||||
/* XXX We can't handle Unicode values in Plane 16 */
|
|
||||||
ucs4 >>= 8;
|
ucs4 >>= 8;
|
||||||
|
/* XXX We can't handle Unicode values in Plane 16 */
|
||||||
if (ucs4 >= 0x10000)
|
if (ucs4 >= 0x10000)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
if (fcs->num == fcs->alloced)
|
if (FC_IS_ZERO_OR_POWER_OF_TWO (fcs->num))
|
||||||
{
|
{
|
||||||
intptr_t *new_leaves = realloc (leaves, (fcs->num + 1) *
|
if (!fcs->num)
|
||||||
sizeof (*leaves));
|
{
|
||||||
intptr_t distance = (intptr_t) new_leaves - (intptr_t) leaves;
|
unsigned int alloced = 8;
|
||||||
|
leaves = malloc (alloced * sizeof (*leaves));
|
||||||
|
numbers = malloc (alloced * sizeof (*numbers));
|
||||||
|
FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*leaves));
|
||||||
|
FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*numbers));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int alloced = fcs->num;
|
||||||
|
intptr_t *new_leaves, distance;
|
||||||
|
|
||||||
|
FcMemFree (FC_MEM_CHARSET, alloced * sizeof (*leaves));
|
||||||
|
FcMemFree (FC_MEM_CHARSET, alloced * sizeof (*numbers));
|
||||||
|
|
||||||
|
alloced *= 2;
|
||||||
|
new_leaves = realloc (leaves, alloced * sizeof (*leaves));
|
||||||
|
numbers = realloc (numbers, alloced * sizeof (*numbers));
|
||||||
|
|
||||||
|
FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*leaves));
|
||||||
|
FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*numbers));
|
||||||
|
|
||||||
|
distance = (intptr_t) new_leaves - (intptr_t) leaves;
|
||||||
if (new_leaves && distance)
|
if (new_leaves && distance)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < fcs->num; i++)
|
for (i = 0; i < fcs->num; i++)
|
||||||
new_leaves[i] -= distance;
|
new_leaves[i] -= distance;
|
||||||
}
|
}
|
||||||
leaves = new_leaves;
|
leaves = new_leaves;
|
||||||
}
|
}
|
||||||
if (!leaves)
|
|
||||||
|
if (!leaves || !numbers)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
if (fcs->num)
|
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
|
|
||||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (intptr_t));
|
|
||||||
fcs->leaves_offset = FcPtrToOffset (fcs, leaves);
|
fcs->leaves_offset = FcPtrToOffset (fcs, leaves);
|
||||||
|
|
||||||
if (!fcs->num)
|
|
||||||
numbers = malloc (sizeof (FcChar16));
|
|
||||||
else
|
|
||||||
numbers = realloc (numbers, (fcs->num + 1) * sizeof (FcChar16));
|
|
||||||
if (!numbers)
|
|
||||||
return FcFalse;
|
|
||||||
|
|
||||||
if (fcs->num)
|
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
|
||||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
|
|
||||||
fcs->numbers_offset = FcPtrToOffset (fcs, numbers);
|
fcs->numbers_offset = FcPtrToOffset (fcs, numbers);
|
||||||
|
}
|
||||||
|
|
||||||
memmove (leaves + pos + 1, leaves + pos,
|
memmove (leaves + pos + 1, leaves + pos,
|
||||||
(fcs->num - pos) * sizeof (*leaves));
|
(fcs->num - pos) * sizeof (*leaves));
|
||||||
|
|
Loading…
Reference in New Issue